gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 82/277: implement abort client lib


From: gnunet
Subject: [taler-merchant] 82/277: implement abort client lib
Date: Sun, 05 Jul 2020 20:49:55 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit 35623b7bc44210bc55a429a4f81b1194bb798034
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat May 2 23:24:22 2020 +0200

    implement abort client lib
---
 src/include/taler_merchant_service.h               |  55 +-
 src/lib/Makefile.am                                |   1 +
 src/lib/merchant_api_post_order_abort.c            | 186 ++-----
 src/testing/Makefile.am                            |   2 +
 src/testing/testing_api_cmd_abort_order.c          | 460 ++++++++++++++++
 src/testing/testing_api_cmd_pay_abort.c            | 595 ---------------------
 ...g_api_cmd_pay.c => testing_api_cmd_pay_order.c} |   0
 7 files changed, 534 insertions(+), 765 deletions(-)

diff --git a/src/include/taler_merchant_service.h 
b/src/include/taler_merchant_service.h
index 5037201..d32d507 100644
--- a/src/include/taler_merchant_service.h
+++ b/src/include/taler_merchant_service.h
@@ -1657,6 +1657,11 @@ struct TALER_MERCHANT_AbortedCoin
    */
   struct TALER_ExchangePublicKeyP exchange_pub;
 
+  /**
+   * Refund fee charged by the exchange. The API will have checked the
+   * signature, but NOT that this is the expected fee.
+   */
+  struct TALER_Amount refund_fee;
 };
 
 
@@ -1679,6 +1684,29 @@ typedef void
   const struct TALER_MERCHANT_AbortedCoin aborts[]);
 
 
+/**
+ * Information we need from the wallet for each coin when aborting.
+ */
+struct TALER_MERCHANT_AbortCoin
+{
+
+  /**
+   * Coin's public key.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * Amount this coin contributes to (including fee).
+   */
+  struct TALER_Amount amount_with_fee;
+
+  /**
+   * URL of the exchange that issued @e coin_priv.
+   */
+  const char *exchange_url;
+
+};
+
 /**
  * Run a payment abort operation, asking for the payment to be aborted,
  * yieldingrefunds for coins that were previously spend on a payment that
@@ -1688,38 +1716,23 @@ typedef void
  *
  * @param ctx execution context
  * @param merchant_url base URL of the merchant
- * @param h_wire hash of the merchant’s account details
+ * @param order_id order to abort
  * @param h_contract hash of the contact of the merchant with the customer
- * @param transaction_id transaction id for the transaction between merchant 
and customer
- * @param amount total value of the contract to be paid to the merchant
- * @param max_fee maximum fee covered by the merchant (according to the 
contract)
  * @param merchant_pub the public key of the merchant (used to identify the 
merchant for refund requests)
- * @param merchant_sig signature from the merchant over the original contract
- * @param timestamp timestamp when the contract was finalized, must match 
approximately the current time of the merchant
- * @param refund_deadline date until which the merchant can issue a refund to 
the customer via the merchant (can be zero if refunds are not allowed)
- * @param pay_deadline maximum time limit to pay for this contract
  * @param num_coins number of coins used to pay
  * @param coins array of coins we use to pay
- * @param coin_sig the signature made with purpose 
#TALER_SIGNATURE_WALLET_COIN_DEPOSIT made by the customer with the coin’s 
private key.
- * @param payref_cb the callback to call when a reply for this request is 
available
- * @param payref_cb_cls closure for @a pay_cb
+ * @param cb the callback to call when a reply for this request is available
+ * @param cb_cls closure for @a cb
  * @return a handle for this request
  */
 struct TALER_MERCHANT_OrderAbortHandle *
 TALER_MERCHANT_order_abort (struct GNUNET_CURL_Context *ctx,
                             const char *merchant_url,
-                            const struct GNUNET_HashCode *h_contract,
-                            const struct TALER_Amount *amount,
-                            const struct TALER_Amount *max_fee,
-                            const struct TALER_MerchantPublicKeyP 
*merchant_pub,
-                            const struct TALER_MerchantSignatureP 
*merchant_sig,
-                            struct GNUNET_TIME_Absolute timestamp,
-                            struct GNUNET_TIME_Absolute refund_deadline,
-                            struct GNUNET_TIME_Absolute pay_deadline,
-                            const struct GNUNET_HashCode *h_wire,
                             const char *order_id,
+                            const struct TALER_MerchantPublicKeyP 
*merchant_pub,
+                            const struct GNUNET_HashCode *h_contract,
                             unsigned int num_coins,
-                            const struct TALER_MERCHANT_PayCoin coins[],
+                            const struct TALER_MERCHANT_AbortCoin coins[],
                             TALER_MERCHANT_AbortCallback cb,
                             void *cb_cls);
 
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index ddf42af..c952011 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -29,6 +29,7 @@ libtalermerchant_la_SOURCES = \
   merchant_api_post_instances.c \
   merchant_api_post_products.c \
   merchant_api_post_orders.c \
+  merchant_api_post_order_abort.c \
   merchant_api_post_order_claim.c \
   merchant_api_post_order_pay.c \
   merchant_api_post_order_refund.c \
diff --git a/src/lib/merchant_api_post_order_abort.c 
b/src/lib/merchant_api_post_order_abort.c
index 6ee20f9..3f1a7c0 100644
--- a/src/lib/merchant_api_post_order_abort.c
+++ b/src/lib/merchant_api_post_order_abort.c
@@ -95,16 +95,16 @@ struct TALER_MERCHANT_OrderAbortHandle
 
 
 /**
- * Check that the response for a /pay refund is well-formed,
+ * Check that the response for an abort is well-formed,
  * and call the application callback with the result if it is
  * OK. Otherwise returns #GNUNET_SYSERR.
  *
- * @param ph handle to operation that created the reply
+ * @param oah handle to operation that created the reply
  * @param json the reply to parse
  * @return #GNUNET_OK on success
  */
 static int
