gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant] branch master updated: address more FIXMEs


From: gnunet
Subject: [taler-merchant] branch master updated: address more FIXMEs
Date: Sat, 03 Jun 2023 23:24:35 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 7f8c111f address more FIXMEs
7f8c111f is described below

commit 7f8c111f1383805d64ab7f754cb6456d3dfb7250
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Jun 3 23:24:31 2023 +0200

    address more FIXMEs
---
 src/include/taler_merchant_service.h               | 227 +++++++++++++----
 src/lib/merchant_api_get_reserves.c                |   1 -
 src/lib/merchant_api_get_transfers.c               |  64 ++---
 src/lib/merchant_api_post_order_abort.c            |  74 +++---
 src/lib/merchant_api_post_order_pay.c              |   2 +-
 src/lib/merchant_api_post_order_refund.c           |  65 ++---
 src/lib/merchant_api_wallet_post_order_refund.c    | 276 +++++++--------------
 src/testing/testing_api_cmd_abort_order.c          |  36 ++-
 src/testing/testing_api_cmd_get_transfers.c        |  53 ++--
 src/testing/testing_api_cmd_refund_order.c         |  27 +-
 .../testing_api_cmd_wallet_post_orders_refund.c    |  47 ++--
 11 files changed, 431 insertions(+), 441 deletions(-)

diff --git a/src/include/taler_merchant_service.h 
b/src/include/taler_merchant_service.h
index 83035455..cb9edb29 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -2904,24 +2904,58 @@ struct TALER_MERCHANT_AbortedCoin
 };
 
 
-// FIXME: change signature!
+/**
+ * Response to an /orders/$ID/abort request.
+ */
+struct TALER_MERCHANT_AbortResponse
+{
+  /**
+   * HTTP response details
+   */
+  struct TALER_MERCHANT_HttpResponse hr;
+
+  /**
+   * Details depending on HTTP status code.
+   */
+  union
+  {
+    /**
+     * Details for #MHD_HTTP_OK.
+     */
+    struct
+    {
+
+      /**
+       * public key of the merchant
+       */
+      const struct TALER_MerchantPublicKeyP *merchant_pub;
+
+      /**
+       * size of the @e aborts array
+       */
+      unsigned int num_aborts;
+
+      /**
+       * merchant signatures refunding coins
+       */
+      const struct TALER_MERCHANT_AbortedCoin *aborts;
+    } ok;
+
+  } details;
+};
+
+
 /**
  * Callbacks of this type are used to serve the result of submitting a
  * /orders/$ID/abort request to a merchant.
  *
  * @param cls closure
- * @param hr HTTP response details
- * @param merchant_pub public key of the merchant
- * @param num_aborts size of the @a res array, 0 on errors
- * @param aborts merchant signatures refunding coins, NULL on errors
+ * @param ar response details
  */
 typedef void
 (*TALER_MERCHANT_AbortCallback) (
   void *cls,
-  const struct TALER_MERCHANT_HttpResponse *hr,
-  const struct TALER_MerchantPublicKeyP *merchant_pub,
-  unsigned int num_aborts,
-  const struct TALER_MERCHANT_AbortedCoin aborts[]);
+  const struct TALER_MERCHANT_AbortResponse *ar);
 
 
 /**
@@ -3048,22 +3082,52 @@ TALER_MERCHANT_order_forget_cancel (struct
 struct TALER_MERCHANT_OrderRefundHandle;
 
 
-// FIXME: change signature!
 /**
- * Callback to process a POST /orders/ID/refund request
+ * Response to a POST /orders/$ID/refund request
+ */
+struct TALER_MERCHANT_RefundResponse
+{
+  /**
+   * HTTP response details this request
+   */
+  struct TALER_MERCHANT_HttpResponse hr;
+
+  /**
+   * Details depending on HTTP status.
+   */
+  union
+  {
+    /**
+     * Details if status is #MHD_HTTP_OK.
+     */
+    struct
+    {
+
+      /**
+       * the refund uri offered to the wallet
+       */
+      const char *taler_refund_uri;
+
+      /**
+       * Hash of the contract a wallet may need to authorize obtaining the HTTP
+       * response.
+       */
+      struct TALER_PrivateContractHashP h_contract;
+    } ok;
+  } details;
+};
+
+
+/**
+ * Callback to process a POST /orders/$ID/refund request
  *
  * @param cls closure
- * @param hr HTTP response details this request
- * @param taler_refund_uri the refund uri offered to the wallet
- * @param h_contract hash of the contract a Browser may need to authorize
- *        obtaining the HTTP response.
+ * @param rr response details this request
  */
 typedef void
 (*TALER_MERCHANT_RefundCallback) (
   void *cls,
-  const struct TALER_MERCHANT_HttpResponse *hr,
-  const char *taler_refund_uri,
-  const struct TALER_PrivateContractHashP *h_contract);
+  const struct TALER_MERCHANT_RefundResponse *rr);
 
 
 /**
@@ -3130,39 +3194,87 @@ struct TALER_MERCHANT_RefundDetail
   struct TALER_Amount refund_amount;
 
   /**
-   * Public key of the exchange affirming the refund,
-   * only valid if the @e hr http_status is #MHD_HTTP_OK.
+   * Details depending on exchange HTTP status.
    */
-  struct TALER_ExchangePublicKeyP exchange_pub;
+  union
+  {
+    /**
+     * Details if exchange status is #MHD_HTTP_OK.
+     */
+    struct
+    {
+      /**
+       * Public key of the exchange affirming the refund,
+       * only valid if the @e hr http_status is #MHD_HTTP_OK.
+       */
+      struct TALER_ExchangePublicKeyP exchange_pub;
+
+      /**
+       * Signature of the exchange affirming the refund,
+       * only valid if the @e hr http_status is #MHD_HTTP_OK.
+       */
+      struct TALER_ExchangeSignatureP exchange_sig;
+    } ok;
+  } details;
+};
+
+
+/**
+ * Response to a POST /orders/$ID/refund request
+ * for wallet API.
+ */
+struct TALER_MERCHANT_WalletRefundResponse
+{
+  /**
+   * HTTP response details this request
+   */
+  struct TALER_MERCHANT_HttpResponse hr;
 
   /**
-   * Signature of the exchange affirming the refund,
-   * only valid if the @e hr http_status is #MHD_HTTP_OK.
+   * Details depending on HTTP status.
    */
-  struct TALER_ExchangeSignatureP exchange_sig;
+  union
+  {
+    /**
+     * Details if status is #MHD_HTTP_OK.
+     */
+    struct
+    {
+
+      /**
+       * Total amount of the refund that was granted
+       */
+      struct TALER_Amount refund_amount;
 
+      /**
+       * public key of the merchant signing the @e refunds
+       */
+      struct TALER_MerchantPublicKeyP merchant_pub;
+
+      /**
+       * array with details about the refunds obtained
+       */
+      const struct TALER_MERCHANT_RefundDetail *refunds;
+
+      /**
+       * length of the @e refunds array
+       */
+      unsigned int refunds_length;
+    } ok;
+  } details;
 };
 
 
