merchant

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

testing_api_cmd_refund_order.c (7178B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014-2023 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_refund_order.c
     21  * @brief command to test refunds.
     22  * @author Marcello Stanisci
     23  * @author Christian Grothoff
     24  */
     25 #include "platform.h"
     26 struct RefundState;
     27 #define TALER_MERCHANT_POST_PRIVATE_ORDERS_REFUND_RESULT_CLOSURE struct RefundState
     28 #include <taler/taler_exchange_service.h>
     29 #include <taler/taler_testing_lib.h>
     30 #include "taler/taler_merchant_service.h"
     31 #include "taler/taler_merchant_testing_lib.h"
     32 #include <taler/merchant/post-private-orders-ORDER_ID-refund.h>
     33 
     34 
     35 /**
     36  * State for a "refund increase" CMD.
     37  */
     38 struct RefundState
     39 {
     40   /**
     41    * Operation handle for a POST /orders/$ID/refund request.
     42    */
     43   struct TALER_MERCHANT_PostPrivateOrdersRefundHandle *orh;
     44 
     45   /**
     46    * Base URL of the merchant serving the request.
     47    */
     48   const char *merchant_url;
     49 
     50   /**
     51    * Order id of the contract to refund.
     52    */
     53   const char *order_id;
     54 
     55   /**
     56    * The amount to refund.
     57    */
     58   struct TALER_Amount refund_amount;
     59 
     60   /**
     61    * Human-readable justification for the refund.
     62    */
     63   const char *reason;
     64 
     65   /**
     66    * Interpreter state.
     67    */
     68   struct TALER_TESTING_Interpreter *is;
     69 
     70   /**
     71    * Expected HTTP response code.
     72    */
     73   unsigned int http_code;
     74 };
     75 
     76 
     77 /**
     78  * Process POST /refund (increase) response; just checking
     79  * if the HTTP response code is the one expected.
     80  *
     81  * @param cls closure
     82  * @param rr response
     83  */
     84 static void
     85 refund_cb (struct RefundState *ris,
     86            const struct TALER_MERCHANT_PostPrivateOrdersRefundResponse *rr)
     87 {
     88 
     89   ris->orh = NULL;
     90   if (ris->http_code != rr->hr.http_status)
     91   {
     92     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     93                 "Expected status %u, got %u(%d) for refund increase\n",
     94                 ris->http_code,
     95                 rr->hr.http_status,
     96                 (int) rr->hr.ec);
     97     TALER_TESTING_FAIL (ris->is);
     98   }
     99   switch (rr->hr.http_status)
    100   {
    101   case MHD_HTTP_OK:
    102     {
    103       struct TALER_MERCHANT_RefundUriData rud;
    104 
    105       if (GNUNET_OK !=
    106           TALER_MERCHANT_parse_refund_uri (
    107             rr->details.ok.taler_refund_uri,
    108             &rud))
    109       {
    110         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    111                     "Taler refund uri is malformed\n");
    112         TALER_TESTING_interpreter_fail (ris->is);
    113         return;
    114       }
    115       {
    116         char *host;
    117 
    118         host = TALER_MERCHANT_TESTING_extract_host (ris->merchant_url);
    119         if ((0 != strcmp (host,
    120                           rud.merchant_host)) ||
    121             (NULL != rud.merchant_prefix_path) ||
    122             (0 != strcmp (ris->order_id,
    123                           rud.order_id)) ||
    124             (NULL != rud.ssid))
    125         {
    126           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
    127                       "Taler refund uri does not match\n");
    128           TALER_TESTING_interpreter_fail (ris->is);
    129           TALER_MERCHANT_parse_refund_uri_free (&rud);
    130           GNUNET_free (host);
    131           return;
    132         }
    133         GNUNET_free (host);
    134       }
    135       TALER_MERCHANT_parse_refund_uri_free (&rud);
    136     }
    137     break;
    138   case MHD_HTTP_UNAUTHORIZED:
    139     break;
    140   case MHD_HTTP_FORBIDDEN:
    141     break;
    142   case MHD_HTTP_NOT_FOUND:
    143     break;
    144   case MHD_HTTP_CONFLICT:
    145     break;
    146   default:
    147     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    148                 "Unhandled HTTP status %u for refund order.\n",
    149                 rr->hr.http_status);
    150   }
    151   TALER_TESTING_interpreter_next (ris->is);
    152 }
    153 
    154 
    155 /**
    156  * Run the "refund increase" CMD.
    157  *
    158  * @param cls closure.
    159  * @param cmd command currently being run.
    160  * @param is the interpreter state.
    161  */
    162 static void
    163 refund_increase_run (void *cls,
    164                      const struct TALER_TESTING_Command *cmd,
    165                      struct TALER_TESTING_Interpreter *is)
    166 {
    167   struct RefundState *ris = cls;
    168 
    169   ris->is = is;
    170   ris->orh = TALER_MERCHANT_post_private_orders_refund_create (
    171     TALER_TESTING_interpreter_get_context (is),
    172     ris->merchant_url,
    173     ris->order_id,
    174     &ris->refund_amount,
    175     ris->reason);
    176   {
    177     enum TALER_ErrorCode ec;
    178 
    179     ec = TALER_MERCHANT_post_private_orders_refund_start (
    180       ris->orh,
    181       &refund_cb,
    182       ris);
    183     GNUNET_assert (TALER_EC_NONE == ec);
    184   }
    185 }
    186 
    187 
    188 /**
    189  * Offer internal data from the "refund increase" CMD
    190  * state to other commands.
    191  *
    192  * @param cls closure
    193  * @param[out] ret result (could be anything)
    194  * @param trait name of the trait
    195  * @param index index number of the object to extract.
    196  * @return #GNUNET_OK on success
    197  */
    198 static int
    199 refund_increase_traits (void *cls,
    200                         const void **ret,
    201                         const char *trait,
    202                         unsigned int index)
    203 {
    204   struct RefundState *ris = cls;
    205   struct TALER_TESTING_Trait traits[] = {
    206     TALER_TESTING_make_trait_amount (&ris->refund_amount),
    207     TALER_TESTING_make_trait_reason (ris->reason),
    208     TALER_TESTING_trait_end ()
    209   };
    210 
    211   return TALER_TESTING_get_trait (traits,
    212                                   ret,
    213                                   trait,
    214                                   index);
    215 }
    216 
    217 
    218 /**
    219  * Free the state of a "refund increase" CMD, and
    220  * possibly cancel a pending "refund increase" operation.
    221  *
    222  * @param cls closure
    223  * @param cmd command currently being freed.
    224  */
    225 static void
    226 refund_increase_cleanup (void *cls,
    227                          const struct TALER_TESTING_Command *cmd)
    228 {
    229   struct RefundState *ris = cls;
    230 
    231   if (NULL != ris->orh)
    232   {
    233     TALER_LOG_WARNING ("Refund operation did not complete\n");
    234     TALER_MERCHANT_post_private_orders_refund_cancel (ris->orh);
    235   }
    236   GNUNET_free (ris);
    237 }
    238 
    239 
    240 struct TALER_TESTING_Command
    241 TALER_TESTING_cmd_merchant_order_refund (const char *label,
    242                                          const char *merchant_url,
    243                                          const char *reason,
    244                                          const char *order_id,
    245                                          const char *refund_amount,
    246                                          unsigned int http_code)
    247 {
    248   struct RefundState *ris;
    249 
    250   ris = GNUNET_new (struct RefundState);
    251   ris->merchant_url = merchant_url;
    252   ris->order_id = order_id;
    253   GNUNET_assert (GNUNET_OK ==
    254                  TALER_string_to_amount (refund_amount,
    255                                          &ris->refund_amount));
    256   ris->reason = reason;
    257   ris->http_code = http_code;
    258   {
    259     struct TALER_TESTING_Command cmd = {
    260       .cls = ris,
    261       .label = label,
    262       .run = &refund_increase_run,
    263       .cleanup = &refund_increase_cleanup,
    264       .traits = &refund_increase_traits
    265     };
    266 
    267     return cmd;
    268   }
    269 }
    270 
    271 
    272 /* end of testing_api_cmd_refund_order.c */