merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

testing_api_cmd_check_order_external.c (6358B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2026 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify
      6   it under the terms of the GNU General Public License as
      7   published by the Free Software Foundation; either version 3, or
      8   (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but
     11   WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   GNU General Public License for more details.
     14 
     15   You should have received a copy of the GNU General Public
     16   License along with TALER; see the file COPYING.  If not, see
     17   <http://www.gnu.org/licenses/>
     18 */
     19 /**
     20  * @file src/testing/testing_api_cmd_check_order_external.c
     21  * @brief command to check the external payments and refunds an order
     22  *        reports through GET /private/orders/$ORDER_ID
     23  * @author Bohdan Potuzhnyi
     24  * @author Volodymyr Potuzhnyi
     25  */
     26 #include "platform.h"
     27 struct CheckOrderExternalState;
     28 #define TALER_MERCHANT_GET_PRIVATE_ORDER_RESULT_CLOSURE \
     29   struct CheckOrderExternalState
     30 #include <taler/taler_exchange_service.h>
     31 #include <taler/taler_testing_lib.h>
     32 #include "taler/taler_merchant_service.h"
     33 #include "taler/taler_merchant_testing_lib.h"
     34 
     35 
     36 /**
     37  * State of a "check order external" CMD.
     38  */
     39 struct CheckOrderExternalState
     40 {
     41 
     42   /**
     43    * Handle for the order status request.
     44    */
     45   struct TALER_MERCHANT_GetPrivateOrderHandle *ogh;
     46 
     47   /**
     48    * The interpreter state.
     49    */
     50   struct TALER_TESTING_Interpreter *is;
     51 
     52   /**
     53    * Base URL of the merchant serving the request.
     54    */
     55   const char *merchant_url;
     56 
     57   /**
     58    * ID of the order to check.
     59    */
     60   const char *order_id;
     61 
     62   /**
     63    * Number of entries expected in "amount_external" of the contract.
     64    */
     65   unsigned int expected_payments;
     66 
     67   /**
     68    * Number of entries expected in "refunds_external" of the status.
     69    */
     70   unsigned int expected_refunds;
     71 
     72   /**
     73    * Choice the order is expected to have been paid with, -1 if the
     74    * contract has no choices.
     75    */
     76   int expected_choice_index;
     77 
     78 };
     79 
     80 
     81 /**
     82  * Callback for the order status request.
     83  *
     84  * @param coes closure for this function
     85  * @param osr response being processed
     86  */
     87 static void
     88 check_order_external_cb (
     89   struct CheckOrderExternalState *coes,
     90   const struct TALER_MERCHANT_GetPrivateOrderResponse *osr)
     91 {
     92   size_t payments;
     93   size_t refunds;
     94 
     95   coes->ogh = NULL;
     96   if (MHD_HTTP_OK != osr->hr.http_status)
     97   {
     98     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     99                 "Unexpected response code %u (%d) to command %s\n",
    100                 osr->hr.http_status,
    101                 (int) osr->hr.ec,
    102                 TALER_TESTING_interpreter_get_current_label (coes->is));
    103     TALER_TESTING_interpreter_fail (coes->is);
    104     return;
    105   }
    106   if (TALER_MERCHANT_OSC_PAID != osr->details.ok.status)
    107   {
    108     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    109                 "Order `%s' is not paid, cannot check external payments\n",
    110                 coes->order_id);
    111     TALER_TESTING_interpreter_fail (coes->is);
    112     return;
    113   }
    114   payments = json_array_size (
    115     json_object_get (osr->details.ok.details.paid.contract_terms,
    116                      "amount_external"));
    117   refunds = json_array_size (osr->details.ok.details.paid.refunds_external);
    118   if (coes->expected_choice_index !=
    119       osr->details.ok.details.paid.choice_index)
    120   {
    121     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    122                 "Order `%s' was paid with choice %d, expected %d\n",
    123                 coes->order_id,
    124                 osr->details.ok.details.paid.choice_index,
    125                 coes->expected_choice_index);
    126     TALER_TESTING_interpreter_fail (coes->is);
    127     return;
    128   }
    129   if ( (payments != (size_t) coes->expected_payments) ||
    130        (refunds != (size_t) coes->expected_refunds) )
    131   {
    132     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    133                 "Order `%s' reports %u external payments and %u external refunds, expected %u and %u\n",
    134                 coes->order_id,
    135                 (unsigned int) payments,
    136                 (unsigned int) refunds,
    137                 coes->expected_payments,
    138                 coes->expected_refunds);
    139     TALER_TESTING_interpreter_fail (coes->is);
    140     return;
    141   }
    142   TALER_TESTING_interpreter_next (coes->is);
    143 }
    144 
    145 
    146 /**
    147  * Run the "check order external" CMD.
    148  *
    149  * @param cls closure.
    150  * @param cmd command being run now.
    151  * @param is interpreter state.
    152  */
    153 static void
    154 check_order_external_run (void *cls,
    155                           const struct TALER_TESTING_Command *cmd,
    156                           struct TALER_TESTING_Interpreter *is)
    157 {
    158   struct CheckOrderExternalState *coes = cls;
    159 
    160   coes->is = is;
    161   coes->ogh = TALER_MERCHANT_get_private_order_create (
    162     TALER_TESTING_interpreter_get_context (is),
    163     coes->merchant_url,
    164     coes->order_id);
    165   GNUNET_assert (NULL != coes->ogh);
    166   {
    167     enum TALER_ErrorCode ec;
    168 
    169     ec = TALER_MERCHANT_get_private_order_start (coes->ogh,
    170                                                  &check_order_external_cb,
    171                                                  coes);
    172     GNUNET_assert (TALER_EC_NONE == ec);
    173   }
    174 }
    175 
    176 
    177 /**
    178  * Free the state of a "check order external" CMD.
    179  *
    180  * @param cls closure.
    181  * @param cmd command being run.
    182  */
    183 static void
    184 check_order_external_cleanup (void *cls,
    185                               const struct TALER_TESTING_Command *cmd)
    186 {
    187   struct CheckOrderExternalState *coes = cls;
    188 
    189   if (NULL != coes->ogh)
    190   {
    191     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    192                 "GET /private/orders/$ORDER_ID operation did not complete\n");
    193     TALER_MERCHANT_get_private_order_cancel (coes->ogh);
    194   }
    195   GNUNET_free (coes);
    196 }
    197 
    198 
    199 struct TALER_TESTING_Command
    200 TALER_TESTING_cmd_merchant_check_order_external (
    201   const char *label,
    202   const char *merchant_url,
    203   const char *order_id,
    204   unsigned int expected_payments,
    205   unsigned int expected_refunds,
    206   int expected_choice_index)
    207 {
    208   struct CheckOrderExternalState *coes;
    209 
    210   coes = GNUNET_new (struct CheckOrderExternalState);
    211   coes->merchant_url = merchant_url;
    212   coes->order_id = order_id;
    213   coes->expected_payments = expected_payments;
    214   coes->expected_refunds = expected_refunds;
    215   coes->expected_choice_index = expected_choice_index;
    216   {
    217     struct TALER_TESTING_Command cmd = {
    218       .cls = coes,
    219       .label = label,
    220       .run = &check_order_external_run,
    221       .cleanup = &check_order_external_cleanup
    222     };
    223 
    224     return cmd;
    225   }
    226 }