-// FIXME: change signature!
 /**
  * Callback to process a (public) POST /orders/ID/refund request
  *
  * @param cls closure
- * @param hr HTTP response details
- * @param refund_amount what is the total amount of the refund that was granted
- * @param merchant_pub public key of the merchant signing the @a refunds
- * @param refunds array with details about the refunds obtained
- * @param refunds_length length of the @a refunds array
+ * @param wrr HTTP response details
  */
 typedef void
 (*TALER_MERCHANT_WalletRefundCallback) (
   void *cls,
-  const struct TALER_MERCHANT_HttpResponse *hr,
-  const struct TALER_Amount *refund_amount,
-  const struct TALER_MerchantPublicKeyP *merchant_pub,
-  struct TALER_MERCHANT_RefundDetail refunds[],
-  unsigned int refunds_length);
+  const struct TALER_MERCHANT_WalletRefundResponse *wrr);
 
 
 /**
@@ -3403,22 +3515,53 @@ struct TALER_MERCHANT_TransferData
 };
 
 
-// FIXME: change signature!
+/**
+ * Response from a GET /transfers request.
+ */
+struct TALER_MERCHANT_GetTransfersResponse
+{
+  /**
+   * HTTP response details
+   */
+  struct TALER_MERCHANT_HttpResponse hr;
+
+  /**
+   * Details depending on HTTP status.
+   */
+  union
+  {
+
+    /**
+     * Details for status #MHD_HTTP_OK.
+     */
+    struct
+    {
+
+      /**
+       * length of the @e transfers array
+       */
+      unsigned int transfers_length;
+
+      /**
+       * array with details about the transfers we received
+       */
+      const struct TALER_MERCHANT_TransferData *transfers;
+    } ok;
+  } details;
+};
+
+
 /**
  * Callbacks of this type are used to work the result of submitting a
  * GET /transfers request to a merchant
  *
  * @param cls closure
- * @param hr HTTP response details
- * @param transfers_length length of the @a transfers array
- * @param transfers array with details about the transfers we received
+ * @param gtr HTTP response details
  */
 typedef void
 (*TALER_MERCHANT_GetTransfersCallback) (
   void *cls,
-  const struct TALER_MERCHANT_HttpResponse *hr,
-  unsigned int transfers_length,
-  const struct TALER_MERCHANT_TransferData transfers[]);
+  const struct TALER_MERCHANT_GetTransfersResponse *gtr);
 
 
 /**
diff --git a/src/lib/merchant_api_get_reserves.c 
b/src/lib/merchant_api_get_reserves.c
index 9b3b45e9..cf462cfb 100644
--- a/src/lib/merchant_api_get_reserves.c
+++ b/src/lib/merchant_api_get_reserves.c
@@ -204,7 +204,6 @@ handle_reserves_get_finished (void *cls,
                 "Unexpected response code %u/%d\n",
                 (unsigned int) response_code,
                 (int) hr.ec);
-    response_code = 0;
     break;
   }
   rgh->cb (rgh->cb_cls,
diff --git a/src/lib/merchant_api_get_transfers.c 
b/src/lib/merchant_api_get_transfers.c
index f2f1186d..473d23a2 100644
--- a/src/lib/merchant_api_get_transfers.c
+++ b/src/lib/merchant_api_get_transfers.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2017, 2020 Taler Systems SA
+  Copyright (C) 2014-2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Lesser General Public License as published by the Free 
Software
@@ -81,23 +81,23 @@ handle_transfers_get_finished (void *cls,
 {
   struct TALER_MERCHANT_GetTransfersHandle *gth = cls;
   const json_t *json = response;
-  struct TALER_MERCHANT_HttpResponse hr = {
-    .http_status = (unsigned int) response_code,
-    .reply = json
+  struct TALER_MERCHANT_GetTransfersResponse gtr = {
+    .hr.http_status = (unsigned int) response_code,
+    .hr.reply = json
   };
 
   gth->job = NULL;
   switch (response_code)
   {
   case 0:
-    hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+    gtr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     break;
   case MHD_HTTP_OK:
     {
-      json_t *transfers;
+      const json_t *transfers;
       struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_json ("transfers",
-                               &transfers),
+        GNUNET_JSON_spec_array_const ("transfers",
+                                      &transfers),
         GNUNET_JSON_spec_end ()
       };
 
@@ -107,11 +107,11 @@ handle_transfers_get_finished (void *cls,
                              NULL, NULL))
       {
         GNUNET_break_op (0);
-        hr.http_status = 0;
-        hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+        gtr.hr.http_status = 0;
+        gtr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
         break;
       }
-      else
+
       {
         size_t tds_length;
         struct TALER_MERCHANT_TransferData *tds;
@@ -119,14 +119,6 @@ handle_transfers_get_finished (void *cls,
         unsigned int i;
         bool ok;
 
-        if (! json_is_array (transfers))
-        {
-          GNUNET_break_op (0);
-          GNUNET_JSON_parse_free (spec);
-          hr.http_status = 0;
-          hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
-          break;
-        }
         tds_length = json_array_size (transfers);
         tds = GNUNET_new_array (tds_length,
                                 struct TALER_MERCHANT_TransferData);
@@ -174,55 +166,51 @@ handle_transfers_get_finished (void *cls,
         {
           GNUNET_break_op (0);
           GNUNET_free (tds);
-          GNUNET_JSON_parse_free (spec);
-          hr.http_status = 0;
-          hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+          gtr.hr.http_status = 0;
+          gtr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
           break;
         }
+        gtr.details.ok.transfers = tds;
+        gtr.details.ok.transfers_length = tds_length;
         gth->cb (gth->cb_cls,
-                 &hr,
-                 tds_length,
-                 tds);
+                 &gtr);
         GNUNET_free (tds);
-        GNUNET_JSON_parse_free (spec);
         TALER_MERCHANT_transfers_get_cancel (gth);
         return;
       }
     }
   case MHD_HTTP_UNAUTHORIZED:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    gtr.hr.ec = TALER_JSON_get_error_code (json);
+    gtr.hr.hint = TALER_JSON_get_error_hint (json);
     /* Nothing really to verify, merchant says we need to authenticate. */
     break;
   case MHD_HTTP_NOT_FOUND:
     /* Nothing really to verify, this should never
        happen, we should pass the JSON reply to the application */
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    gtr.hr.ec = TALER_JSON_get_error_code (json);
+    gtr.hr.hint = TALER_JSON_get_error_hint (json);
     break;
   case MHD_HTTP_INTERNAL_SERVER_ERROR:
     /* Server had an internal issue; we should retry, but this API
        leaves this to the application */
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    gtr.hr.ec = TALER_JSON_get_error_code (json);
+    gtr.hr.hint = TALER_JSON_get_error_hint (json);
     break;
   default:
     /* unexpected response code */
     GNUNET_break_op (0);
     TALER_MERCHANT_parse_error_details_ (json,
                                          response_code,
-                                         &hr);
+                                         &gtr.hr);
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Unexpected response code %u/%d\n",
                 (unsigned int) response_code,