-check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *ph,
+check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle *oah,
                     const json_t *json)
 {
   json_t *refunds;
@@ -161,9 +161,10 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle 
*ph,
                                        &res[i].exchange_sig),
           GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                        &res[i].exchange_pub),
+          TALER_JSON_spec_amount ("refund_fee",
+                                  &res[i].refund_fee),
           GNUNET_JSON_spec_end ()
         };
-        int found;
 
         if (GNUNET_OK !=
             GNUNET_JSON_parse (exchange_reply,
@@ -177,7 +178,7 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle 
*ph,
       }
 
       {
-        struct TALER_RefundRequestPS rr = {
+        struct TALER_RefundConfirmationPS rr = {
           .purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_REFUND),
           .purpose.size = htonl (sizeof (rr)),
           .h_contract_terms = oah->h_contract_terms,
@@ -189,12 +190,12 @@ check_abort_refund (struct 
TALER_MERCHANT_OrderAbortHandle *ph,
         TALER_amount_hton (&rr.refund_amount,
                            &oah->coins[i].amount_with_fee);
         TALER_amount_hton (&rr.refund_fee,
-                           &oah->coins[i].refund_fee);
+                           &res[i].refund_fee);
         if (GNUNET_OK !=
-            GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_MERCHANT_REFUND,
+            GNUNET_CRYPTO_eddsa_verify 
(TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND,
                                         &rr,
-                                        &sig->eddsa_sig,
-                                        &merchant_pub.eddsa_pub))
+                                        &res[i].exchange_sig.eddsa_signature,
+                                        &res[i].exchange_pub.eddsa_pub))
         {
           GNUNET_break_op (0);
           GNUNET_JSON_parse_free (spec);
@@ -210,6 +211,7 @@ check_abort_refund (struct TALER_MERCHANT_OrderAbortHandle 
*ph,
 
       oah->abort_cb (oah->abort_cb_cls,
                      &hr,
+                     &oah->merchant_pub,
                      num_refunds,
                      res);
     }
@@ -220,124 +222,6 @@ check_abort_refund (struct 
TALER_MERCHANT_OrderAbortHandle *ph,
 }
 
 
-/**
- * We got a 403 response back from the exchange (or the merchant).
- * Now we need to check the provided cryptographic proof that the
- * coin was actually already spent!
- *
- * @param pc handle of the original coin we paid with
- * @param json cryptographic proof of coin's transaction
- *        history as was returned by the exchange/merchant
- * @return #GNUNET_OK if proof checks out
- */
-static int
-check_coin_history (const struct TALER_MERCHANT_PaidCoin *pc,
-                    json_t *json)
-{
-  struct TALER_Amount spent;
-  struct TALER_Amount spent_plus_contrib;
-
-  if (GNUNET_OK !=
-      TALER_EXCHANGE_verify_coin_history (NULL, /* do not verify fees */
-                                          pc->amount_with_fee.currency,
-                                          &pc->coin_pub,
-                                          json,
-                                          &spent))
-  {
-    /* Exchange's history fails to verify */
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  if (0 >
-      TALER_amount_add (&spent_plus_contrib,
-                        &spent,
-                        &pc->amount_with_fee))
-  {
-    /* We got an integer overflow? Bad application! */
-    GNUNET_break (0);
-    return GNUNET_SYSERR;
-  }
-  if (-1 != TALER_amount_cmp (&pc->denom_value,
-                              &spent_plus_contrib))
-  {
-    /* according to our calculations, the transaction should
-       have still worked, exchange error! */
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              "Accepting proof of double-spending\n");
-  return GNUNET_OK;
-}
-
-
-/**
- * We got a 409 response back from the exchange (or the merchant).
- * Now we need to check the provided cryptographic proof that the
- * coin was actually already spent!
- *
- * @param ph handle of the original pay operation
- * @param json cryptographic proof returned by the
- *        exchange/merchant
- * @return #GNUNET_OK if proof checks out
- */
-static int
-check_conflict (struct TALER_MERCHANT_Pay *ph,
-                const json_t *json)
-{
-  json_t *history;
-  json_t *ereply;
-  struct TALER_CoinSpendPublicKeyP coin_pub;
-  struct GNUNET_JSON_Specification spec[] = {
-    GNUNET_JSON_spec_json ("exchange_reply", &ereply),
-    GNUNET_JSON_spec_fixed_auto ("coin_pub", &coin_pub),
-    GNUNET_JSON_spec_end ()
-  };
-  struct GNUNET_JSON_Specification hspec[] = {
-    GNUNET_JSON_spec_json ("history", &history),
-    GNUNET_JSON_spec_end ()
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (json,
-                         spec,
-                         NULL, NULL))
-  {
-    GNUNET_break_op (0);
-    return GNUNET_SYSERR;
-  }
-  if (GNUNET_OK !=
-      GNUNET_JSON_parse (ereply,
-                         hspec,
-                         NULL, NULL))
-  {
-    GNUNET_break_op (0);
-    GNUNET_JSON_parse_free (spec);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_JSON_parse_free (spec);
-
-  for (unsigned int i = 0; i<oah->num_coins; i++)
-  {
-    if (0 == memcmp (&oah->coins[i].coin_pub,
-                     &coin_pub,
-                     sizeof (struct TALER_CoinSpendPublicKeyP)))
-    {
-      int ret;
-
-      ret = check_coin_history (&oah->coins[i],
-                                history);
-      GNUNET_JSON_parse_free (hspec);
-      return ret;
-    }
-  }
-  GNUNET_break_op (0); /* complaint is not about any of the coins
-                          that we actually paid with... */
-  GNUNET_JSON_parse_free (hspec);
-  return GNUNET_SYSERR;
-}
-
-
 /**
  * Function called when we're done processing the
  * abort request.
@@ -436,9 +320,10 @@ handle_abort_finished (void *cls,
   }
   oah->abort_cb (oah->abort_cb_cls,
                  &hr,
+                 NULL,
                  0,
                  NULL);
-  TALER_MERCHANT_abort_cancel (oah);
+  TALER_MERCHANT_order_abort_cancel (oah);
 }
 
 
@@ -470,6 +355,7 @@ TALER_MERCHANT_order_abort (struct GNUNET_CURL_Context *ctx,
 {
   struct TALER_MERCHANT_OrderAbortHandle *oah;
   json_t *abort_obj;
+  json_t *j_coins;
 
   j_coins = json_array ();
   if (NULL == j_coins)
@@ -542,30 +428,32 @@ TALER_MERCHANT_order_abort (struct GNUNET_CURL_Context 
*ctx,
   memcpy (oah->coins,
           coins,
           num_coins * sizeof (struct TALER_MERCHANT_AbortCoin));
-
-  eh = curl_easy_init ();
-  GNUNET_assert (NULL != eh);
-  if (GNUNET_OK !=
-      TALER_curl_easy_post (&oah->post_ctx,
-                            eh,
-                            abort_obj))
   {
-    GNUNET_break (0);
+    CURL *eh;
+
+    eh = curl_easy_init ();
+    GNUNET_assert (NULL != eh);
+    if (GNUNET_OK !=
+        TALER_curl_easy_post (&oah->post_ctx,
+                              eh,
+                              abort_obj))
+    {
+      GNUNET_break (0);
+      json_decref (abort_obj);
+      GNUNET_free (oah);
+      return NULL;
+    }
     json_decref (abort_obj);
-    GNUNET_free (oah);
-    return NULL;
+    GNUNET_assert (CURLE_OK ==
+                   curl_easy_setopt (eh,
+                                     CURLOPT_URL,
+                                     oah->url));
+    oah->job = GNUNET_CURL_job_add2 (ctx,
+                                     eh,
+                                     oah->post_ctx.headers,
+                                     &handle_abort_finished,
+                                     oah);
   }
-  json_decref (abort_obj);
-  GNUNET_assert (CURLE_OK ==
-                 curl_easy_setopt (eh,
-                                   CURLOPT_URL,
-                                   oah->url));
-  oah->job = GNUNET_CURL_job_add2 (ctx,
-                                   eh,
-                                   oah->post_ctx.headers,
-                                   &handle_abort_finished,
-                                   oah);
-
   return oah;
 }
 
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index 24374ee..e939513 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -15,6 +15,7 @@ libtalermerchanttesting_la_LDFLAGS = \
 
 libtalermerchanttesting_la_SOURCES = \
   testing_api_cmd_config.c \
+  testing_api_cmd_abort_order.c \
   testing_api_cmd_claim_order.c \
   testing_api_cmd_get_instance.c \
   testing_api_cmd_get_instances.c \
@@ -23,6 +24,7 @@ libtalermerchanttesting_la_SOURCES = \
   testing_api_cmd_delete_instance.c \
   testing_api_cmd_delete_product.c \
   testing_api_cmd_lock_product.c \
+  testing_api_cmd_pay_order.c \
   testing_api_cmd_post_instances.c \
   testing_api_cmd_post_products.c \
   testing_api_cmd_post_orders.c \
diff --git a/src/testing/testing_api_cmd_abort_order.c 
b/src/testing/testing_api_cmd_abort_order.c
new file mode 100644
index 0000000..4444c34
--- /dev/null
+++ b/src/testing/testing_api_cmd_abort_order.c
@@ -0,0 +1,460 @@
+/*
+  This file is part of TALER
+  Copyright (C) 2014-2018, 2020 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
+  published by the Free Software Foundation; either version 3, or
+  (at your option) any later version.
+
+  TALER is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public
+  License along with TALER; see the file COPYING.  If not, see
+  <http://www.gnu.org/licenses/>
+*/
+/**
+ * @file lib/testing_api_cmd_abort_order.c
+ * @brief command to test the abort feature.
+ * @author Marcello Stanisci
+ */
+#include "platform.h"
+#include <taler/taler_exchange_service.h>
+#include <taler/taler_testing_lib.h>
+#include <taler/taler_signatures.h>
+#include "taler_merchant_service.h"
+#include "taler_merchant_testing_lib.h"
+
+#define AMOUNT_WITH_FEE 0
+
+/**
+ * State for a " abort" CMD.
+ */
+struct AbortState
+{
+
+  /**
+   * Merchant public key.
+   */
+  struct TALER_MerchantPublicKeyP merchant_pub;
+
+  /**
+   * Reference to the "pay" command to abort.
+   */
+  const char *pay_reference;
+
+  /**
+   * Merchant URL.
+   */
+  const char *merchant_url;
+
+  /**
+   * Handle to a "abort" operation.
+   */
+  struct TALER_MERCHANT_OrderAbortHandle *oah;
+
+  /**
+   * Interpreter state.
+   */
+  struct TALER_TESTING_Interpreter *is;
+
+  /**
+   * The actual abort/refund data.
+   */
+  struct TALER_MERCHANT_AbortedCoin *acs;
+
+  /**
+   * Expected HTTP response code.
+   */
+  unsigned int http_status;
+
+  /**
+   * How many refund permissions this CMD got
+   * the right for.  Roughly, there is one refund
+   * permission for one coin.
+   */
+  unsigned int acs_length;
+
+};
+
+
+/**
+ * Parse the @a coins specification and grow the @a ac
+ * array with the coins found, updating @a nac.
+ *
+ * @param[in,out] ac pointer to array of coins found
+ * @param[in,out] nac length of array at @a pc
+ * @param[in] coins string specifying coins to add to @a pc,
+ *            clobbered in the process
+ * @param is interpreter state
+ * @param amount_with_fee total amount to be paid for a contract.
+ * @param amount_without_fee to be removed, there is no
+ *        per-contract fee, only per-coin exists.
+ * @param refund_fee per-contract? per-coin?
+ * @return #GNUNET_OK on success
+ */
+static int
+build_coins (struct TALER_MERCHANT_AbortCoin **ac,
+             unsigned int *nac,
+             char *coins,
+             struct TALER_TESTING_Interpreter *is,
+             const char *amount_with_fee)
+{
+  char *token;
+
+  for (token = strtok (coins, ";");
+       NULL != token;
+       token = strtok (NULL, ";"))
+  {
+    char *ctok;
+    unsigned int ci;
+    struct TALER_MERCHANT_AbortCoin *icoin;
+
+    /* Token syntax is "LABEL[/NUMBER]" */
+    ctok = strchr (token, '/');
+    ci = 0;
+    if (NULL != ctok)
+    {
+      *ctok = '\0';
+      ctok++;
+      if (1 != sscanf (ctok,
+                       "%u",
+                       &ci))
+      {
+        GNUNET_break (0);
+        return GNUNET_SYSERR;
+      }
+    }
+    // FIXME: ci not used!?
+    {
+      const struct TALER_TESTING_Command *coin_cmd;
+      coin_cmd = TALER_TESTING_interpreter_lookup_command (is,
+                                                           token);
+      if (NULL == coin_cmd)
+      {
+        GNUNET_break (0);
+        return GNUNET_SYSERR;
+      }
+      GNUNET_array_grow (*pc,
+                         *npc,
+                         (*npc) + 1);
+      icoin = &((*pc)[(*npc) - 1]);
+
+      {
+        const struct TALER_CoinSpendPublicKeyP *coin_pub;
+
+        GNUNET_assert (GNUNET_OK ==
+                       TALER_TESTING_get_trait_coin_pub (coin_cmd,
+                                                         0,
+                                                         &coin_pub));
+        icoin->coin_pub = *coin_pub;
+      }
+      GNUNET_assert (GNUNET_OK ==
+                     TALER_TESTING_get_trait_url (coin_cmd,
+                                                  
TALER_TESTING_UT_EXCHANGE_BASE_URL,
+                                                  &icoin->exchange_url));
+      // FIXME: initialize icon->amount_with_fee!
+    }
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Callback for a "pay abort" operation.  Mainly, check HTTP
+ * response code was as expected and stores refund permissions
+ * in the state.
+ *
+ * @param cls closure.
+ * @param hr HTTP response
+ * @param merchant_pub public key of the merchant refunding the
+ *        contract.
+ * @param h_contract the contract involved in the refund.
+ * @param num_refunds length of the @a res array
+ * @param res array containing the abort confirmations
+ */
+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[])
+{
+  struct AbortState *as = cls;
+
+  as->pao = NULL;
+  if (as->http_status != hr->http_status)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Unexpected response code %u (%d) to command %s\n",
+                hr->http_status,
+                (int) hr->ec,
+                TALER_TESTING_interpreter_get_current_label (as->is));
+    TALER_TESTING_FAIL (as->is);
+  }
+  if ( (MHD_HTTP_OK == hr->http_status) &&
+       (TALER_EC_NONE == hr->ec) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "Received %u refunds\n",
+                num_refunds);
+    as->acs_length = num_aborts;
+    as->acs = GNUNET_new_array (num_aborts,
+                                struct TALER_MERCHANT_AbortedCoin);
+    memcpy (as->res,
+            res,
+            num_refunds * sizeof (struct TALER_MERCHANT_AbortedCoin));
+    as->merchant_pub = *merchant_pub;
+  }
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Successful pay-abort (HTTP status: %u)\n",
+              hr->http_status);
+  TALER_TESTING_interpreter_next (as->is);
+}
+
+
+/**
+ * Run an "abort" CMD.
+ *
+ * @param cls closure
+ * @param cmd command being run.
+ * @param is interpreter state
+ */
+static void
+abort_run (void *cls,
+           const struct TALER_TESTING_Command *cmd,
+           struct TALER_TESTING_Interpreter *is)
+{
+  struct AbortState *as = cls;
+  const struct TALER_TESTING_Command *pay_cmd;
+  const char *proposal_reference;
+  const char *coin_reference;
+  const char *amount_with_fee;
+  const struct TALER_TESTING_Command *proposal_cmd;
+  const char *order_id;
+  struct TALER_MerchantPublicKeyP merchant_pub;
+  const struct GNUNET_HashCode *h_proposal;
+  struct TALER_Amount total_amount;
+  const char *error_name;
+  unsigned int error_line;
+  struct TALER_MERCHANT_AbortCoin *abort_coins;
+  unsigned int nabort_coins;
+  char *cr;
+  struct TALER_MERCHANT_OrderAbortHandle *oah;
+
+  as->is = is;
+  pay_cmd = TALER_TESTING_interpreter_lookup_command (is,
+                                                      as->pay_reference);
+  if (NULL == pay_cmd)
+    TALER_TESTING_FAIL (is);
+  if (GNUNET_OK !=
+      TALER_TESTING_get_trait_proposal_reference (pay_cmd,
+                                                  0,
+                                                  &proposal_reference))
+    TALER_TESTING_FAIL (is);
+  if (GNUNET_OK !=
+      TALER_TESTING_get_trait_coin_reference (pay_cmd,
+                                              0,
+                                              &coin_reference))
+    TALER_TESTING_FAIL (is);
+  if (GNUNET_OK !=
+      TALER_TESTING_get_trait_string (pay_cmd,
+                                      AMOUNT_WITH_FEE,
+                                      &amount_with_fee))
+    TALER_TESTING_FAIL (is);
+  proposal_cmd = TALER_TESTING_interpreter_lookup_command (is,
+                                                           proposal_reference);
+
+  if (NULL == proposal_cmd)
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+
+  {
+    const json_t *contract_terms;
+
+    if (GNUNET_OK !=
+        TALER_TESTING_get_trait_contract_terms (proposal_cmd,
+                                                0,
+                                                &contract_terms))
+    {
+      GNUNET_break (0);
+      return NULL;
+    }
+    {
+      /* Get information that needs to be put verbatim in the
+       * deposit permission */
+      struct GNUNET_JSON_Specification spec[] = {
+        GNUNET_JSON_spec_string ("order_id",
+                                 &order_id),
+        GNUNET_JSON_spec_fixed_auto ("merchant_pub",
+                                     &as->merchant_pub),
+        TALER_JSON_spec_amount ("amount",
+                                &total_amount),
+        GNUNET_JSON_spec_end ()
+      };
+
+      if (GNUNET_OK !=
+          GNUNET_JSON_parse (contract_terms,
+                             spec,
+                             &error_name,
+                             &error_line))
+      {
+        char *js;
+
+        js = json_dumps (contract_terms,
+                         JSON_INDENT (1));
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                    "Parser failed on %s:%u for input `%s'\n",
+                    error_name,
+                    error_line,
+                    js);
+        free (js);
+        GNUNET_break_op (0);
+        return NULL;
+      }
+    }
+  }
+
+  cr = GNUNET_strdup (coin_reference);
+  pay_coins = NULL;
+  npay_coins = 0;
+  if (GNUNET_OK !=
+      build_coins (&abort_coins,
+                   &nabort_coins,
+                   cr,
+                   is,
+                   amount_with_fee))
+  {
+    GNUNET_array_grow (pay_coins,
+                       npay_coins,
+                       0);
+    GNUNET_free (cr);
+    GNUNET_break (0);
+    return NULL;
+  }
+  GNUNET_free (cr);
+
+  if (GNUNET_OK !=
+      TALER_TESTING_get_trait_h_contract_terms (proposal_cmd,
+                                                0,
+                                                &h_proposal))
+  {
+    GNUNET_break (0);
+    return NULL;
+  }
+  as->oah = TALER_MERCHANT_order_abort (is->ctx,
+                                        merchant_url,
+                                        order_id,
+                                        &as->merchant_pub,
+                                        h_proposal,
+                                        nabort_coins,
+                                        abort_coins,
+                                        api_cb,
+                                        api_cb_cls);
+  GNUNET_array_grow (pay_coins,
+                     npay_coins,
+                     0);
+  if (NULL == as->pao)
+    TALER_TESTING_FAIL (is);
+}
+
+
+/**
+ * Free a "pay abort" CMD, and cancel it if need be.
+ *
+ * @param cls closure.
+ * @param cmd command currently being freed.
+ */
+static void
+abort_cleanup (void *cls,
+               const struct TALER_TESTING_Command *cmd)
+{
+  struct AbortState *as = cls;
+
+  if (NULL != as->pao)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                "Command `%s' did not complete.\n",
+                TALER_TESTING_interpreter_get_current_label (
+                  as->is));
+    TALER_MERCHANT_pay_cancel (as->pao);
+  }
+  GNUNET_free_non_null (as->res);
+  GNUNET_free (as);
+}
+
+
+/**
+ * Offer internal data useful to other commands.
+ *
+ * @param cls closure
+ * @param ret[out] result (could be anything)
+ * @param trait name of the trait
+ * @param index index number of the object to extract.
+ * @return #GNUNET_OK on success
+ */
+static int
+abort_traits (void *cls,
+              const void **ret,
+              const char *trait,
+              unsigned int index)
+{
+  struct AbortState *as = cls;
+  struct TALER_TESTING_Trait traits[] = {
+    TALER_TESTING_make_trait_merchant_pub (0,
+                                           &as->merchant_pub),
+    TALER_TESTING_make_trait_refund_entry (0,
+                                           as->acs),
+    TALER_TESTING_make_trait_uint (0,
+                                   &as->num_refunds),
+    TALER_TESTING_trait_end ()
+  };
+
+  return TALER_TESTING_get_trait (traits,
+                                  ret,
+                                  trait,
+                                  index);
+}
+
+
+/**
+ * Make an "abort" test command.
+ *
+ * @param label command label
+ * @param merchant_url merchant base URL
+ * @param pay_reference reference to the payment to abort
+ * @param http_status expected HTTP response code
+ * @return the command
+ */
+struct TALER_TESTING_Command
+TALER_TESTING_cmd_abort (const char *label,
+                         const char *merchant_url,
+                         const char *pay_reference,
+                         unsigned int http_status)
+{
+  struct AbortState *as;
+
+  as = GNUNET_new (struct AbortState);
+  as->http_status = http_status;
+  as->pay_reference = pay_reference;
+  as->merchant_url = merchant_url;
+  {
+    struct TALER_TESTING_Command cmd = {
+      .cls = as,
+      .label = label,
+      .run = &abort_run,
+      .cleanup = &abort_cleanup,
+      .traits = &abort_traits
+    };
+
+    return cmd;
+  }
+}
+
+
+/* end of testing_api_cmd_abort_order.c */
diff --git a/src/testing/testing_api_cmd_pay_abort.c 
b/src/testing/testing_api_cmd_pay_abort.c
deleted file mode 100644
index 5911dd1..0000000
--- a/src/testing/testing_api_cmd_pay_abort.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
-  This file is part of TALER
-  Copyright (C) 2014-2018, 2020 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
-  published by the Free Software Foundation; either version 3, or
-  (at your option) any later version.
-
-  TALER is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public
-  License along with TALER; see the file COPYING.  If not, see
-  <http://www.gnu.org/licenses/>
-*/
-
-/**
- * @file lib/testing_api_cmd_pay_abort.c
- * @brief command to test the /pay abort feature.
- * @author Marcello Stanisci
- */
-
-#include "platform.h"
-#include <taler/taler_exchange_service.h>
-#include <taler/taler_testing_lib.h>
-#include <taler/taler_signatures.h>
-#include "taler_merchant_service.h"
-#include "taler_merchant_testing_lib.h"
-
-#define AMOUNT_WITH_FEE 0
-#define AMOUNT_WITHOUT_FEE 1
-#define REFUND_FEE 2
-
-/**
- * State for a "pay abort" CMD.
- */
-struct PayAbortState
-{
-
-  /**
-   * Expected HTTP response code.
-   */
-  unsigned int http_status;
-
-  /**
-   * Reference to the "pay" command to abort.
-   */
-  const char *pay_reference;
-
-  /**
-   * Merchant URL.
-   */
-  const char *merchant_url;
-
-  /**
-   * Handle to a "pay abort" operation.
-   */
-  struct TALER_MERCHANT_Pay *pao;
-
-  /**
-   * Interpreter state.
-   */
-  struct TALER_TESTING_Interpreter *is;
-
-  /**
-   * How many refund permissions this CMD got
-   * the right for.  Roughly, there is one refund
-   * permission for one coin.
-   */
-  unsigned int num_refunds;
-
-  /**
-   * The actual refund data.
-   */
-  struct TALER_MERCHANT_RefundEntry *res;
-
-  /**
-   * The contract whose payment is to be aborted.
-   */
-  struct GNUNET_HashCode h_contract;
-
-  /**
-   * Merchant public key.
-   */
-  struct TALER_MerchantPublicKeyP merchant_pub;
-};
-
-
-/**
- * Parse the @a coins specification and grow the @a pc
- * array with the coins found, updating @a npc.
- *
- * @param[in,out] pc pointer to array of coins found
- * @param[in,out] npc length of array at @a pc
- * @param[in] coins string specifying coins to add to @a pc,
- *            clobbered in the process
- * @param is interpreter state
- * @param amount_with_fee total amount to be paid for a contract.
- * @param amount_without_fee to be removed, there is no
- *        per-contract fee, only per-coin exists.
- * @param refund_fee per-contract? per-coin?
- * @return #GNUNET_OK on success
- */
-static int
-build_coins (struct TALER_MERCHANT_PayCoin **pc,
-             unsigned int *npc,
-             char *coins,
-             struct TALER_TESTING_Interpreter *is,
-             const char *amount_with_fee,
-             const char *amount_without_fee,
-             const char *refund_fee)
-{
-  char *token;
-
-  for (token = strtok (coins, ";");
-       NULL != token;
-       token = strtok (NULL, ";"))
-  {
-    const struct TALER_TESTING_Command *coin_cmd;
-    char *ctok;
-    unsigned int ci;
-    struct TALER_MERCHANT_PayCoin *icoin;
-    const struct TALER_EXCHANGE_DenomPublicKey *dpk;
-
-    /* Token syntax is "LABEL[/NUMBER]" */
-    ctok = strchr (token, '/');
-    ci = 0;
-    if (NULL != ctok)
-    {
-      *ctok = '\0';
-      ctok++;
-      if (1 != sscanf (ctok,
-                       "%u",
-                       &ci))
-      {
-        GNUNET_break (0);
-        return GNUNET_SYSERR;
-      }
-    }
-
-    coin_cmd = TALER_TESTING_interpreter_lookup_command
-                 (is, token);
-
-    if (NULL == coin_cmd)
-    {
-      GNUNET_break (0);
-      return GNUNET_SYSERR;
-    }
-
-    GNUNET_array_grow (*pc,
-                       *npc,
-                       (*npc) + 1);
-
-    icoin = &((*pc)[(*npc) - 1]);
-
-    {
-      const struct TALER_CoinSpendPrivateKeyP *coin_priv;
-      const struct TALER_DenominationSignature *denom_sig;
-      const struct TALER_Amount *denom_value;
-      const struct TALER_EXCHANGE_DenomPublicKey *denom_pub;
-
-      GNUNET_assert
-        (GNUNET_OK == TALER_TESTING_get_trait_coin_priv
-          (coin_cmd, 0, &coin_priv));
-
-      GNUNET_assert
-        (GNUNET_OK == TALER_TESTING_get_trait_denom_pub
-          (coin_cmd, 0, &denom_pub));
-
-      GNUNET_assert
-        (GNUNET_OK == TALER_TESTING_get_trait_denom_sig
-          (coin_cmd, 0, &denom_sig));
-
-      GNUNET_assert
-        (GNUNET_OK == TALER_TESTING_get_trait_amount_obj
-          (coin_cmd, 0, &denom_value));
-
-      icoin->coin_priv = *coin_priv;
-      icoin->denom_pub = denom_pub->key;
-      icoin->denom_sig = *denom_sig;
-      icoin->denom_value = *denom_value;
-      icoin->amount_with_fee = *denom_value;
-    }
-    GNUNET_assert (NULL != (dpk =
-                              TALER_TESTING_find_pk (is->keys,
-                                                     &icoin->denom_value)));
-
-    GNUNET_assert (0 <=
-                   TALER_amount_subtract (&icoin->amount_without_fee,
-                                          &icoin->denom_value,
-                                          &dpk->fee_deposit));
-    GNUNET_assert (GNUNET_OK ==
-                   TALER_TESTING_get_trait_url (coin_cmd,
-                                                
TALER_TESTING_UT_EXCHANGE_BASE_URL,
-                                                &icoin->exchange_url));
-    GNUNET_assert (GNUNET_OK ==
-                   TALER_string_to_amount (refund_fee,
-                                           &icoin->refund_fee));
-  }
-
-  return GNUNET_OK;
-}
-
-
-/**
- * Callback for a "pay abort" operation.  Mainly, check HTTP
- * response code was as expected and stores refund permissions
- * in the state.
- *
- * @param cls closure.
- * @param hr HTTP response
- * @param merchant_pub public key of the merchant refunding the
- *        contract.
- * @param h_contract the contract involved in the refund.
- * @param num_refunds how many refund permissions have been
- *        issued.
- * @param res array containing the refund permissions.
- */
-static void
-pay_abort_cb (void *cls,
-              const struct TALER_MERCHANT_HttpResponse *hr,
-              const struct TALER_MerchantPublicKeyP *merchant_pub,
-              const struct GNUNET_HashCode *h_contract,
-              unsigned int num_refunds,
-              const struct TALER_MERCHANT_RefundEntry *res)
-{
-  struct PayAbortState *pas = cls;
-
-  pas->pao = NULL;
-  if (pas->http_status != hr->http_status)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Unexpected response code %u (%d) to command %s\n",
-                hr->http_status,
-                (int) hr->ec,
-                TALER_TESTING_interpreter_get_current_label (pas->is));
-    TALER_TESTING_FAIL (pas->is);
-  }
-  if ( (MHD_HTTP_OK == hr->http_status) &&
-       (TALER_EC_NONE == hr->ec) )
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-                "Received %u refunds\n",
-                num_refunds);
-    pas->num_refunds = num_refunds;
-    pas->res = GNUNET_new_array (num_refunds,
-                                 struct TALER_MERCHANT_RefundEntry);
-    memcpy (pas->res,
-            res,
-            num_refunds * sizeof (struct TALER_MERCHANT_RefundEntry));
-    pas->h_contract = *h_contract;
-    pas->merchant_pub = *merchant_pub;
-  }
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Successful pay-abort (HTTP status: %u)\n",
-              hr->http_status);
-  TALER_TESTING_interpreter_next (pas->is);
-}
-
-
-/**
- * Function used by both the "abort" operation.
- * It prepares data and sends the "pay-abort" request to the
- * backend.
- *
- * @param merchant_url base URL of the merchant serving the
- *        request.
- * @param coin_reference reference to the CMD(s) that offer
- *        "coins" traits.  It is possible to give multiple
- *        references by using semicolons to separate them.
- * @param proposal_refere reference to a "proposal" CMD.
- * @param is interpreter state.
- * @param amount_with_fee amount to be paid, including deposit
- *        fee.
- * @param amount_without_fee amount to be paid, without deposit
- *        fee.
- * @param refund_fee refund fee.
- * @param api_func "lib" function that will be called to either
- *        issue a "pay" or "abort" request.
- * @param api_cb callback for @a api_func.
- * @param api_cb_cls closure for @a api_cb
- * @return handle to the operation, NULL if errors occur.
- */
-static struct TALER_MERCHANT_Pay *
-_pay_abort_run (const char *merchant_url,
-                const char *coin_reference,
-                const char *proposal_reference,
-                struct TALER_TESTING_Interpreter *is,
-                const char *amount_with_fee,
-                const char *amount_without_fee,
-                const char *refund_fee,
-                TALER_MERCHANT_PayRefundCallback api_cb,
-                void *api_cb_cls)
-{
-  const struct TALER_TESTING_Command *proposal_cmd;
-  const json_t *contract_terms;
-  const char *order_id;
-  struct GNUNET_TIME_Absolute refund_deadline;
-  struct GNUNET_TIME_Absolute pay_deadline;
-  struct GNUNET_TIME_Absolute timestamp;
-  struct TALER_MerchantPublicKeyP merchant_pub;
-  struct GNUNET_HashCode h_wire;
-  const struct GNUNET_HashCode *h_proposal;
-  struct TALER_Amount total_amount;
-  struct TALER_Amount max_fee;
-  const char *error_name;
-  unsigned int error_line;
-  struct TALER_MERCHANT_PayCoin *pay_coins;
-  unsigned int npay_coins;
-  char *cr;
-  struct TALER_MerchantSignatureP *merchant_sig;
-  struct TALER_MERCHANT_Pay *ret;
-
-  proposal_cmd = TALER_TESTING_interpreter_lookup_command (is,
-                                                           proposal_reference);
-
-  if (NULL == proposal_cmd)
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-
-  if (GNUNET_OK !=
-      TALER_TESTING_get_trait_contract_terms (proposal_cmd,
-                                              0,
-                                              &contract_terms))
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-  {
-    /* Get information that needs to be put verbatim in the
-     * deposit permission */
-    struct GNUNET_JSON_Specification spec[] = {
-      GNUNET_JSON_spec_string ("order_id",
-                               &order_id),
-      GNUNET_JSON_spec_absolute_time ("refund_deadline",
-                                      &refund_deadline),
-      GNUNET_JSON_spec_absolute_time ("pay_deadline",
-                                      &pay_deadline),
-      GNUNET_JSON_spec_absolute_time ("timestamp",
-                                      &timestamp),
-      GNUNET_JSON_spec_fixed_auto ("merchant_pub",
-                                   &merchant_pub),
-      GNUNET_JSON_spec_fixed_auto ("h_wire",
-                                   &h_wire),
-      TALER_JSON_spec_amount ("amount",
-                              &total_amount),
-      TALER_JSON_spec_amount ("max_fee",
-                              &max_fee),
-      GNUNET_JSON_spec_end ()
-    };
-
-    if (GNUNET_OK !=
-        GNUNET_JSON_parse (contract_terms,
-                           spec,
-                           &error_name,
-                           &error_line))
-    {
-      char *js;
-
-      js = json_dumps (contract_terms,
-                       JSON_INDENT (1));
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Parser failed on %s:%u for input `%s'\n",
-                  error_name,
-                  error_line,
-                  js);
-      free (js);
-      GNUNET_break_op (0);
-      return NULL;
-    }
-  }
-
-  cr = GNUNET_strdup (coin_reference);
-  pay_coins = NULL;
-  npay_coins = 0;
-  if (GNUNET_OK !=
-      build_coins (&pay_coins,
-                   &npay_coins,
-                   cr,
-                   is,
-                   amount_with_fee,
-                   amount_without_fee,
-                   refund_fee))
-  {
-    GNUNET_array_grow (pay_coins,
-                       npay_coins,
-                       0);
-    GNUNET_free (cr);
-    GNUNET_break (0);
-    return NULL;
-  }
-
-  GNUNET_free (cr);
-  if (GNUNET_OK !=
-      TALER_TESTING_get_trait_merchant_sig (proposal_cmd,
-                                            0,
-                                            &merchant_sig))
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-  if (GNUNET_OK !=
-      TALER_TESTING_get_trait_h_contract_terms (proposal_cmd,
-                                                0,
-                                                &h_proposal))
-  {
-    GNUNET_break (0);
-    return NULL;
-  }
-  ret = TALER_MERCHANT_pay_abort (is->ctx,
-                                  merchant_url,
-                                  h_proposal,
-                                  &total_amount,
-                                  &max_fee,
-                                  &merchant_pub,
-                                  merchant_sig,
-                                  timestamp,
-                                  refund_deadline,
-                                  pay_deadline,
-                                  &h_wire,
-                                  order_id,
-                                  npay_coins,
-                                  pay_coins,
-                                  api_cb,
-                                  api_cb_cls);
-  GNUNET_array_grow (pay_coins,
-                     npay_coins,
-                     0);
-  return ret;
-}
-
-
-/**
- * Free a "pay abort" CMD, and cancel it if need be.
- *
- * @param cls closure.
- * @param cmd command currently being freed.
- */
-static void
-pay_abort_cleanup (void *cls,
-                   const struct TALER_TESTING_Command *cmd)
-{
-  struct PayAbortState *pas = cls;
-
-  if (NULL != pas->pao)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                "Command `%s' did not complete.\n",
-                TALER_TESTING_interpreter_get_current_label (
-                  pas->is));
-    TALER_MERCHANT_pay_cancel (pas->pao);
-  }
-  GNUNET_free_non_null (pas->res);
-  GNUNET_free (pas);
-}
-
-
-/**
- * Run a "pay abort" CMD.
- *
- * @param cls closure
- * @param cmd command being run.
- * @param is interpreter state
- */
-static void
-pay_abort_run (void *cls,
-               const struct TALER_TESTING_Command *cmd,
-               struct TALER_TESTING_Interpreter *is)
-{
-
-  struct PayAbortState *pas = cls;
-  const struct TALER_TESTING_Command *pay_cmd;
-
-  const char *proposal_reference;
-  const char *coin_reference;
-  const char *amount_with_fee;
-  const char *amount_without_fee;
-  const char *refund_fee;
-
-  pas->is = is;
-  pay_cmd = TALER_TESTING_interpreter_lookup_command
-              (is, pas->pay_reference);
-  if (NULL == pay_cmd)
-    TALER_TESTING_FAIL (is);
-
-  if (GNUNET_OK != TALER_TESTING_get_trait_proposal_reference
-        (pay_cmd, 0, &proposal_reference))
-    TALER_TESTING_FAIL (is);
-
-  if (GNUNET_OK != TALER_TESTING_get_trait_coin_reference
-        (pay_cmd, 0, &coin_reference))
-    TALER_TESTING_FAIL (is);
-
-  if (GNUNET_OK != TALER_TESTING_get_trait_string
-        (pay_cmd, AMOUNT_WITH_FEE, &amount_with_fee))
-    TALER_TESTING_FAIL (is);
-
-  if (GNUNET_OK != TALER_TESTING_get_trait_string
-        (pay_cmd, AMOUNT_WITHOUT_FEE, &amount_without_fee))
-    TALER_TESTING_FAIL (is);
-
-  if (GNUNET_OK != TALER_TESTING_get_trait_string
-        (pay_cmd, REFUND_FEE, &refund_fee))
-    TALER_TESTING_FAIL (is);
-
-  if (NULL == (pas->pao = _pay_abort_run (pas->merchant_url,
-                                          coin_reference,
-                                          proposal_reference,
-                                          is,
-                                          amount_with_fee,
-                                          amount_without_fee,
-                                          refund_fee,
-                                          &pay_abort_cb,
-                                          pas)))
-    TALER_TESTING_FAIL (is);
-}
-
-
-/**
- * Offer internal data useful to other commands.
- *
- * @param cls closure
- * @param ret[out] result (could be anything)
- * @param trait name of the trait
- * @param index index number of the object to extract.
- * @return #GNUNET_OK on success
- */
-static int
-pay_abort_traits (void *cls,
-                  const void **ret,
-                  const char *trait,
-                  unsigned int index)
-{
-  struct PayAbortState *pas = cls;
-  struct TALER_TESTING_Trait traits[] = {
-    TALER_TESTING_make_trait_merchant_pub
-      (0, &pas->merchant_pub),
-    TALER_TESTING_make_trait_h_contract_terms
-      (0, &pas->h_contract),
-    TALER_TESTING_make_trait_refund_entry
-      (0, pas->res),
-    TALER_TESTING_make_trait_uint (0, &pas->num_refunds),
-    TALER_TESTING_trait_end ()
-  };
-
-  return TALER_TESTING_get_trait (traits,
-                                  ret,
-                                  trait,
-                                  index);
-}
-
-
-/**
- * Make a "pay abort" test command.
- *
- * @param label command label
- * @param merchant_url merchant base URL
- * @param pay_reference reference to the payment to abort
- * @param http_status expected HTTP response code
- *
- * @return the command
- */
-struct TALER_TESTING_Command
-TALER_TESTING_cmd_pay_abort (const char *label,
-                             const char *merchant_url,
-                             const char *pay_reference,
-                             unsigned int http_status)
-{
-  struct PayAbortState *pas;
-
-  pas = GNUNET_new (struct PayAbortState);
-  pas->http_status = http_status;
-  pas->pay_reference = pay_reference;
-  pas->merchant_url = merchant_url;
-  {
-    struct TALER_TESTING_Command cmd = {
-      .cls = pas,
-      .label = label,
-      .run = &pay_abort_run,
-      .cleanup = &pay_abort_cleanup,
-      .traits = &pay_abort_traits
-    };
-
-    return cmd;
-  }
-}
-
-
-/* end of testing_api_cmd_pay_abort.c */
diff --git a/src/testing/testing_api_cmd_pay.c 
b/src/testing/testing_api_cmd_pay_order.c
similarity index 100%
rename from src/testing/testing_api_cmd_pay.c
rename to src/testing/testing_api_cmd_pay_order.c

-- 
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]