merchant

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

testing_api_cmd_refund_order.c (6845B)


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