-                (int) hr.ec);
-    response_code = 0;
+                (int) gtr.hr.ec);
+    gtr.hr.http_status = 0;
     break;
   }
   gth->cb (gth->cb_cls,
-           &hr,
-           0,
-           NULL);
+           &gtr);
   TALER_MERCHANT_transfers_get_cancel (gth);
 }
 
diff --git a/src/lib/merchant_api_post_order_abort.c 
b/src/lib/merchant_api_post_order_abort.c
index d980ae18..a924119b 100644
--- a/src/lib/merchant_api_post_order_abort.c
+++ b/src/lib/merchant_api_post_order_abort.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2021 Taler Systems SA
+  Copyright (C) 2014-2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as
@@ -102,17 +102,20 @@ struct TALER_MERCHANT_OrderAbortHandle
  * OK. Otherwise returns #GNUNET_SYSERR.
  *
  * @param oah handle to operation that created the reply
+ * @param[in] ar abort response, partially initialized
  * @param json the reply to parse
  * @return #GNUNET_OK on success
  */
-static int
+static enum GNUNET_GenericReturnValue
 check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah,
+                    struct TALER_MERCHANT_AbortResponse *ar,
                     const json_t *json)
 {
   json_t *refunds;
   unsigned int num_refunds;
   struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("refunds", &refunds),
+    GNUNET_JSON_spec_json ("refunds",
+                           &refunds),
     GNUNET_JSON_spec_end ()
   };
 
@@ -189,18 +192,11 @@ check_abort_refund (struct 
TALER_MERCHANT_OrderAbortHandle *oah,
         }
       }
     }
-    {
-      struct TALER_MERCHANT_HttpResponse hr = {
-        .reply = json,
-        .http_status = MHD_HTTP_OK
-      };
-
-      oah->abort_cb (oah->abort_cb_cls,
-                     &hr,
-                     &oah->merchant_pub,
-                     num_refunds,
-                     res);
-    }
+    ar->details.ok.merchant_pub = &oah->merchant_pub;
+    ar->details.ok.num_aborts = num_refunds;
+    ar->details.ok.aborts = res;
+    oah->abort_cb (oah->abort_cb_cls,
+                   ar);
     oah->abort_cb = NULL;
   }
   GNUNET_JSON_parse_free (spec);
@@ -223,9 +219,9 @@ handle_abort_finished (void *cls,
 {
   struct TALER_MERCHANT_OrderAbortHandle *oah = cls;
   const json_t *json = response;
-  struct TALER_MERCHANT_HttpResponse hr = {
-    .http_status = (unsigned int) response_code,
-    .reply = json
+  struct TALER_MERCHANT_AbortResponse ar = {
+    .hr.http_status = (unsigned int) response_code,
+    .hr.reply = json
   };
 
   oah->job = NULL;
@@ -235,40 +231,41 @@ handle_abort_finished (void *cls,
   switch (response_code)
   {
   case 0:
-    hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+    ar.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     break;
   case MHD_HTTP_OK:
     if (GNUNET_OK ==
         check_abort_refund (oah,
+                            &ar,
                             json))
     {
       TALER_MERCHANT_order_abort_cancel (oah);
       return;
     }
-    hr.http_status = 0;
-    hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
+    ar.hr.http_status = 0;
+    ar.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     break;
   case MHD_HTTP_BAD_REQUEST:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ar.hr.ec = TALER_JSON_get_error_code (json);
+    ar.hr.hint = TALER_JSON_get_error_hint (json);
     /* This should never happen, either us or the
        merchant is buggy (or API version conflict); just
        pass JSON reply to the application */
     break;
   case MHD_HTTP_FORBIDDEN:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ar.hr.ec = TALER_JSON_get_error_code (json);
+    ar.hr.hint = TALER_JSON_get_error_hint (json);
     break;
   case MHD_HTTP_NOT_FOUND:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ar.hr.ec = TALER_JSON_get_error_code (json);
+    ar.hr.hint = TALER_JSON_get_error_hint (json);
     /* Nothing really to verify, this should never
  happen, we should pass the JSON reply to the
        application */
     break;
   case MHD_HTTP_REQUEST_TIMEOUT:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ar.hr.ec = TALER_JSON_get_error_code (json);
+    ar.hr.hint = TALER_JSON_get_error_hint (json);
     /* Nothing really to verify, merchant says one of
        the signatures is invalid; as we checked them,
        this should never happen, we should pass the JSON
@@ -276,19 +273,19 @@ handle_abort_finished (void *cls,
     break;
   case MHD_HTTP_PRECONDITION_FAILED:
     /* Our *payment* already succeeded fully. */
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ar.hr.ec = TALER_JSON_get_error_code (json);
+    ar.hr.hint = TALER_JSON_get_error_hint (json);
     break;
   case MHD_HTTP_INTERNAL_SERVER_ERROR:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    ar.hr.ec = TALER_JSON_get_error_code (json);
+    ar.hr.hint = TALER_JSON_get_error_hint (json);
     /* Server had an internal issue; we should retry,
        but this API leaves this to the application */
     break;
   case MHD_HTTP_BAD_GATEWAY:
     TALER_MERCHANT_parse_error_details_ (json,
                                          response_code,
-                                         &hr);
+                                         &ar.hr);
     /* Nothing really to verify, the merchant is blaming the exchange.
        We should pass the JSON reply to the application */
     break;
@@ -296,19 +293,16 @@ handle_abort_finished (void *cls,
     /* unexpected response code */
     TALER_MERCHANT_parse_error_details_ (json,
                                          response_code,
-                                         &hr);
+                                         &ar.hr);
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Unexpected response code %u/%d\n",
                 (unsigned int) response_code,
-                (int) hr.ec);
+                (int) ar.hr.ec);
     GNUNET_break_op (0);
     break;
   }
   oah->abort_cb (oah->abort_cb_cls,
-                 &hr,
-                 NULL,
-                 0,
-                 NULL);
+                 &ar);
   TALER_MERCHANT_order_abort_cancel (oah);
 }
 
diff --git a/src/lib/merchant_api_post_order_pay.c 
b/src/lib/merchant_api_post_order_pay.c
index aecc9fc4..6cfeb846 100644
--- a/src/lib/merchant_api_post_order_pay.c
+++ b/src/lib/merchant_api_post_order_pay.c
@@ -493,7 +493,7 @@ handle_pay_finished (void *cls,
         return; /* ! */
       case GNUNET_SYSERR:
         GNUNET_break_op (0);
-        response_code = 0;
+        pr.hr.http_status = 0;
         break;
       }
       break;
diff --git a/src/lib/merchant_api_post_order_refund.c 
b/src/lib/merchant_api_post_order_refund.c
index be996dc2..4414bd86 100644
--- a/src/lib/merchant_api_post_order_refund.c
+++ b/src/lib/merchant_api_post_order_refund.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2021 Taler Systems SA
+  Copyright (C) 2014-2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Lesser General Public License as published by the Free 
Software
@@ -85,30 +85,26 @@ handle_refund_finished (void *cls,
 {
   struct TALER_MERCHANT_OrderRefundHandle *orh = cls;
   const json_t *json = response;
-  struct TALER_MERCHANT_HttpResponse hr = {
-    .http_status = (unsigned int) response_code,
-    .reply = json
+  struct TALER_MERCHANT_RefundResponse rr = {
+    .hr.http_status = (unsigned int) response_code,
+    .hr.reply = json
   };
 
   orh->job = NULL;
   switch (response_code)
   {
   case 0:
-    hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
-    orh->cb (orh->cb_cls,
-             &hr,
-             NULL,
-             NULL);
+    rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     break;
   case MHD_HTTP_OK:
     {
-      const char *taler_refund_uri;
-      struct TALER_PrivateContractHashP h_contract;
       struct GNUNET_JSON_Specification spec[] = {
-        GNUNET_JSON_spec_string ("taler_refund_uri",
-                                 &taler_refund_uri),
-        GNUNET_JSON_spec_fixed_auto ("h_contract",
-                                     &h_contract),
+        GNUNET_JSON_spec_string (
+          "taler_refund_uri",
+          &rr.details.ok.taler_refund_uri),
+        GNUNET_JSON_spec_fixed_auto (
+          "h_contract",
+          &rr.details.ok.h_contract),
         GNUNET_JSON_spec_end ()
       };
 
@@ -118,51 +114,36 @@ handle_refund_finished (void *cls,
                              NULL, NULL))
       {
         GNUNET_break_op (0);
-        hr.http_status = 0;
-        hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
-        orh->cb (orh->cb_cls,
-                 &hr,
-                 NULL,
-                 NULL);
+        rr.hr.http_status = 0;
+        rr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
         break;
       }
-      orh->cb (orh->cb_cls,
-               &hr,
-               taler_refund_uri,
-               &h_contract);
-      GNUNET_JSON_parse_free (spec);
+      break;
     }
-    break;
   case MHD_HTTP_UNAUTHORIZED:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    rr.hr.ec = TALER_JSON_get_error_code (json);
+    rr.hr.hint = TALER_JSON_get_error_hint (json);
     /* Nothing really to verify, merchant says we need to authenticate. */
     break;
   case MHD_HTTP_FORBIDDEN:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
+    rr.hr.ec = TALER_JSON_get_error_code (json);
+    rr.hr.hint = TALER_JSON_get_error_hint (json);
     /* Nothing really to verify, merchant says we need to authenticate. */
     break;
   case MHD_HTTP_NOT_FOUND:
   case MHD_HTTP_CONFLICT:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
-    orh->cb (orh->cb_cls,
-             &hr,
-             NULL,
-             NULL);
+    rr.hr.ec = TALER_JSON_get_error_code (json);
+    rr.hr.hint = TALER_JSON_get_error_hint (json);
     break;
   default:
     GNUNET_break_op (0); /* unexpected status code */
     TALER_MERCHANT_parse_error_details_ (json,
                                          response_code,
-                                         &hr);
-    orh->cb (orh->cb_cls,
-             &hr,
-             NULL,
-             NULL);
+                                         &rr.hr);
     break;
   }
+  orh->cb (orh->cb_cls,
+           &rr);
   TALER_MERCHANT_post_order_refund_cancel (orh);
 }
 
diff --git a/src/lib/merchant_api_wallet_post_order_refund.c 
b/src/lib/merchant_api_wallet_post_order_refund.c
index fc4b0abd..ed3fc1b8 100644
--- a/src/lib/merchant_api_wallet_post_order_refund.c
+++ b/src/lib/merchant_api_wallet_post_order_refund.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2020 Taler Systems SA
+  Copyright (C) 2020-2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify it under the
   terms of the GNU Lesser General Public License as published by the Free 
Software
@@ -70,33 +70,6 @@ struct TALER_MERCHANT_WalletOrderRefundHandle
 };
 
 
-/**
- * Convenience function to call the callback in @a owgh with an error code of
- * @a ec and the exchange body being set to @a reply.
- *
- * @param orh handle providing callback
- * @param ec error code to return to application
- * @param reply JSON reply we got from the exchange, can be NULL
- */
-static void
-cb_failure (struct TALER_MERCHANT_WalletOrderRefundHandle *orh,
-            enum TALER_ErrorCode ec,
-            const json_t *reply)
-{
-  struct TALER_MERCHANT_HttpResponse hr = {
-    .ec = ec,
-    .reply = reply
-  };
-
-  orh->cb (orh->cb_cls,
-           &hr,
-           NULL,
-           NULL,
-           NULL,
-           0);
-}
-
-
 /**
  * Callback to process (public) POST /orders/ID/refund response
  *
@@ -111,37 +84,31 @@ handle_refund_finished (void *cls,
 {
   struct TALER_MERCHANT_WalletOrderRefundHandle *orh = cls;
   const json_t *json = response;
-  struct TALER_MERCHANT_HttpResponse hr = {
-    .http_status = (unsigned int) response_code,
-    .reply = json
+  struct TALER_MERCHANT_WalletRefundResponse wrr = {
+    .hr.http_status = (unsigned int) response_code,
+    .hr.reply = json
   };
 
   orh->job = NULL;
-
   switch (response_code)
   {
   case 0:
-    hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
-    orh->cb (orh->cb_cls,
-             &hr,
-             NULL,
-             NULL,
-             NULL,
-             0);
+    wrr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     break;
   case MHD_HTTP_OK:
     {
-      struct TALER_Amount refund_amount;
-      json_t *refunds;
-      struct TALER_MerchantPublicKeyP merchant_pub;
+      const json_t *refunds;
       unsigned int refund_len;
       struct GNUNET_JSON_Specification spec[] = {
-        TALER_JSON_spec_amount_any ("refund_amount",
-                                    &refund_amount),
-        GNUNET_JSON_spec_json ("refunds",
-                               &refunds),
-        GNUNET_JSON_spec_fixed_auto ("merchant_pub",
-                                     &merchant_pub),
+        TALER_JSON_spec_amount_any (
+          "refund_amount",
+          &wrr.details.ok.refund_amount),
+        GNUNET_JSON_spec_array_const (
+          "refunds",
+          &refunds),
+        GNUNET_JSON_spec_fixed_auto (
+          "merchant_pub",
+          &wrr.details.ok.merchant_pub),
         GNUNET_JSON_spec_end ()
       };
 
@@ -151,27 +118,13 @@ handle_refund_finished (void *cls,
                              NULL, NULL))
       {
         GNUNET_break_op (0);
-        cb_failure (orh,
-                    TALER_EC_GENERIC_REPLY_MALFORMED,
-                    json);
-        TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
-        return;
-      }
-
-      if (! json_is_array (refunds))
-      {
-        GNUNET_break_op (0);
-        cb_failure (orh,
-                    TALER_EC_GENERIC_REPLY_MALFORMED,
-                    json);
-        GNUNET_JSON_parse_free (spec);
-        TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
-        return;
+        wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+        wrr.hr.http_status = 0;
+        break;
       }
-
       refund_len = json_array_size (refunds);
       {
-        struct TALER_MERCHANT_RefundDetail rds[refund_len];
+        struct TALER_MERCHANT_RefundDetail rds[GNUNET_NZL (refund_len)];
 
         memset (rds,
                 0,
@@ -183,10 +136,26 @@ handle_refund_finished (void *cls,
                                                   i);
           const char *refund_status_type;
           uint32_t exchange_status;
-          int ret;
+          uint32_t eec = 0;
           struct GNUNET_JSON_Specification espec[] = {
+            GNUNET_JSON_spec_string ("type",
+                                     &refund_status_type),
             GNUNET_JSON_spec_uint32 ("exchange_status",
                                      &exchange_status),
+            GNUNET_JSON_spec_uint64 ("rtransaction_id",
+                                     &rd->rtransaction_id),
+            GNUNET_JSON_spec_fixed_auto ("coin_pub",
+                                         &rd->coin_pub),
+            TALER_JSON_spec_amount_any ("refund_amount",
+                                        &rd->refund_amount),
+            GNUNET_JSON_spec_mark_optional (
+              GNUNET_JSON_spec_object_const ("exchange_reply",
+                                             &rd->hr.reply),
+              NULL),
+            GNUNET_JSON_spec_mark_optional (
+              GNUNET_JSON_spec_uint32 ("exchange_code",
+                                       &eec),
+              NULL),
             GNUNET_JSON_spec_end ()
           };
 
@@ -196,151 +165,84 @@ handle_refund_finished (void *cls,
                                  NULL, NULL))
           {
             GNUNET_break_op (0);
-            cb_failure (orh,
-                        TALER_EC_GENERIC_REPLY_MALFORMED,
-                        json);
-            TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
-            return;
+            wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+            wrr.hr.http_status = 0;
+            goto finish;
           }
 
-          if (MHD_HTTP_OK == exchange_status)
+          rd->hr.http_status = exchange_status;
+          rd->hr.ec = (enum TALER_ErrorCode) eec;
+          switch (exchange_status)
           {
-            struct GNUNET_JSON_Specification rspec[] = {
-              GNUNET_JSON_spec_string ("type",
-                                       &refund_status_type),
-              GNUNET_JSON_spec_fixed_auto ("exchange_sig",
-                                           &rd->exchange_sig),
-              GNUNET_JSON_spec_fixed_auto ("exchange_pub",
-                                           &rd->exchange_pub),
-              GNUNET_JSON_spec_uint64 ("rtransaction_id",
-                                       &rd->rtransaction_id),
-              GNUNET_JSON_spec_fixed_auto ("coin_pub",
-                                           &rd->coin_pub),
-              TALER_JSON_spec_amount_any ("refund_amount",
-                                          &rd->refund_amount),
-              GNUNET_JSON_spec_end ()
-            };
-
-            ret = GNUNET_JSON_parse (jrefund,
-                                     rspec,
-                                     NULL, NULL);
-            if (GNUNET_OK == ret)
+          case MHD_HTTP_OK:
             {
-              /* check that type field is correct */
-              if (0 != strcmp ("success", refund_status_type))
-              {
-                GNUNET_break_op (0);
-                ret = GNUNET_SYSERR;
-              }
-            }
-          }
-          else
-          {
-            struct GNUNET_JSON_Specification rspec[] = {
-              GNUNET_JSON_spec_string ("type",
-                                       &refund_status_type),
-              GNUNET_JSON_spec_fixed_auto ("coin_pub",
-                                           &rd->coin_pub),
-              GNUNET_JSON_spec_uint64 ("rtransaction_id",
-                                       &rd->rtransaction_id),
-              TALER_JSON_spec_amount_any ("refund_amount",
-                                          &rd->refund_amount),
-              GNUNET_JSON_spec_end ()
-            };
-
-            ret = GNUNET_JSON_parse (jrefund,
+              struct GNUNET_JSON_Specification rspec[] = {
+                GNUNET_JSON_spec_fixed_auto ("exchange_sig",
+                                             &rd->details.ok.exchange_sig),
+                GNUNET_JSON_spec_fixed_auto ("exchange_pub",
+                                             &rd->details.ok.exchange_pub),
+                GNUNET_JSON_spec_end ()
+              };
+
+              if (GNUNET_OK !=
+                  GNUNET_JSON_parse (jrefund,
                                      rspec,
-                                     NULL, NULL);
-            if (GNUNET_OK == ret)
-            {
-              /* parse optional arguments */
-              json_t *jec;
-
-              jec = json_object_get (jrefund,
-                                     "exchange_code");
-              if (NULL != jec)
+                                     NULL,
+                                     NULL))
               {
-                if (! json_is_integer (jec))
-                {
-                  GNUNET_break_op (0);
-                  ret = GNUNET_SYSERR;
-                }
-                else
-                {
-                  rd->hr.ec = (enum TALER_ErrorCode) json_integer_value (jec);
-                }
+                GNUNET_break_op (0);
+                wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+                wrr.hr.http_status = 0;
+                goto finish;
               }
-              rd->hr.reply = json_object_get (jrefund,
-                                              "exchange_reply");
               /* check that type field is correct */
-              if (0 != strcmp ("failure", refund_status_type))
+              if (0 != strcmp ("success",
+                               refund_status_type))
               {
                 GNUNET_break_op (0);
-                ret = GNUNET_SYSERR;
+                wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+                wrr.hr.http_status = 0;
+                goto finish;
               }
             }
-          }
-          if (GNUNET_OK != ret)
-          {
-            GNUNET_break_op (0);
-            cb_failure (orh,
-                        TALER_EC_GENERIC_REPLY_MALFORMED,
-                        json);
-            TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
-            return;
-          }
-          rd->hr.http_status = exchange_status;
-        }
-
-        {
-          struct TALER_MERCHANT_HttpResponse hr = {
-            .reply = json,
-            .http_status = MHD_HTTP_OK
-          };
+            break; /* end MHD_HTTP_OK */
+          default:
+            if (0 != strcmp ("failure",
+                             refund_status_type))
+            {
+              GNUNET_break_op (0);
+              wrr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
+              wrr.hr.http_status = 0;
+              goto finish;
+            }
+          } /* switch on exchange status code */
+        } /* for all refunds */
 
-          orh->cb (orh->cb_cls,
-                   &hr,
-                   &refund_amount,
-                   &merchant_pub,
-                   rds,
-                   refund_len);
-        }
-      }
-      GNUNET_JSON_parse_free (spec);
-    }
+        wrr.details.ok.refunds = rds;
+        wrr.details.ok.refunds_length = refund_len;
+        orh->cb (orh->cb_cls,
+                 &wrr);
+        return;
+      } /* end 'rds' scope */
+    } /* case MHD_HTTP_OK */
     break;
   case MHD_HTTP_NO_CONTENT:
-    orh->cb (orh->cb_cls,
-             &hr,
-             NULL,
-             NULL,
-             NULL,
-             0);
     break;
   case MHD_HTTP_CONFLICT:
   case MHD_HTTP_NOT_FOUND:
-    hr.ec = TALER_JSON_get_error_code (json);
-    hr.hint = TALER_JSON_get_error_hint (json);
-    orh->cb (orh->cb_cls,
-             &hr,
-             NULL,
-             NULL,
-             NULL,
-             0);
+    wrr.hr.ec = TALER_JSON_get_error_code (json);
+    wrr.hr.hint = TALER_JSON_get_error_hint (json);
     break;
   default:
     GNUNET_break_op (0); /* unexpected status code */
     TALER_MERCHANT_parse_error_details_ (json,
                                          response_code,
-                                         &hr);
-    orh->cb (orh->cb_cls,
-             &hr,
-             NULL,
-             NULL,
-             NULL,
-             0);
+                                         &wrr.hr);
     break;
   }
+finish:
+  orh->cb (orh->cb_cls,
+           &wrr);
   TALER_MERCHANT_wallet_post_order_refund_cancel (orh);
 }
 
diff --git a/src/testing/testing_api_cmd_abort_order.c 
b/src/testing/testing_api_cmd_abort_order.c
index c90851f8..58b11308 100644
--- a/src/testing/testing_api_cmd_abort_order.c
+++ b/src/testing/testing_api_cmd_abort_order.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2018, 2020 Taler Systems SA
+  Copyright (C) 2014-2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as
@@ -165,48 +165,42 @@ build_coins (struct TALER_MERCHANT_AbortCoin **ac,
  * in the state.
  *
  * @param cls closure.
- * @param hr HTTP response
- * @param merchant_pub public key of the merchant refunding the
- *        contract.
- * @param num_aborts length of the @a res array
- * @param res array containing the abort confirmations
+ * @param ar response
  */
 static void
 abort_cb (void *cls,
-          const struct TALER_MERCHANT_HttpResponse *hr,
-          const struct TALER_MerchantPublicKeyP *merchant_pub,
-          unsigned int num_aborts,
-          const struct TALER_MERCHANT_AbortedCoin res[])
+          const struct TALER_MERCHANT_AbortResponse *ar)
 {
   struct AbortState *as = cls;
 
   as->oah = NULL;
-  if (as->http_status != hr->http_status)
+  if (as->http_status != ar->hr.http_status)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Unexpected response code %u (%d) to command `%s' (expected 
%u)\n",
-                hr->http_status,
-                (int) hr->ec,
+                ar->hr.http_status,
+                (int) ar->hr.ec,
                 TALER_TESTING_interpreter_get_current_label (as->is),
                 as->http_status);
     TALER_TESTING_FAIL (as->is);
   }
-  if ( (MHD_HTTP_OK == hr->http_status) &&
-       (TALER_EC_NONE == hr->ec) )
+  if ( (MHD_HTTP_OK == ar->hr.http_status) &&
+       (TALER_EC_NONE == ar->hr.ec) )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Received %u refunds\n",
-                num_aborts);
-    as->acs_length = num_aborts;
-    as->acs = GNUNET_new_array (num_aborts,
+                ar->details.ok.num_aborts);
+    as->acs_length = ar->details.ok.num_aborts;
+    as->acs = GNUNET_new_array (as->acs_length,
                                 struct TALER_MERCHANT_AbortedCoin);
     GNUNET_memcpy (as->acs,
-                   res,
-                   num_aborts * sizeof (struct TALER_MERCHANT_AbortedCoin));
+                   ar->details.ok.aborts,
+                   as->acs_length
+                   * sizeof (struct TALER_MERCHANT_AbortedCoin));
   }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Successful pay-abort (HTTP status: %u)\n",
-              hr->http_status);
+              ar->hr.http_status);
   TALER_TESTING_interpreter_next (as->is);
 }
 
diff --git a/src/testing/testing_api_cmd_get_transfers.c 
b/src/testing/testing_api_cmd_get_transfers.c
index 33c2d462..50544587 100644
--- a/src/testing/testing_api_cmd_get_transfers.c
+++ b/src/testing/testing_api_cmd_get_transfers.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2018, 2020 Taler Systems SA
+  Copyright (C) 2014-2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as
@@ -83,42 +83,40 @@ struct GetTransfersState
  * Check the result of our GET /transfers request to a merchant
  *
  * @param cls closure
- * @param hr HTTP response details
- * @param transfers_length length of the @a transfers array
- * @param transfers array with details about the transfers we received
+ * @param gtr response details
  */
 static void
 get_transfers_cb (
   void *cls,
-  const struct TALER_MERCHANT_HttpResponse *hr,
-  unsigned int transfers_length,
-  const struct TALER_MERCHANT_TransferData transfers[])
+  const struct TALER_MERCHANT_GetTransfersResponse *gtr)
 {
   struct GetTransfersState *gts = cls;
 
   gts->gth = NULL;
-  if (gts->http_status != hr->http_status)
+  if (gts->http_status != gtr->hr.http_status)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Unexpected response code %u (%d) to command %s\n",
-                hr->http_status,
-                (int) hr->ec,
+                gtr->hr.http_status,
+                (int) gtr->hr.ec,
                 TALER_TESTING_interpreter_get_current_label (gts->is));
     TALER_TESTING_interpreter_fail (gts->is);
     return;
   }
-  switch (hr->http_status)
+  switch (gtr->hr.http_status)
   {
   case MHD_HTTP_OK:
-    if (transfers_length != gts->transfers_length)
+    if (gtr->details.ok.transfers_length != gts->transfers_length)
     {
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   "Transfers length does not match\n");
       TALER_TESTING_interpreter_fail (gts->is);
       return;
     }
-    for (unsigned int i = 0; i < transfers_length; ++i)
+    for (unsigned int i = 0; i < gtr->details.ok.transfers_length; ++i)
     {
+      const struct TALER_MERCHANT_TransferData *transfer
+        = &gtr->details.ok.transfers[i];
       const struct TALER_TESTING_Command *transfer_cmd;
 
       transfer_cmd = TALER_TESTING_interpreter_lookup_command (
@@ -145,7 +143,7 @@ get_transfers_cb (
           return;
         }
         if (0 != GNUNET_memcmp (wtid,
-                                &transfers[i].wtid))
+                                &transfer->wtid))
         {
           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                       "Wire transfer id does not match\n");
@@ -154,7 +152,7 @@ get_transfers_cb (
         }
         TALER_TESTING_cmd_merchant_post_transfer_set_serial (
           (struct TALER_TESTING_Command *) transfer_cmd,
-          transfers[i].credit_serial);
+          transfer->credit_serial);
       }
       {
         const char **payto_uri;
@@ -169,12 +167,12 @@ get_transfers_cb (
           return;
         }
         if (0 != strcmp (*payto_uri,
-                         transfers[i].payto_uri))
+                         transfer->payto_uri))
         {
           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                       "Wire transfer payto uri does not match: %s != %s\n",
                       *payto_uri,
-                      transfers[i].payto_uri);
+                      transfer->payto_uri);
           TALER_TESTING_interpreter_fail (gts->is);
           return;
         }
@@ -193,9 +191,9 @@ get_transfers_cb (
         }
         if ( (GNUNET_OK !=
               TALER_amount_cmp_currency (credit_amount,
-                                         &transfers[i].credit_amount)) ||
+                                         &transfer->credit_amount)) ||
              (0 != TALER_amount_cmp (credit_amount,
-                                     &transfers[i].credit_amount)))
+                                     &transfer->credit_amount)))
         {
           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                       "Wire transfer credit amount does not match\n");
@@ -216,7 +214,7 @@ get_transfers_cb (
           return;
         }
         if (0 != strcmp (*exchange_url,
-                         transfers[i].exchange_url))
+                         transfer->exchange_url))
         {
           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                       "Wire transfer exchange url does not match\n");
@@ -228,7 +226,9 @@ get_transfers_cb (
     break;
   default:
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Unhandled HTTP status.\n");
+                "Unhandled HTTP status %u.\n",
+                gtr->hr.http_status);
+    break;
   }
   TALER_TESTING_interpreter_next (gts->is);
 }
@@ -290,11 +290,12 @@ get_transfers_cleanup (void *cls,
 
 
 struct TALER_TESTING_Command
-TALER_TESTING_cmd_merchant_get_transfers (const char *label,
-                                          const char *merchant_url,
-                                          const char *payto_uri,
-                                          unsigned int http_code,
-                                          ...)
+TALER_TESTING_cmd_merchant_get_transfers (
+  const char *label,
+  const char *merchant_url,
+  const char *payto_uri,
+  unsigned int http_code,
+  ...)
 {
   struct GetTransfersState *gts;
 
diff --git a/src/testing/testing_api_cmd_refund_order.c 
b/src/testing/testing_api_cmd_refund_order.c
index 0f94622c..cac965c5 100644
--- a/src/testing/testing_api_cmd_refund_order.c
+++ b/src/testing/testing_api_cmd_refund_order.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2014-2019 Taler Systems SA
+  Copyright (C) 2014-2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as
@@ -76,39 +76,34 @@ struct RefundState
  * if the HTTP response code is the one expected.
  *
  * @param cls closure
- * @param hr HTTP response
- * @param taler_refund_uri the refund uri offered to the wallet
- * @param h_contract hash of the contract a Browser may need to authorize
- *        obtaining the HTTP response.
+ * @param rr response
  */
 static void
 refund_cb (void *cls,
-           const struct TALER_MERCHANT_HttpResponse *hr,
-           const char *taler_refund_uri,
-           const struct TALER_PrivateContractHashP *h_contract)
+           const struct TALER_MERCHANT_RefundResponse *rr)
 {
   struct RefundState *ris = cls;
 
-  (void) h_contract;
   ris->orh = NULL;
-  if (ris->http_code != hr->http_status)
+  if (ris->http_code != rr->hr.http_status)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Expected status %u, got %u(%d) for refund increase\n",
                 ris->http_code,
-                hr->http_status,
-                (int) hr->ec);
+                rr->hr.http_status,
+                (int) rr->hr.ec);
     TALER_TESTING_FAIL (ris->is);
   }
-  switch (hr->http_status)
+  switch (rr->hr.http_status)
   {
   case MHD_HTTP_OK:
     {
       struct TALER_MERCHANT_RefundUriData rud;
 
       if (GNUNET_OK !=
-          TALER_MERCHANT_parse_refund_uri (taler_refund_uri,
-                                           &rud))
+          TALER_MERCHANT_parse_refund_uri (
+            rr->details.ok.taler_refund_uri,
+            &rud))
       {
         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                     "Taler refund uri is malformed\n");
@@ -165,7 +160,7 @@ refund_cb (void *cls,
   default:
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                 "Unhandled HTTP status %u for refund order.\n",
-                hr->http_status);
+                rr->hr.http_status);
   }
   TALER_TESTING_interpreter_next (ris->is);
 }
diff --git a/src/testing/testing_api_cmd_wallet_post_orders_refund.c 
b/src/testing/testing_api_cmd_wallet_post_orders_refund.c
index b9e7981f..fff3bb33 100644
--- a/src/testing/testing_api_cmd_wallet_post_orders_refund.c
+++ b/src/testing/testing_api_cmd_wallet_post_orders_refund.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  Copyright (C) 2020 Taler Systems SA
+  Copyright (C) 2020-2023 Taler Systems SA
 
   TALER is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as
@@ -76,44 +76,39 @@ struct WalletRefundState
  * if the HTTP response code is the one expected.
  *
  * @param cls closure
- * @param hr HTTP response
- * @param refund_amount refund amount
- * @param merchant_pub public key of the merchant giving the refund
- * @param refunds the given refunds
- * @param refunds_length how many refunds were given
+ * @param wrr response
  */
 static void
 refund_cb (
   void *cls,
-  const struct TALER_MERCHANT_HttpResponse *hr,
-  const struct TALER_Amount *refund_amount,
-  const struct TALER_MerchantPublicKeyP *merchant_pub,
-  struct TALER_MERCHANT_RefundDetail refunds[],
-  unsigned int refunds_length)
+  const struct TALER_MERCHANT_WalletRefundResponse *wrr)
 {
   struct WalletRefundState *wrs = cls;
 
   wrs->orh = NULL;
-  if (wrs->http_code != hr->http_status)
+  if (wrs->http_code != wrr->hr.http_status)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 "Expected status %u, got %u(%d) for refund increase\n",
                 wrs->http_code,
-                hr->http_status,
-                (int) hr->ec);
+                wrr->hr.http_status,
+                (int) wrr->hr.ec);
     TALER_TESTING_FAIL (wrs->is);
   }
-  switch (hr->http_status)
+  switch (wrr->hr.http_status)
   {
   case MHD_HTTP_OK:
     {
       struct TALER_Amount refunded_total;
-      if (refunds_length > 0)
+      if (wrr->details.ok.refunds_length > 0)
         GNUNET_assert (GNUNET_OK ==
-                       TALER_amount_set_zero 
(refunds[0].refund_amount.currency,
-                                              &refunded_total));
-      for (unsigned int i = 0; i < refunds_length; ++i)
+                       TALER_amount_set_zero (
+                         wrr->details.ok.refunds[0].refund_amount.currency,
+                         &refunded_total));
+      for (unsigned int i = 0; i < wrr->details.ok.refunds_length; ++i)
       {
+        const struct TALER_MERCHANT_RefundDetail *refund
+          = &wrr->details.ok.refunds[wrr->details.ok.refunds_length - 1 - i];
         const struct TALER_TESTING_Command *refund_cmd;
         const struct TALER_Amount *expected_amount;
 
@@ -133,13 +128,12 @@ refund_cb (
         /* The most recent refunds are returned first */
         GNUNET_assert (0 <= TALER_amount_add (&refunded_total,
                                               &refunded_total,
-                                              &refunds[refunds_length - 1
-                                                       - i].refund_amount));
-        if ((GNUNET_OK !=
-             TALER_amount_cmp_currency (expected_amount,
-                                        &refunded_total)) ||
-            (0 != TALER_amount_cmp (expected_amount,
-                                    &refunded_total)))
+                                              &refund->refund_amount));
+        if ( (GNUNET_OK !=
+              TALER_amount_cmp_currency (expected_amount,
+                                         &refunded_total)) ||
+             (0 != TALER_amount_cmp (expected_amount,
+                                     &refunded_total)) )
         {
           GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                       "Refund amounts do not match\n");
@@ -150,7 +144,6 @@ refund_cb (
     }
     break;
   default:
-
     break;
   }
   TALER_TESTING_interpreter_next (wrs->is);

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]