merchant

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

test_merchant_api.c (169311B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2014-2023 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify
      6   it under the terms of the GNU General Public License as
      7   published by the Free Software Foundation; either version 3, or
      8   (at your option) any later version.
      9 
     10   TALER is distributed in the hope that it will be useful, but
     11   WITHOUT ANY WARRANTY; without even the implied warranty of
     12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13   GNU General Public License for more details.
     14 
     15   You should have received a copy of the GNU General Public
     16   License along with TALER; see the file COPYING.  If not, see
     17   <http://www.gnu.org/licenses/>
     18 */
     19 /**
     20  * @file src/testing/test_merchant_api.c
     21  * @brief testcase to test exchange's HTTP API interface
     22  * @author Sree Harsha Totakura <sreeharsha@totakura.in>
     23  * @author Christian Grothoff
     24  * @author Marcello Stanisci
     25  */
     26 #include "platform.h"
     27 #include <gnunet/gnunet_time_lib.h>
     28 #include <taler/taler_util.h>
     29 #include <taler/taler_signatures.h>
     30 #include <taler/taler_exchange_service.h>
     31 #include <taler/taler_json_lib.h>
     32 #include <gnunet/gnunet_util_lib.h>
     33 #include <gnunet/gnunet_testing_lib.h>
     34 #include <microhttpd.h>
     35 #include <taler/taler_bank_service.h>
     36 #include <taler/taler_fakebank_lib.h>
     37 #include <taler/taler_testing_lib.h>
     38 #include <taler/taler_error_codes.h>
     39 #include "taler/taler_merchant_util.h"
     40 #include "taler/taler_merchant_testing_lib.h"
     41 #include <donau/donau_testing_lib.h>
     42 
     43 
     44 /**
     45  * The 'poll-orders-conclude-1' and other 'conclude'
     46  * commands should NOT wait for this timeout!
     47  */
     48 #define POLL_ORDER_TIMEOUT \
     49         GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
     50 
     51 /**
     52  * The 'poll-orders-conclude-1x' and other 'conclude'
     53  * commands that should (!) wait for this timeout! Hence,
     54  * here we use a short value!
     55  */
     56 #define POLL_ORDER_SHORT_TIMEOUT \
     57         GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2)
     58 
     59 /**
     60  * Configuration file we use.  One (big) configuration is used
     61  * for the various components for this test.
     62  */
     63 static char *config_file;
     64 
     65 /**
     66  * Exchange base URL.  Could also be taken from config.
     67  */
     68 #define EXCHANGE_URL "http://localhost:8081/"
     69 
     70 /**
     71  * Payto URI of the customer (payer).
     72  */
     73 static struct TALER_FullPayto payer_payto;
     74 
     75 /**
     76  * Payto URI of the exchange (escrow account).
     77  */
     78 static struct TALER_FullPayto exchange_payto;
     79 
     80 /**
     81  * Payto URI of the merchant (receiver).
     82  */
     83 static struct TALER_FullPayto merchant_payto;
     84 
     85 /**
     86  * Credentials for the test.
     87  */
     88 static struct TALER_TESTING_Credentials cred;
     89 
     90 /**
     91  * Merchant base URL.
     92  */
     93 static const char *merchant_url;
     94 
     95 /**
     96  * Merchant instance "i1a" base URL.
     97  */
     98 static char *merchant_url_i1a;
     99 
    100 /**
    101  * Account number of the exchange at the bank.
    102  */
    103 #define EXCHANGE_ACCOUNT_NAME "2"
    104 
    105 /**
    106  * Account number of some user.
    107  */
    108 #define USER_ACCOUNT_NAME "62"
    109 
    110 /**
    111  * Account number of some other user.
    112  */
    113 #define USER_ACCOUNT_NAME2 "63"
    114 
    115 /**
    116  * Account number used by the merchant
    117  */
    118 #define MERCHANT_ACCOUNT_NAME "3"
    119 
    120 static const char *order_1_transfers[] = {
    121   "post-transfer-1",
    122   NULL
    123 };
    124 
    125 static const char *order_1_forgets_1[] = {
    126   "forget-1",
    127   NULL
    128 };
    129 
    130 static const char *order_1_forgets_2[] = {
    131   "forget-1",
    132   "forget-order-array-elem",
    133   NULL
    134 };
    135 
    136 static const char *order_1_forgets_3[] = {
    137   "forget-1",
    138   "forget-order-array-elem",
    139   "forget-order-array-wc",
    140   NULL
    141 };
    142 
    143 static const struct TALER_TESTING_ProductUnitExpectations
    144   expect_unicorn_defaults = {
    145   .have_unit_allow_fraction = true,
    146   .unit_allow_fraction = true,
    147   .have_unit_precision_level = true,
    148   .unit_precision_level = 1
    149 };
    150 
    151 static const struct TALER_TESTING_ProductUnitExpectations
    152   expect_unicorn_patched = {
    153   .have_unit_allow_fraction = true,
    154   .unit_allow_fraction = false,
    155   .have_unit_precision_level = true,
    156   .unit_precision_level = 0
    157 };
    158 
    159 /**
    160  * Build an array of selected product IDs.
    161  *
    162  * @param first first product id
    163  * @param second second product id or NULL
    164  * @return JSON array of product ids
    165  */
    166 static json_t *
    167 make_selected_products (const char *first,
    168                         const char *second)
    169 {
    170   json_t *arr;
    171 
    172   arr = json_array ();
    173   GNUNET_assert (NULL != arr);
    174   if (NULL != first)
    175     GNUNET_assert (0 ==
    176                    json_array_append_new (arr,
    177                                           json_string (first)));
    178   if (NULL != second)
    179     GNUNET_assert (0 ==
    180                    json_array_append_new (arr,
    181                                           json_string (second)));
    182   return arr;
    183 }
    184 
    185 
    186 /**
    187  * Build an array of selected category IDs.
    188  *
    189  * @param first first category id
    190  * @param second second category id or 0
    191  * @return JSON array of category ids
    192  */
    193 static json_t *
    194 make_selected_categories (uint64_t first,
    195                           uint64_t second)
    196 {
    197   json_t *arr;
    198 
    199   arr = json_array ();
    200   GNUNET_assert (NULL != arr);
    201   if (0 != first)
    202     GNUNET_assert (0 ==
    203                    json_array_append_new (arr,
    204                                           json_integer (first)));
    205   if (0 != second)
    206     GNUNET_assert (0 ==
    207                    json_array_append_new (arr,
    208                                           json_integer (second)));
    209   return arr;
    210 }
    211 
    212 
    213 /**
    214  * Build an inventory selection array.
    215  *
    216  * @param first_id first product id
    217  * @param first_qty first quantity
    218  * @param second_id second product id or NULL
    219  * @param second_qty second quantity or NULL
    220  * @return JSON array of inventory selections
    221  */
    222 static json_t *
    223 make_inventory_selection (const char *first_id,
    224                           const char *first_qty,
    225                           const char *second_id,
    226                           const char *second_qty)
    227 {
    228   json_t *arr;
    229 
    230   arr = json_array ();
    231   GNUNET_assert (NULL != arr);
    232   if (NULL != first_id)
    233     GNUNET_assert (0 ==
    234                    json_array_append_new (
    235                      arr,
    236                      GNUNET_JSON_PACK (
    237                        GNUNET_JSON_pack_string ("product_id",
    238                                                 first_id),
    239                        GNUNET_JSON_pack_string ("quantity",
    240                                                 first_qty))));
    241   if (NULL != second_id)
    242     GNUNET_assert (0 ==
    243                    json_array_append_new (
    244                      arr,
    245                      GNUNET_JSON_PACK (
    246                        GNUNET_JSON_pack_string ("product_id",
    247                                                 second_id),
    248                        GNUNET_JSON_pack_string ("quantity",
    249                                                 second_qty))));
    250   return arr;
    251 }
    252 
    253 
    254 /**
    255  * Execute the taler-merchant-webhook command with
    256  * our configuration file.
    257  *
    258  * @param label label to use for the command.
    259  */
    260 static struct TALER_TESTING_Command
    261 cmd_webhook (const char *label)
    262 {
    263   return TALER_TESTING_cmd_webhook (label, config_file);
    264 }
    265 
    266 
    267 /**
    268  * Execute the taler-exchange-wirewatch command with
    269  * our configuration file.
    270  *
    271  * @param label label to use for the command.
    272  */
    273 static struct TALER_TESTING_Command
    274 cmd_exec_wirewatch (const char *label)
    275 {
    276   return TALER_TESTING_cmd_exec_wirewatch (label,
    277                                            config_file);
    278 }
    279 
    280 
    281 /**
    282  * Execute the taler-exchange-aggregator, closer and transfer commands with
    283  * our configuration file.
    284  *
    285  * @param label label to use for the command.
    286  */
    287 #define CMD_EXEC_AGGREGATOR(label) \
    288         TALER_TESTING_cmd_exec_aggregator (label "-aggregator", config_file), \
    289         TALER_TESTING_cmd_exec_transfer (label "-transfer", config_file)
    290 
    291 
    292 /**
    293  * Run wire transfer of funds from some user's account to the
    294  * exchange.
    295  *
    296  * @param label label to use for the command.
    297  * @param amount amount to transfer, i.e. "EUR:1"
    298  * @param url exchange_url
    299  */
    300 static struct TALER_TESTING_Command
    301 cmd_transfer_to_exchange (const char *label,
    302                           const char *amount)
    303 {
    304   return TALER_TESTING_cmd_admin_add_incoming (label,
    305                                                amount,
    306                                                &cred.ba,
    307                                                payer_payto);
    308 }
    309 
    310 
    311 /**
    312  * Main function that will tell the interpreter what commands to
    313  * run.
    314  *
    315  * @param cls closure
    316  */
    317 static void
    318 run (void *cls,
    319      struct TALER_TESTING_Interpreter *is)
    320 {
    321   struct TALER_TESTING_Command get_private_order_id[] = {
    322     TALER_TESTING_cmd_merchant_post_instances (
    323       "instance-create-admin",
    324       merchant_url,
    325       "admin",
    326       MHD_HTTP_NO_CONTENT),
    327     TALER_TESTING_cmd_merchant_kyc_get (
    328       "instance-create-kyc-no-accounts",
    329       merchant_url,
    330       NULL,
    331       NULL,
    332       EXCHANGE_URL,
    333       TALER_EXCHANGE_KLPT_NONE,
    334       MHD_HTTP_NO_CONTENT,
    335       false),
    336     TALER_TESTING_cmd_merchant_post_account (
    337       "instance-create-default-account",
    338       merchant_url,
    339       merchant_payto,
    340       NULL, NULL,
    341       MHD_HTTP_OK),
    342     TALER_TESTING_cmd_merchant_kyc_get (
    343       "instance-create-kyc-0",
    344       merchant_url,
    345       NULL,
    346       NULL,
    347       EXCHANGE_URL,
    348       TALER_EXCHANGE_KLPT_NONE,
    349       MHD_HTTP_OK,
    350       true),
    351     TALER_TESTING_cmd_merchant_post_orders_no_claim (
    352       "create-proposal-bad-currency",
    353       merchant_url,
    354       MHD_HTTP_CONFLICT,
    355       "4",
    356       GNUNET_TIME_UNIT_ZERO_TS,
    357       GNUNET_TIME_UNIT_FOREVER_TS,
    358       "XXX:5.0"),
    359     TALER_TESTING_cmd_merchant_post_orders_no_claim (
    360       "create-proposal-4",
    361       merchant_url,
    362       MHD_HTTP_OK,
    363       "4",
    364       GNUNET_TIME_UNIT_ZERO_TS,
    365       GNUNET_TIME_UNIT_FOREVER_TS,
    366       "EUR:5.0"),
    367     TALER_TESTING_cmd_merchant_get_order (
    368       "get-order-4",
    369       merchant_url,
    370       "create-proposal-4",
    371       TALER_MERCHANT_OSC_UNPAID,
    372       false,
    373       MHD_HTTP_OK,
    374       NULL),
    375     TALER_TESTING_cmd_merchant_delete_order (
    376       "delete-order-4",
    377       merchant_url,
    378       "4",
    379       MHD_HTTP_NO_CONTENT),
    380     TALER_TESTING_cmd_merchant_purge_instance (
    381       "purge-admin",
    382       merchant_url,
    383       "admin",
    384       MHD_HTTP_NO_CONTENT),
    385     TALER_TESTING_cmd_end ()
    386   };
    387 
    388   struct TALER_TESTING_Command pay[] = {
    389     /**
    390      * Move money to the exchange's bank account.
    391      */
    392     cmd_transfer_to_exchange ("create-reserve-1",
    393                               "EUR:10.02"),
    394     /**
    395      * Make a reserve exist, according to the previous transfer.
    396      */
    397     cmd_exec_wirewatch ("wirewatch-1"),
    398     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-2",
    399                                                  "EUR:10.02",
    400                                                  payer_payto,
    401                                                  exchange_payto,
    402                                                  "create-reserve-1"),
    403     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1",
    404                                        "create-reserve-1",
    405                                        "EUR:5",
    406                                        0,
    407                                        MHD_HTTP_OK),
    408     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
    409                                        "create-reserve-1",
    410                                        "EUR:5",
    411                                        0,
    412                                        MHD_HTTP_OK),
    413     TALER_TESTING_cmd_merchant_get_orders ("get-orders-empty",
    414                                            merchant_url,
    415                                            MHD_HTTP_OK,
    416                                            NULL),
    417     /**
    418      * Check the reserve is depleted.
    419      */
    420     TALER_TESTING_cmd_status ("withdraw-status-1",
    421                               "create-reserve-1",
    422                               "EUR:0",
    423                               MHD_HTTP_OK),
    424     TALER_TESTING_cmd_merchant_delete_order ("delete-order-nx",
    425                                              merchant_url,
    426                                              "1",
    427                                              MHD_HTTP_NOT_FOUND),
    428     TALER_TESTING_cmd_poll_orders_start ("poll-orders-1-start",
    429                                          merchant_url,
    430                                          POLL_ORDER_TIMEOUT),
    431     TALER_TESTING_cmd_merchant_claim_order ("claim-order-nx",
    432                                             merchant_url,
    433                                             MHD_HTTP_NOT_FOUND,
    434                                             NULL,
    435                                             "1"),
    436     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-1",
    437                                              cred.cfg,
    438                                              merchant_url,
    439                                              MHD_HTTP_OK,
    440                                              "1",
    441                                              GNUNET_TIME_UNIT_ZERO_TS,
    442                                              GNUNET_TIME_UNIT_FOREVER_TS,
    443                                              true,
    444                                              "EUR:5.0",
    445                                              "x-taler-bank",
    446                                              "",
    447                                              "",
    448                                              NULL),
    449     TALER_TESTING_cmd_merchant_post_webhooks ("post-webhooks-pay-w1",
    450                                               merchant_url,
    451                                               "webhook-pay-1",
    452                                               "pay",
    453                                               MHD_HTTP_NO_CONTENT),
    454     TALER_TESTING_cmd_merchant_post_webhooks2 ("post-webhooks-settled-w1",
    455                                                merchant_url,
    456                                                "webhook-settled-1",
    457                                                "order_settled",
    458                                                "http://localhost:12345/",
    459                                                "POST",
    460                                                "Taler-test-header: settled",
    461                                                "order-settled",
    462                                                MHD_HTTP_NO_CONTENT),
    463     TALER_TESTING_cmd_testserver ("launch-http-server-for-webhooks",
    464                                   12345),
    465     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-1-idem",
    466                                              cred.cfg,
    467                                              merchant_url,
    468                                              MHD_HTTP_OK,
    469                                              "1",
    470                                              GNUNET_TIME_UNIT_ZERO_TS,
    471                                              GNUNET_TIME_UNIT_FOREVER_TS,
    472                                              true,
    473                                              "EUR:5.0",
    474                                              "x-taler-bank",
    475                                              "",
    476                                              "",
    477                                              "create-proposal-1"),
    478     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-1x",
    479                                              cred.cfg,
    480                                              merchant_url,
    481                                              MHD_HTTP_OK,
    482                                              "1x",
    483                                              GNUNET_TIME_UNIT_ZERO_TS,
    484                                              GNUNET_TIME_UNIT_FOREVER_TS,
    485                                              true,
    486                                              "EUR:5.0",
    487                                              "x-taler-bank",
    488                                              "",
    489                                              "",
    490                                              NULL),
    491     TALER_TESTING_cmd_merchant_claim_order ("reclaim-1",
    492                                             merchant_url,
    493                                             MHD_HTTP_OK,
    494                                             "create-proposal-1",
    495                                             NULL),
    496     TALER_TESTING_cmd_merchant_claim_order ("reclaim-1-bad-nonce",
    497                                             merchant_url,
    498                                             MHD_HTTP_CONFLICT,
    499                                             NULL,
    500                                             "1"),
    501     TALER_TESTING_cmd_merchant_claim_order ("reclaim-1x",
    502                                             merchant_url,
    503                                             MHD_HTTP_OK,
    504                                             "create-proposal-1x",
    505                                             NULL),
    506     /* A claimed order is owned by the wallet that claimed it, so it
    507        may only be deleted with an explicit force option. */
    508     TALER_TESTING_cmd_merchant_post_orders_no_claim (
    509       "create-proposal-claimed-del",
    510       merchant_url,
    511       MHD_HTTP_OK,
    512       "claimed-del",
    513       GNUNET_TIME_UNIT_ZERO_TS,
    514       GNUNET_TIME_UNIT_FOREVER_TS,
    515       "EUR:5.0"),
    516     /* deleting it now, while still unclaimed, would simply work */
    517     TALER_TESTING_cmd_merchant_claim_order ("claim-claimed-del",
    518                                             merchant_url,
    519                                             MHD_HTTP_OK,
    520                                             "create-proposal-claimed-del",
    521                                             NULL),
    522     TALER_TESTING_cmd_merchant_delete_order2 ("delete-claimed-del-noforce",
    523                                               merchant_url,
    524                                               "claimed-del",
    525                                               false,
    526                                               MHD_HTTP_CONFLICT),
    527     TALER_TESTING_cmd_merchant_delete_order2 ("delete-claimed-del-force",
    528                                               merchant_url,
    529                                               "claimed-del",
    530                                               true, /* force flag */
    531                                               MHD_HTTP_NO_CONTENT),
    532     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-1-pre-exists",
    533                                             cred.cfg,
    534                                             merchant_url,
    535                                             MHD_HTTP_CONFLICT,
    536                                             "1",
    537                                             GNUNET_TIME_UNIT_ZERO_TS,
    538                                             GNUNET_TIME_UNIT_FOREVER_TS,
    539                                             "EUR:5.0"),
    540     TALER_TESTING_cmd_poll_orders_conclude ("poll-orders-1-conclude",
    541                                             MHD_HTTP_OK,
    542                                             "poll-orders-1-start"),
    543     TALER_TESTING_cmd_merchant_get_orders ("get-orders-1",
    544                                            merchant_url,
    545                                            MHD_HTTP_OK,
    546                                            "create-proposal-1x",
    547                                            "create-proposal-1",
    548                                            NULL),
    549     TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1",
    550                                         merchant_url,
    551                                         "create-proposal-1",
    552                                         false,
    553                                         false,
    554                                         false,
    555                                         MHD_HTTP_PAYMENT_REQUIRED),
    556     TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1",
    557                                           merchant_url,
    558                                           "create-proposal-1",
    559                                           TALER_MERCHANT_OSC_CLAIMED,
    560                                           false,
    561                                           MHD_HTTP_OK,
    562                                           NULL),
    563     TALER_TESTING_cmd_wallet_poll_order_start ("poll-order-wallet-start-1",
    564                                                merchant_url,
    565                                                "create-proposal-1",
    566                                                POLL_ORDER_TIMEOUT,
    567                                                NULL),
    568     TALER_TESTING_cmd_wallet_poll_order_start2 ("poll-order-wallet-start-1x",
    569                                                 merchant_url,
    570                                                 "create-proposal-1x",
    571                                                 POLL_ORDER_SHORT_TIMEOUT,
    572                                                 NULL, /* no refund */
    573                                                 "session-0"),
    574     TALER_TESTING_cmd_poll_order_start ("poll-order-merchant-1-start",
    575                                         merchant_url,
    576                                         "1",
    577                                         POLL_ORDER_TIMEOUT),
    578     TALER_TESTING_cmd_merchant_pay_order ("deposit-simple",
    579                                           merchant_url,
    580                                           MHD_HTTP_OK,
    581                                           "create-proposal-1",
    582                                           "withdraw-coin-1",
    583                                           "EUR:5",
    584                                           "EUR:4.99",
    585                                           "session-0"),
    586     TALER_TESTING_cmd_poll_order_conclude ("poll-order-merchant-1-conclude",
    587                                            MHD_HTTP_OK,
    588                                            "poll-order-merchant-1-start"),
    589     TALER_TESTING_cmd_wallet_poll_order_conclude ("poll-order-1-conclude",
    590                                                   MHD_HTTP_OK,
    591                                                   NULL,
    592                                                   "poll-order-wallet-start-1"),
    593     /* Check for webhook */
    594     cmd_webhook ("pending-webhooks-pay-w1"),
    595     /* Check webhook did anything: have a command that inspects traits of the testserver
    596        and check if the traits have the right values set! */
    597     TALER_TESTING_cmd_checkserver ("check-http-server-for-webhooks",
    598                                    "launch-http-server-for-webhooks",
    599                                    0),
    600     /* Here we expect to run into a timeout, as we do not pay this one */
    601     TALER_TESTING_cmd_wallet_poll_order_conclude2 ("poll-order-1x-conclude",
    602                                                    MHD_HTTP_PAYMENT_REQUIRED,
    603                                                    NULL,
    604                                                    "poll-order-wallet-start-1x",
    605                                                    "1"),
    606     TALER_TESTING_cmd_merchant_post_orders_paid ("verify-order-1-paid",
    607                                                  merchant_url,
    608                                                  "deposit-simple",
    609                                                  "session-1",
    610                                                  MHD_HTTP_OK),
    611     TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1-2",
    612                                         merchant_url,
    613                                         "create-proposal-1",
    614                                         true,
    615                                         false,
    616                                         false,
    617                                         MHD_HTTP_OK),
    618     TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1-2a",
    619                                           merchant_url,
    620                                           "create-proposal-1",
    621                                           TALER_MERCHANT_OSC_PAID,
    622                                           false,
    623                                           MHD_HTTP_OK,
    624                                           NULL),
    625     TALER_TESTING_cmd_merchant_get_orders ("get-orders-1-paid",
    626                                            merchant_url,
    627                                            MHD_HTTP_OK,
    628                                            "create-proposal-1x",
    629                                            "create-proposal-1",
    630                                            NULL),
    631     TALER_TESTING_cmd_merchant_pay_order ("replay-simple",
    632                                           merchant_url,
    633                                           MHD_HTTP_OK,
    634                                           "create-proposal-1",
    635                                           "withdraw-coin-1",
    636                                           "EUR:5",
    637                                           "EUR:4.99",
    638                                           "session-0"),
    639     TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-1"),
    640     TALER_TESTING_cmd_sleep (
    641       "Wait for wire transfer deadline",
    642       3),
    643     CMD_EXEC_AGGREGATOR ("run-aggregator"),
    644     TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-498c",
    645                                            EXCHANGE_URL,
    646                                            "EUR:4.98",
    647                                            exchange_payto,
    648                                            merchant_payto),
    649     TALER_TESTING_cmd_merchant_post_transfer ("post-transfer-1",
    650                                               &cred.ba,
    651                                               merchant_payto,
    652                                               merchant_url,
    653                                               "EUR:4.98",
    654                                               MHD_HTTP_NO_CONTENT,
    655                                               "deposit-simple",
    656                                               NULL),
    657     TALER_TESTING_cmd_depositcheck ("run taler-merchant-depositcheck-1",
    658                                     config_file),
    659     TALER_TESTING_cmd_run_tme ("run taler-merchant-reconciliation-1",
    660                                config_file),
    661     /* Check for settled webhook after reconciliation */
    662     cmd_webhook ("pending-webhooks-settled-w1"),
    663     TALER_TESTING_cmd_checkserver2 ("check-http-server-for-settled-webhook",
    664                                     "launch-http-server-for-webhooks",
    665                                     1,
    666                                     "/",
    667                                     "POST",
    668                                     "settled",
    669                                     "order-settled"),
    670     TALER_TESTING_cmd_merchant_post_transfer2 ("post-transfer-bad",
    671                                                merchant_url,
    672                                                merchant_payto,
    673                                                "EUR:4.98",
    674                                                NULL,
    675                                                /*non-routable IP address
    676                                                so we are sure to not get
    677                                                any reply*/
    678                                                "http://192.0.2.1/404/",
    679                                                MHD_HTTP_NO_CONTENT),
    680     TALER_TESTING_cmd_merchant_get_transfers ("get-transfers-1",
    681                                               merchant_url,
    682                                               merchant_payto,
    683                                               MHD_HTTP_OK,
    684                                               "post-transfer-1",
    685                                               "post-transfer-bad",
    686                                               NULL),
    687     TALER_TESTING_cmd_merchant_delete_transfer ("delete-transfer-1",
    688                                                 merchant_url,
    689                                                 "post-transfer-bad",
    690                                                 MHD_HTTP_NO_CONTENT),
    691     TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-2b",
    692                                            merchant_url,
    693                                            "create-proposal-1",
    694                                            TALER_MERCHANT_OSC_PAID,
    695                                            true,
    696                                            order_1_transfers, /* "post-transfer-1" */
    697                                            false,
    698                                            NULL,
    699                                            NULL,
    700                                            MHD_HTTP_OK),
    701     TALER_TESTING_cmd_merchant_forget_order ("forget-1",
    702                                              merchant_url,
    703                                              MHD_HTTP_NO_CONTENT,
    704                                              "create-proposal-1",
    705                                              NULL,
    706                                              "$.dummy_obj",
    707                                              NULL),
    708     TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-forget-1",
    709                                            merchant_url,
    710                                            "create-proposal-1",
    711                                            TALER_MERCHANT_OSC_PAID,
    712                                            true,
    713                                            order_1_transfers,
    714                                            false,
    715                                            NULL,
    716                                            order_1_forgets_1,
    717                                            MHD_HTTP_OK),
    718     TALER_TESTING_cmd_merchant_forget_order ("forget-unforgettable",
    719                                              merchant_url,
    720                                              MHD_HTTP_CONFLICT,
    721                                              "create-proposal-1",
    722                                              NULL,
    723                                              "$.amount",
    724                                              NULL),
    725     TALER_TESTING_cmd_merchant_forget_order ("forget-order-nx",
    726                                              merchant_url,
    727                                              MHD_HTTP_NOT_FOUND,
    728                                              NULL,
    729                                              "nx-order",
    730                                              "$.dummy_obj",
    731                                              NULL),
    732     TALER_TESTING_cmd_merchant_forget_order ("forget-order-array-elem",
    733                                              merchant_url,
    734                                              MHD_HTTP_NO_CONTENT,
    735                                              "create-proposal-1",
    736                                              NULL,
    737                                              "$.dummy_array[0].item",
    738                                              NULL),
    739     TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-forget-2",
    740                                            merchant_url,
    741                                            "create-proposal-1",
    742                                            TALER_MERCHANT_OSC_PAID,
    743                                            true,
    744                                            order_1_transfers,
    745                                            false,
    746                                            NULL,
    747                                            order_1_forgets_2,
    748                                            MHD_HTTP_OK),
    749     TALER_TESTING_cmd_merchant_forget_order ("forget-order-array-wc",
    750                                              merchant_url,
    751                                              MHD_HTTP_NO_CONTENT,
    752                                              "create-proposal-1",
    753                                              NULL,
    754                                              "$.dummy_array[*].item",
    755                                              NULL),
    756     TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-forget-3",
    757                                            merchant_url,
    758                                            "create-proposal-1",
    759                                            TALER_MERCHANT_OSC_PAID,
    760                                            true,
    761                                            order_1_transfers,
    762                                            false,
    763                                            NULL,
    764                                            order_1_forgets_3,
    765                                            MHD_HTTP_OK),
    766     TALER_TESTING_cmd_merchant_forget_order ("forget-order-malformed",
    767                                              merchant_url,
    768                                              MHD_HTTP_BAD_REQUEST,
    769                                              "create-proposal-1",
    770                                              NULL,
    771                                              "$.dummy_array[abc].item",
    772                                              NULL),
    773     TALER_TESTING_cmd_merchant_post_products ("post-products-p3",
    774                                               merchant_url,
    775                                               "product-3",
    776                                               "a product",
    777                                               "EUR:1",
    778                                               MHD_HTTP_NO_CONTENT),
    779     TALER_TESTING_cmd_merchant_post_products2 ("post-product-piece",
    780                                                merchant_url,
    781                                                "product-piece",
    782                                                "a product sold by piece",
    783                                                NULL,
    784                                                "Piece",
    785                                                "EUR:1",
    786                                                "",
    787                                                NULL,
    788                                                4,
    789                                                0,
    790                                                NULL,
    791                                                GNUNET_TIME_UNIT_ZERO_TS,
    792                                                MHD_HTTP_NO_CONTENT),
    793     TALER_TESTING_cmd_merchant_post_products_with_unit_prices (
    794       "post-products-dup-currency",
    795       merchant_url,
    796       "product-dup-currency",
    797       "duplicate currency product",
    798       "test-unit",
    799       (const char *[]) { "EUR:1", "EUR:2" },
    800       2,
    801       MHD_HTTP_BAD_REQUEST),
    802     TALER_TESTING_cmd_merchant_post_products2 ("post-products-p4",
    803                                                merchant_url,
    804                                                "product-4age",
    805                                                "an age-restricted product",
    806                                                NULL,
    807                                                "unit",
    808                                                "EUR:1",
    809                                                "", /* image */
    810                                                NULL,
    811                                                4,
    812                                                16 /* minimum age */,
    813                                                NULL,
    814                                                GNUNET_TIME_UNIT_FOREVER_TS,
    815                                                MHD_HTTP_NO_CONTENT),
    816     TALER_TESTING_cmd_merchant_post_products3 ("post-products-frac",
    817                                                merchant_url,
    818                                                "product-frac",
    819                                                "fractional product",
    820                                                json_pack ("{s:s}",
    821                                                           "en",
    822                                                           "fractional product"),
    823                                                "kg",
    824                                                "EUR:1.5",
    825                                                "",
    826                                                json_array (),
    827                                                1,
    828                                                (TALER_MERCHANT_UNIT_FRAC_BASE
    829                                                 * 3)
    830                                                / 4,
    831                                                true,
    832                                                0,
    833                                                NULL,
    834                                                GNUNET_TIME_UNIT_ZERO_TS,
    835                                                MHD_HTTP_NO_CONTENT),
    836     TALER_TESTING_cmd_merchant_get_product ("get-product-frac-post",
    837                                             merchant_url,
    838                                             "product-frac",
    839                                             MHD_HTTP_OK,
    840                                             "post-products-frac"),
    841     TALER_TESTING_cmd_merchant_patch_product_with_unit_prices (
    842       "patch-products-dup-currency",
    843       merchant_url,
    844       "product-3",
    845       "a product",
    846       "can",
    847       (const char *[]) { "EUR:1", "EUR:2" },
    848       2,
    849       MHD_HTTP_BAD_REQUEST),
    850     TALER_TESTING_cmd_merchant_patch_product ("patch-products-p3",
    851                                               merchant_url,
    852                                               "product-3",
    853                                               "a product",
    854                                               json_object (),
    855                                               "can",
    856                                               "EUR:1",
    857                                               "data:image/jpeg;base64,RAWDATA",
    858                                               json_array (),
    859                                               5,
    860                                               0,
    861                                               json_object (),
    862                                               GNUNET_TIME_relative_to_timestamp
    863                                               (
    864                                                 GNUNET_TIME_UNIT_MINUTES),
    865                                               MHD_HTTP_NO_CONTENT),
    866     TALER_TESTING_cmd_merchant_patch_product2 ("patch-product-frac",
    867                                                merchant_url,
    868                                                "product-frac",
    869                                                "fractional product patched",
    870                                                json_pack ("{s:s}",
    871                                                           "en",
    872                                                           "fractional product patched"),
    873                                                "kg",
    874                                                "EUR:1.6",
    875                                                "",
    876                                                json_array (),
    877                                                2,
    878                                                TALER_MERCHANT_UNIT_FRAC_BASE / 4
    879                                                ,
    880                                                true,
    881                                                0,
    882                                                json_object (),
    883                                                GNUNET_TIME_relative_to_timestamp
    884                                                (
    885                                                  GNUNET_TIME_UNIT_MINUTES),
    886                                                MHD_HTTP_NO_CONTENT),
    887     TALER_TESTING_cmd_merchant_get_product ("get-product-frac-patched",
    888                                             merchant_url,
    889                                             "product-frac",
    890                                             MHD_HTTP_OK,
    891                                             "patch-product-frac"),
    892     TALER_TESTING_cmd_merchant_delete_unit ("delete-unit-piece-denied",
    893                                             merchant_url,
    894                                             "Piece",
    895                                             MHD_HTTP_CONFLICT),
    896     TALER_TESTING_cmd_merchant_post_units ("post-unit-piece-conflict",
    897                                            merchant_url,
    898                                            "Piece",
    899                                            "piece",
    900                                            "pc",
    901                                            false,
    902                                            0,
    903                                            true,
    904                                            NULL,
    905                                            NULL,
    906                                            MHD_HTTP_CONFLICT),
    907     /* Per-instance override of a *builtin* unit (#12); only the policy
    908        flags may be changed, hence all name arguments must be NULL. */
    909     TALER_TESTING_cmd_merchant_patch_unit ("patch-unit-builtin",
    910                                            merchant_url,
    911                                            "SizeUnitCm",
    912                                            NULL,
    913                                            NULL,
    914                                            NULL,
    915                                            NULL,
    916                                            false,
    917                                            0,
    918                                            true,
    919                                            MHD_HTTP_NO_CONTENT),
    920     TALER_TESTING_cmd_merchant_get_unit ("get-unit-builtin-patched",
    921                                          merchant_url,
    922                                          "SizeUnitCm",
    923                                          MHD_HTTP_OK,
    924                                          "patch-unit-builtin"),
    925     /* second PATCH must update the existing override row */
    926     TALER_TESTING_cmd_merchant_patch_unit ("patch-unit-builtin-again",
    927                                            merchant_url,
    928                                            "SizeUnitCm",
    929                                            NULL,
    930                                            NULL,
    931                                            NULL,
    932                                            NULL,
    933                                            true,
    934                                            2,
    935                                            true,
    936                                            MHD_HTTP_NO_CONTENT),
    937     TALER_TESTING_cmd_merchant_get_unit ("get-unit-builtin-repatched",
    938                                          merchant_url,
    939                                          "SizeUnitCm",
    940                                          MHD_HTTP_OK,
    941                                          "patch-unit-builtin-again"),
    942     /* renaming a builtin unit remains a conflict */
    943     TALER_TESTING_cmd_merchant_patch_unit ("patch-unit-builtin-rename-denied",
    944                                            merchant_url,
    945                                            "SizeUnitCm",
    946                                            "centimetres",
    947                                            "cm",
    948                                            NULL,
    949                                            NULL,
    950                                            true,
    951                                            2,
    952                                            true,
    953                                            MHD_HTTP_CONFLICT),
    954     TALER_TESTING_cmd_merchant_post_units ("post-unit-bucket",
    955                                            merchant_url,
    956                                            "BucketCustomUnit",
    957                                            "bucket",
    958                                            "bkt",
    959                                            false,
    960                                            0,
    961                                            true,
    962                                            json_pack ("{s:s}", "en", "bucket"),
    963                                            json_pack ("{s:s}", "en", "bkt"),
    964                                            MHD_HTTP_NO_CONTENT),
    965     TALER_TESTING_cmd_merchant_get_unit ("get-unit-bucket",
    966                                          merchant_url,
    967                                          "BucketCustomUnit",
    968                                          MHD_HTTP_OK,
    969                                          "post-unit-bucket"),
    970     TALER_TESTING_cmd_merchant_get_units ("get-units-bucket-list",
    971                                           merchant_url,
    972                                           MHD_HTTP_OK,
    973                                           "post-unit-bucket",
    974                                           NULL),
    975     TALER_TESTING_cmd_merchant_patch_unit ("patch-unit-bucket",
    976                                            merchant_url,
    977                                            "BucketCustomUnit",
    978                                            "bucket-updated",
    979                                            "bkt-upd",
    980                                            json_pack ("{s:s}", "en",
    981                                                       "bucket-updated"),
    982                                            json_pack ("{s:s}", "en", "bkt-upd"),
    983                                            true,
    984                                            0,
    985                                            false,
    986                                            MHD_HTTP_NO_CONTENT),
    987     TALER_TESTING_cmd_merchant_get_unit ("get-unit-bucket-patched",
    988                                          merchant_url,
    989                                          "BucketCustomUnit",
    990                                          MHD_HTTP_OK,
    991                                          "patch-unit-bucket"),
    992     TALER_TESTING_cmd_merchant_get_units ("get-units-bucket-updated",
    993                                           merchant_url,
    994                                           MHD_HTTP_OK,
    995                                           "patch-unit-bucket",
    996                                           NULL),
    997     TALER_TESTING_cmd_merchant_delete_unit ("delete-unit-bucket",
    998                                             merchant_url,
    999                                             "BucketCustomUnit",
   1000                                             MHD_HTTP_NO_CONTENT),
   1001     TALER_TESTING_cmd_merchant_get_unit ("get-unit-bucket-deleted",
   1002                                          merchant_url,
   1003                                          "BucketCustomUnit",
   1004                                          MHD_HTTP_NOT_FOUND,
   1005                                          NULL),
   1006     TALER_TESTING_cmd_merchant_post_units ("post-unit-unicorn",
   1007                                            merchant_url,
   1008                                            "UnitUnicorn",
   1009                                            "unicorn",
   1010                                            "uni",
   1011                                            true,
   1012                                            1,
   1013                                            true,
   1014                                            json_pack ("{s:s}", "en", "unicorn"),
   1015                                            json_pack ("{s:s}", "en", "uni"),
   1016                                            MHD_HTTP_NO_CONTENT),
   1017     TALER_TESTING_cmd_merchant_post_products2 ("post-product-unicorn",
   1018                                                merchant_url,
   1019                                                "product-unicorn",
   1020                                                "a unicorn snack",
   1021                                                json_pack ("{s:s}",
   1022                                                           "en",
   1023                                                           "a unicorn snack"),
   1024                                                "UnitUnicorn",
   1025                                                "EUR:3.5",
   1026                                                "",
   1027                                                json_array (),
   1028                                                7,
   1029                                                0,
   1030                                                json_object (),
   1031                                                GNUNET_TIME_UNIT_ZERO_TS,
   1032                                                MHD_HTTP_NO_CONTENT),
   1033     TALER_TESTING_cmd_merchant_get_product2 ("get-product-unicorn-default",
   1034                                              merchant_url,
   1035                                              "product-unicorn",
   1036                                              MHD_HTTP_OK,
   1037                                              "post-product-unicorn",
   1038                                              &expect_unicorn_defaults),
   1039     TALER_TESTING_cmd_merchant_patch_unit ("patch-unit-unicorn",
   1040                                            merchant_url,
   1041                                            "UnitUnicorn",
   1042                                            NULL,
   1043                                            NULL,
   1044                                            NULL,
   1045                                            NULL,
   1046                                            false,
   1047                                            0,
   1048                                            true,
   1049                                            MHD_HTTP_NO_CONTENT),
   1050     TALER_TESTING_cmd_merchant_get_product2 ("get-product-unicorn-patched",
   1051                                              merchant_url,
   1052                                              "product-unicorn",
   1053                                              MHD_HTTP_OK,
   1054                                              "post-product-unicorn",
   1055                                              &expect_unicorn_patched),
   1056     TALER_TESTING_cmd_merchant_delete_product ("delete-product-unicorn",
   1057                                                merchant_url,
   1058                                                "product-unicorn",
   1059                                                MHD_HTTP_NO_CONTENT),
   1060     TALER_TESTING_cmd_merchant_delete_unit ("delete-unit-unicorn",
   1061                                             merchant_url,
   1062                                             "UnitUnicorn",
   1063                                             MHD_HTTP_NO_CONTENT),
   1064     TALER_TESTING_cmd_merchant_lock_product ("lock-product-p3",
   1065                                              merchant_url,
   1066                                              "product-3",
   1067                                              GNUNET_TIME_UNIT_MINUTES,
   1068                                              2,
   1069                                              MHD_HTTP_NO_CONTENT),
   1070     TALER_TESTING_cmd_merchant_lock_product2 (
   1071       "lock-product-p3-float-denied",
   1072       merchant_url,
   1073       "product-3",
   1074       GNUNET_TIME_UNIT_MINUTES,
   1075       1,
   1076       TALER_MERCHANT_UNIT_FRAC_BASE / 2,
   1077       true,
   1078       MHD_HTTP_BAD_REQUEST),
   1079     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-float-denied",
   1080                                              cred.cfg,
   1081                                              merchant_url,
   1082                                              MHD_HTTP_BAD_REQUEST,
   1083                                              "order-p3-float-denied",
   1084                                              GNUNET_TIME_UNIT_ZERO_TS,
   1085                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1086                                              true,
   1087                                              "EUR:5.0",
   1088                                              "x-taler-bank",
   1089                                              "product-3/1.5",
   1090                                              "",
   1091                                              NULL),
   1092     TALER_TESTING_cmd_merchant_patch_product2 (
   1093       "patch-product-3-allow-float",
   1094       merchant_url,
   1095       "product-3",
   1096       "a product allow fractional",
   1097       json_pack ("{s:s}",
   1098                  "en",
   1099                  "a product allow fractional"),
   1100       "can",
   1101       "EUR:1",
   1102       "data:image/jpeg;base64,RAWDATA",
   1103       json_array (),
   1104       5,
   1105       0,
   1106       true,
   1107       0,
   1108       json_object (),
   1109       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES),
   1110       MHD_HTTP_NO_CONTENT),
   1111     cmd_transfer_to_exchange ("create-reserve-p3-float",
   1112                               "EUR:5.01"),
   1113     cmd_exec_wirewatch ("wirewatch-p3-float"),
   1114     TALER_TESTING_cmd_check_bank_admin_transfer (
   1115       "check_bank_transfer-p3-float",
   1116       "EUR:5.01",
   1117       payer_payto,
   1118       exchange_payto,
   1119       "create-reserve-p3-float"),
   1120     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-p3-float",
   1121                                        "create-reserve-p3-float",
   1122                                        "EUR:5",
   1123                                        0,
   1124                                        MHD_HTTP_OK),
   1125     TALER_TESTING_cmd_merchant_lock_product2 (
   1126       "lock-product-p3-float",
   1127       merchant_url,
   1128       "product-3",
   1129       GNUNET_TIME_UNIT_MINUTES,
   1130       1,
   1131       TALER_MERCHANT_UNIT_FRAC_BASE / 2,
   1132       true,
   1133       MHD_HTTP_NO_CONTENT),
   1134     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-float",
   1135                                              cred.cfg,
   1136                                              merchant_url,
   1137                                              MHD_HTTP_OK,
   1138                                              "order-p3-float",
   1139                                              GNUNET_TIME_UNIT_ZERO_TS,
   1140                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1141                                              true,
   1142                                              "EUR:5.0",
   1143                                              "x-taler-bank",
   1144                                              "product-3/1.5",
   1145                                              "",
   1146                                              NULL),
   1147     TALER_TESTING_cmd_merchant_claim_order ("claim-order-p3-float",
   1148                                             merchant_url,
   1149                                             MHD_HTTP_OK,
   1150                                             "create-proposal-p3-float",
   1151                                             NULL),
   1152     TALER_TESTING_cmd_merchant_pay_order ("pay-order-p3-float",
   1153                                           merchant_url,
   1154                                           MHD_HTTP_OK,
   1155                                           "create-proposal-p3-float",
   1156                                           "withdraw-coin-p3-float",
   1157                                           "EUR:5",
   1158                                           "EUR:4.99",
   1159                                           "session-p3-float"),
   1160     TALER_TESTING_cmd_sleep (
   1161       "Wait for wire transfer deadline-p3-float",
   1162       3),
   1163     CMD_EXEC_AGGREGATOR ("run-aggregator-p3-float"),
   1164     TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-p3-float",
   1165                                            EXCHANGE_URL,
   1166                                            "EUR:4.98",
   1167                                            exchange_payto,
   1168                                            merchant_payto),
   1169     TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-p3-float-paid",
   1170                                           merchant_url,
   1171                                           "create-proposal-p3-float",
   1172                                           TALER_MERCHANT_OSC_PAID,
   1173                                           false,
   1174                                           MHD_HTTP_OK,
   1175                                           NULL),
   1176     TALER_TESTING_cmd_merchant_patch_product2 (
   1177       "patch-product-3-restore",
   1178       merchant_url,
   1179       "product-3",
   1180       "a product",
   1181       json_pack ("{s:s}",
   1182                  "en",
   1183                  "a product"),
   1184       "can",
   1185       "EUR:1",
   1186       "data:image/jpeg;base64,RAWDATA",
   1187       json_array (),
   1188       5,
   1189       0,
   1190       false,
   1191       0,
   1192       json_object (),
   1193       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES),
   1194       MHD_HTTP_NO_CONTENT),
   1195     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-wm-nx",
   1196                                              cred.cfg,
   1197                                              merchant_url,
   1198                                              MHD_HTTP_NOT_FOUND,
   1199                                              "order-p3",
   1200                                              GNUNET_TIME_UNIT_ZERO_TS,
   1201                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1202                                              true,
   1203                                              "EUR:5.0",
   1204                                              "unsupported-wire-method",
   1205                                              "product-3/2",
   1206                                              "", /* locks */
   1207                                              NULL),
   1208     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-pd-nx",
   1209                                              cred.cfg,
   1210                                              merchant_url,
   1211                                              MHD_HTTP_NOT_FOUND,
   1212                                              "order-p3",
   1213                                              GNUNET_TIME_UNIT_ZERO_TS,
   1214                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1215                                              true,
   1216                                              "EUR:5.0",
   1217                                              "x-taler-bank",
   1218                                              "unknown-product/2",
   1219                                              "",
   1220                                              NULL),
   1221     TALER_TESTING_cmd_merchant_post_orders2 (
   1222       "create-proposal-p3-not-enough-stock",
   1223       cred.cfg,
   1224       merchant_url,
   1225       MHD_HTTP_GONE,
   1226       "order-p3",
   1227       GNUNET_TIME_UNIT_ZERO_TS,
   1228       GNUNET_TIME_UNIT_FOREVER_TS,
   1229       true,
   1230       "EUR:5.0",
   1231       "x-taler-bank",
   1232       "product-3/24",
   1233       "",
   1234       NULL),
   1235     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3",
   1236                                              cred.cfg,
   1237                                              merchant_url,
   1238                                              MHD_HTTP_OK,
   1239                                              "order-p3",
   1240                                              GNUNET_TIME_UNIT_ZERO_TS,
   1241                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1242                                              false,
   1243                                              "EUR:5.0",
   1244                                              "x-taler-bank",
   1245                                              "product-3/3",
   1246                                              "lock-product-p3",
   1247                                              NULL),
   1248     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p4-age",
   1249                                              cred.cfg,
   1250                                              merchant_url,
   1251                                              MHD_HTTP_OK,
   1252                                              "order-p4-age",
   1253                                              GNUNET_TIME_UNIT_ZERO_TS,
   1254                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1255                                              false,
   1256                                              "EUR:5.0",
   1257                                              "x-taler-bank",
   1258                                              "product-4age",
   1259                                              "", /* locks */
   1260                                              NULL),
   1261     TALER_TESTING_cmd_merchant_get_order4 ("get-order-merchant-p4-age",
   1262                                            merchant_url,
   1263                                            "create-proposal-p4-age",
   1264                                            TALER_MERCHANT_OSC_CLAIMED,
   1265                                            16,
   1266                                            MHD_HTTP_OK),
   1267     TALER_TESTING_cmd_merchant_delete_order ("delete-order-paid",
   1268                                              merchant_url,
   1269                                              "1",
   1270                                              MHD_HTTP_CONFLICT),
   1271     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-no-id",
   1272                                             cred.cfg,
   1273                                             merchant_url,
   1274                                             MHD_HTTP_OK,
   1275                                             NULL,
   1276                                             GNUNET_TIME_UNIT_ZERO_TS,
   1277                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1278                                             "EUR:5.0"),
   1279     TALER_TESTING_cmd_merchant_delete_webhook ("post-webhooks-pay-w1",
   1280                                                merchant_url,
   1281                                                "webhook-pay-1",
   1282                                                MHD_HTTP_NO_CONTENT),
   1283     TALER_TESTING_cmd_merchant_delete_webhook ("post-webhooks-settled-w1",
   1284                                                merchant_url,
   1285                                                "webhook-settled-1",
   1286                                                MHD_HTTP_NO_CONTENT),
   1287     TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-2"),
   1288     TALER_TESTING_cmd_end ()
   1289   };
   1290   struct TALER_TESTING_Command double_spending[] = {
   1291     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-2",
   1292                                             cred.cfg,
   1293                                             merchant_url,
   1294                                             MHD_HTTP_OK,
   1295                                             "2",
   1296                                             GNUNET_TIME_UNIT_ZERO_TS,
   1297                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1298                                             "EUR:5.0"),
   1299     TALER_TESTING_cmd_merchant_claim_order ("fetch-proposal-2",
   1300                                             merchant_url,
   1301                                             MHD_HTTP_OK,
   1302                                             "create-proposal-2",
   1303                                             NULL),
   1304     TALER_TESTING_cmd_merchant_pay_order ("deposit-double-2",
   1305                                           merchant_url,
   1306                                           MHD_HTTP_CONFLICT,
   1307                                           "create-proposal-2",
   1308                                           "withdraw-coin-1",
   1309                                           "EUR:5",
   1310                                           "EUR:4.99",
   1311                                           NULL),
   1312     TALER_TESTING_cmd_end ()
   1313   };
   1314 
   1315   const char *order_1r_refunds[] = {
   1316     "refund-increase-1r",
   1317     "refund-increase-1r-2",
   1318     NULL
   1319   };
   1320   struct TALER_TESTING_Command refund[] = {
   1321     cmd_transfer_to_exchange ("create-reserve-1r",
   1322                               "EUR:10.02"),
   1323     /**
   1324      * Make a reserve exist, according to the previous transfer.
   1325      */
   1326     cmd_exec_wirewatch ("wirewatch-1r"),
   1327     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-2r",
   1328                                                  "EUR:10.02",
   1329                                                  payer_payto,
   1330                                                  exchange_payto,
   1331                                                  "create-reserve-1r"),
   1332     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1r",
   1333                                        "create-reserve-1r",
   1334                                        "EUR:5",
   1335                                        0,
   1336                                        MHD_HTTP_OK),
   1337     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2r",
   1338                                        "create-reserve-1r",
   1339                                        "EUR:5",
   1340                                        0,
   1341                                        MHD_HTTP_OK),
   1342     /**
   1343      * Check the reserve is depleted.
   1344      */
   1345     TALER_TESTING_cmd_status ("withdraw-status-1r",
   1346                               "create-reserve-1r",
   1347                               "EUR:0",
   1348                               MHD_HTTP_OK),
   1349     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-1r",
   1350                                             cred.cfg,
   1351                                             merchant_url,
   1352                                             MHD_HTTP_OK,
   1353                                             "1r",
   1354                                             GNUNET_TIME_UNIT_ZERO_TS,
   1355                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1356                                             "EUR:5.0"),
   1357     TALER_TESTING_cmd_wallet_poll_order_start ("poll-order-wallet-refund-1-low",
   1358                                                merchant_url,
   1359                                                "create-proposal-1r",
   1360                                                POLL_ORDER_TIMEOUT,
   1361                                                "EUR:0.01"),
   1362     TALER_TESTING_cmd_wallet_poll_order_start (
   1363       "poll-order-wallet-refund-1-high",
   1364       merchant_url,
   1365       "create-proposal-1r",
   1366       POLL_ORDER_TIMEOUT,
   1367       "EUR:0.2"),
   1368     TALER_TESTING_cmd_merchant_pay_order ("pay-for-refund-1r",
   1369                                           merchant_url,
   1370                                           MHD_HTTP_OK,
   1371                                           "create-proposal-1r",
   1372                                           "withdraw-coin-1r",
   1373                                           "EUR:5",
   1374                                           "EUR:4.99",
   1375                                           NULL),
   1376     TALER_TESTING_cmd_poll_order_start ("poll-payment-refund-1",
   1377                                         merchant_url,
   1378                                         "1r", /* proposal name, not cmd ref! */
   1379                                         POLL_ORDER_TIMEOUT),
   1380     TALER_TESTING_cmd_merchant_order_refund ("refund-increase-1r",
   1381                                              merchant_url,
   1382                                              "refund test",
   1383                                              "1r", /* order ID */
   1384                                              "EUR:0.1",
   1385                                              MHD_HTTP_OK),
   1386     TALER_TESTING_cmd_wallet_poll_order_conclude ("poll-order-1-conclude-low",
   1387                                                   MHD_HTTP_OK,
   1388                                                   "EUR:0.1",
   1389                                                   "poll-order-wallet-refund-1-low"),
   1390     TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1r",
   1391                                         merchant_url,
   1392                                         "create-proposal-1r",
   1393                                         true,
   1394                                         true,
   1395                                         true,
   1396                                         MHD_HTTP_OK),
   1397     TALER_TESTING_cmd_merchant_order_refund ("refund-increase-1r-2",
   1398                                              merchant_url,
   1399                                              "refund test 2",
   1400                                              "1r", /* order ID */
   1401                                              "EUR:1.0",
   1402                                              MHD_HTTP_OK),
   1403     TALER_TESTING_cmd_wallet_poll_order_conclude ("poll-order-1-conclude-high",
   1404                                                   MHD_HTTP_OK,
   1405                                                   "EUR:1.0",
   1406                                                   "poll-order-wallet-refund-1-high"),
   1407     TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1r-2",
   1408                                         merchant_url,
   1409                                         "create-proposal-1r",
   1410                                         true,
   1411                                         true,
   1412                                         true,
   1413                                         MHD_HTTP_OK),
   1414     TALER_TESTING_cmd_wallet_order_refund ("obtain-refund-1r",
   1415                                            merchant_url,
   1416                                            "create-proposal-1r",
   1417                                            MHD_HTTP_OK,
   1418                                            "refund-increase-1r",
   1419                                            "refund-increase-1r-2",
   1420                                            NULL),
   1421     TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1r-3",
   1422                                         merchant_url,
   1423                                         "create-proposal-1r",
   1424                                         true,
   1425                                         true,
   1426                                         false,
   1427                                         MHD_HTTP_OK),
   1428     TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1r",
   1429                                           merchant_url,
   1430                                           "create-proposal-1r",
   1431                                           TALER_MERCHANT_OSC_PAID,
   1432                                           true,
   1433                                           MHD_HTTP_OK,
   1434                                           "refund-increase-1r",
   1435                                           "refund-increase-1r-2",
   1436                                           NULL),
   1437     TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1r-2",
   1438                                            merchant_url,
   1439                                            "create-proposal-1r",
   1440                                            TALER_MERCHANT_OSC_PAID,
   1441                                            false,
   1442                                            NULL,
   1443                                            true,
   1444                                            order_1r_refunds,
   1445                                            NULL,
   1446                                            MHD_HTTP_OK),
   1447     TALER_TESTING_cmd_poll_order_conclude ("poll-payment-refund-conclude-1",
   1448                                            MHD_HTTP_OK,
   1449                                            "poll-payment-refund-1"),
   1450 
   1451     /* Test /refund on a contract that was never paid.  */
   1452     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-not-to-be-paid",
   1453                                             cred.cfg,
   1454                                             merchant_url,
   1455                                             MHD_HTTP_OK,
   1456                                             "1-unpaid",
   1457                                             GNUNET_TIME_UNIT_ZERO_TS,
   1458                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1459                                             "EUR:5.0"),
   1460     /* Try to increase an unpaid proposal.  */
   1461     TALER_TESTING_cmd_merchant_order_refund ("refund-increase-unpaid-proposal",
   1462                                              merchant_url,
   1463                                              "refund test",
   1464                                              "1-unpaid",
   1465                                              "EUR:0.1",
   1466                                              MHD_HTTP_CONFLICT),
   1467     /* Try to increase a non existent proposal.  */
   1468     TALER_TESTING_cmd_merchant_order_refund (
   1469       "refund-increase-nonexistent-proposal",
   1470       merchant_url,
   1471       "refund test",
   1472       "non-existent-id",
   1473       "EUR:0.1",
   1474       MHD_HTTP_NOT_FOUND),
   1475     /*
   1476        The following block will (1) create a new
   1477        reserve, then (2) a proposal, then (3) pay for
   1478        it, and finally (4) attempt to pick up a refund
   1479        from it without any increasing taking place
   1480        in the first place.
   1481     */
   1482     cmd_transfer_to_exchange ("create-reserve-unincreased-refund",
   1483                               "EUR:5.01"),
   1484     cmd_exec_wirewatch ("wirewatch-unincreased-refund"),
   1485     TALER_TESTING_cmd_check_bank_admin_transfer (
   1486       "check_bank_transfer-unincreased-refund",
   1487       "EUR:5.01",
   1488       payer_payto,
   1489       exchange_payto,
   1490       "create-reserve-unincreased-refund"),
   1491     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-unincreased-refund",
   1492                                        "create-reserve-unincreased-refund",
   1493                                        "EUR:5",
   1494                                        0,
   1495                                        MHD_HTTP_OK),
   1496     TALER_TESTING_cmd_merchant_post_orders (
   1497       "create-proposal-unincreased-refund",
   1498       cred.cfg,
   1499       merchant_url,
   1500       MHD_HTTP_OK,
   1501       "unincreased-proposal",
   1502       GNUNET_TIME_UNIT_ZERO_TS,
   1503       GNUNET_TIME_UNIT_FOREVER_TS,
   1504       "EUR:5.0"),
   1505     TALER_TESTING_cmd_merchant_pay_order ("pay-unincreased-proposal",
   1506                                           merchant_url,
   1507                                           MHD_HTTP_OK,
   1508                                           "create-proposal-unincreased-refund",
   1509                                           "withdraw-coin-unincreased-refund",
   1510                                           "EUR:5",
   1511                                           "EUR:4.99",
   1512                                           NULL),
   1513     TALER_TESTING_cmd_sleep (
   1514       "Wait for wire transfer deadline",
   1515       3),
   1516     CMD_EXEC_AGGREGATOR ("run-aggregator-unincreased-refund"),
   1517     TALER_TESTING_cmd_check_bank_transfer (
   1518       "check_bank_transfer-paid-unincreased-refund",
   1519       EXCHANGE_URL,
   1520       "EUR:8.97", /* '4.98 from above', plus 4.99 from 'pay-for-refund-1r'
   1521                      and MINUS 0.1 MINUS 0.9 from
   1522                      'refund-increase-1r' and 'refund-increase-1r-2' */
   1523       exchange_payto,
   1524       merchant_payto),
   1525     TALER_TESTING_cmd_end ()
   1526   };
   1527 
   1528   struct TALER_TESTING_Command auth[] = {
   1529     TALER_TESTING_cmd_merchant_post_instances ("instance-create-i1a",
   1530                                                merchant_url,
   1531                                                "i1a",
   1532                                                MHD_HTTP_NO_CONTENT),
   1533     TALER_TESTING_cmd_merchant_post_account (
   1534       "instance-create-i1a-account",
   1535       merchant_url_i1a,
   1536       merchant_payto,
   1537       NULL, NULL,
   1538       MHD_HTTP_OK),
   1539     TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-1",
   1540                                             merchant_url_i1a,
   1541                                             "nx-product",
   1542                                             MHD_HTTP_NOT_FOUND,
   1543                                             NULL),
   1544     TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-1",
   1545                                              merchant_url_i1a,
   1546                                              MHD_HTTP_OK,
   1547                                              NULL),
   1548     TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-2",
   1549                                             merchant_url_i1a,
   1550                                             "nx-product",
   1551                                             MHD_HTTP_NOT_FOUND,
   1552                                             NULL),
   1553     TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-2",
   1554                                              merchant_url_i1a,
   1555                                              MHD_HTTP_OK,
   1556                                              NULL),
   1557     TALER_TESTING_cmd_merchant_post_instance_auth (
   1558       "instance-create-i1a-auth-ok",
   1559       merchant_url,
   1560       "i1a",
   1561       "my-secret",
   1562       MHD_HTTP_NO_CONTENT),
   1563     TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-3",
   1564                                             merchant_url_i1a,
   1565                                             "nx-product",
   1566                                             MHD_HTTP_UNAUTHORIZED,
   1567                                             NULL),
   1568     TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-3",
   1569                                              merchant_url_i1a,
   1570                                              MHD_HTTP_UNAUTHORIZED,
   1571                                              NULL),
   1572     TALER_TESTING_cmd_set_authorization ("set-auth-valid",
   1573                                          "Basic aTFhOm15LXNlY3JldA=="),
   1574     TALER_TESTING_cmd_merchant_post_instance_token (
   1575       "instance-create-i1a-token-ok",
   1576       merchant_url,
   1577       "i1a",
   1578       "write", /* scope */
   1579       GNUNET_TIME_UNIT_DAYS, /* duration */
   1580       GNUNET_YES, /* refreshable */
   1581       MHD_HTTP_OK),
   1582     TALER_TESTING_cmd_set_authorization ("unset-auth-valid",
   1583                                          NULL), // Unset header
   1584     TALER_TESTING_cmd_merchant_set_instance_token (
   1585       "instance-create-i1a-token-set",
   1586       "instance-create-i1a-token-ok"),
   1587     TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-4",
   1588                                             merchant_url_i1a,
   1589                                             "nx-product",
   1590                                             MHD_HTTP_NOT_FOUND,
   1591                                             NULL),
   1592     TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-4",
   1593                                              merchant_url_i1a,
   1594                                              MHD_HTTP_OK,
   1595                                              NULL),
   1596     TALER_TESTING_cmd_merchant_delete_instance_token (
   1597       "instance-create-i1a-token-delete",
   1598       merchant_url,
   1599       "i1a",
   1600       MHD_HTTP_NO_CONTENT),
   1601     TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-5",
   1602                                             merchant_url_i1a,
   1603                                             "nx-product",
   1604                                             MHD_HTTP_UNAUTHORIZED,
   1605                                             NULL),
   1606     TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-5",
   1607                                              merchant_url_i1a,
   1608                                              MHD_HTTP_UNAUTHORIZED,
   1609                                              NULL),
   1610     TALER_TESTING_cmd_merchant_purge_instance ("instance-delete-i1a-fail",
   1611                                                merchant_url_i1a,
   1612                                                NULL,
   1613                                                MHD_HTTP_UNAUTHORIZED),
   1614     TALER_TESTING_cmd_set_authorization ("set-token-auth-valid-again",
   1615                                          "Basic aTFhOm15LXNlY3JldA=="),
   1616     TALER_TESTING_cmd_merchant_post_instance_token (
   1617       "set-auth-valid-again",
   1618       merchant_url,
   1619       "i1a",
   1620       "write", /* scope */
   1621       GNUNET_TIME_UNIT_DAYS, /* duration */
   1622       GNUNET_YES, /* refreshable */
   1623       MHD_HTTP_OK),
   1624     TALER_TESTING_cmd_set_authorization ("unset-auth-valid2",
   1625                                          NULL), // Unset header
   1626     TALER_TESTING_cmd_merchant_set_instance_token (
   1627       "instance-create-i1a-token-set-again",
   1628       "set-auth-valid-again"),
   1629     TALER_TESTING_cmd_merchant_post_instance_auth2 (
   1630       "instance-create-i1a-auth-ok-idempotent",
   1631       merchant_url_i1a,
   1632       NULL,
   1633       RFC_8959_PREFIX "my-other-secret",
   1634       "my-secret",
   1635       MHD_HTTP_NO_CONTENT),
   1636     TALER_TESTING_cmd_merchant_post_instance_auth2 (
   1637       "instance-create-i1a-clear-auth",
   1638       merchant_url_i1a,
   1639       NULL,
   1640       NULL,
   1641       "my-other-secret",
   1642       MHD_HTTP_NO_CONTENT),
   1643     TALER_TESTING_cmd_set_authorization ("set-auth-none",
   1644                                          NULL),
   1645     TALER_TESTING_cmd_merchant_purge_instance ("instance-delete-i1a",
   1646                                                merchant_url_i1a,
   1647                                                NULL,
   1648                                                MHD_HTTP_NO_CONTENT),
   1649     TALER_TESTING_cmd_end ()
   1650   };
   1651 
   1652   struct TALER_TESTING_Command pay_again[] = {
   1653     cmd_transfer_to_exchange ("create-reserve-20",
   1654                               "EUR:20.04"),
   1655     cmd_exec_wirewatch ("wirewatch-20"),
   1656     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-10",
   1657                                                  "EUR:20.04",
   1658                                                  payer_payto,
   1659                                                  exchange_payto,
   1660                                                  "create-reserve-20"),
   1661     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-10a",
   1662                                        "create-reserve-20",
   1663                                        "EUR:5",
   1664                                        0,
   1665                                        MHD_HTTP_OK),
   1666     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-10b",
   1667                                        "create-reserve-20",
   1668                                        "EUR:5",
   1669                                        0,
   1670                                        MHD_HTTP_OK),
   1671     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-10c",
   1672                                        "create-reserve-20",
   1673                                        "EUR:5",
   1674                                        0,
   1675                                        MHD_HTTP_OK),
   1676     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-10d",
   1677                                        "create-reserve-20",
   1678                                        "EUR:5",
   1679                                        0,
   1680                                        MHD_HTTP_OK),
   1681     TALER_TESTING_cmd_status ("withdraw-status-20",
   1682                               "create-reserve-20",
   1683                               "EUR:0",
   1684                               MHD_HTTP_OK),
   1685     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-10",
   1686                                             cred.cfg,
   1687                                             merchant_url,
   1688                                             MHD_HTTP_OK,
   1689                                             "10",
   1690                                             GNUNET_TIME_UNIT_ZERO_TS,
   1691                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1692                                             "EUR:10.0"),
   1693     TALER_TESTING_cmd_merchant_pay_order ("pay-fail-partial-double-10",
   1694                                           merchant_url,
   1695                                           MHD_HTTP_CONFLICT,
   1696                                           "create-proposal-10",
   1697                                           "withdraw-coin-10a;withdraw-coin-1",
   1698                                           "EUR:5",
   1699                                           "EUR:4.99",
   1700                                           NULL),
   1701     TALER_TESTING_cmd_merchant_pay_order ("pay-again-10",
   1702                                           merchant_url,
   1703                                           MHD_HTTP_OK,
   1704                                           "create-proposal-10",
   1705                                           "withdraw-coin-10a;withdraw-coin-10b",
   1706                                           "EUR:5",
   1707                                           "EUR:4.99",
   1708                                           NULL),
   1709     TALER_TESTING_cmd_merchant_pay_order ("pay-too-much-10",
   1710                                           merchant_url,
   1711                                           MHD_HTTP_CONFLICT,
   1712                                           "create-proposal-10",
   1713                                           "withdraw-coin-10c;withdraw-coin-10d",
   1714                                           "EUR:5",
   1715                                           "EUR:4.99",
   1716                                           NULL),
   1717     TALER_TESTING_cmd_sleep (
   1718       "Wait for wire transfer deadline",
   1719       3),
   1720     CMD_EXEC_AGGREGATOR ("run-aggregator-10"),
   1721     TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-9.97-10",
   1722                                            EXCHANGE_URL,
   1723                                            "EUR:9.97",
   1724                                            exchange_payto,
   1725                                            merchant_payto),
   1726     TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-10"),
   1727     TALER_TESTING_cmd_end ()
   1728   };
   1729 
   1730   struct TALER_TESTING_Command pay_abort[] = {
   1731     cmd_transfer_to_exchange ("create-reserve-11",
   1732                               "EUR:10.02"),
   1733     cmd_exec_wirewatch ("wirewatch-11"),
   1734     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-11",
   1735                                                  "EUR:10.02",
   1736                                                  payer_payto,
   1737                                                  exchange_payto,
   1738                                                  "create-reserve-11"),
   1739     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-11a",
   1740                                        "create-reserve-11",
   1741                                        "EUR:5",
   1742                                        0,
   1743                                        MHD_HTTP_OK),
   1744     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-11b",
   1745                                        "create-reserve-11",
   1746                                        "EUR:5",
   1747                                        0,
   1748                                        MHD_HTTP_OK),
   1749     TALER_TESTING_cmd_status ("withdraw-status-11",
   1750                               "create-reserve-11",
   1751                               "EUR:0",
   1752                               MHD_HTTP_OK),
   1753     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-11",
   1754                                             cred.cfg,
   1755                                             merchant_url,
   1756                                             MHD_HTTP_OK,
   1757                                             "11",
   1758                                             GNUNET_TIME_UNIT_ZERO_TS,
   1759                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1760                                             "EUR:10.0"),
   1761     TALER_TESTING_cmd_merchant_pay_order ("pay-fail-partial-double-11-good",
   1762                                           merchant_url,
   1763                                           MHD_HTTP_BAD_REQUEST,
   1764                                           "create-proposal-11",
   1765                                           "withdraw-coin-11a",
   1766                                           "EUR:5",
   1767                                           "EUR:4.99",
   1768                                           NULL),
   1769     TALER_TESTING_cmd_merchant_pay_order ("pay-fail-partial-double-11-bad",
   1770                                           merchant_url,
   1771                                           MHD_HTTP_CONFLICT,
   1772                                           "create-proposal-11",
   1773                                           "withdraw-coin-1",
   1774                                           "EUR:5",
   1775                                           "EUR:4.99",
   1776                                           NULL),
   1777     TALER_TESTING_cmd_merchant_order_abort ("pay-abort-11",
   1778                                             merchant_url,
   1779                                             "pay-fail-partial-double-11-good",
   1780                                             MHD_HTTP_OK),
   1781     TALER_TESTING_cmd_sleep (
   1782       "Wait for wire transfer deadline",
   1783       3),
   1784     CMD_EXEC_AGGREGATOR ("run-aggregator-11"),
   1785     TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-11"),
   1786     TALER_TESTING_cmd_end ()
   1787   };
   1788 
   1789   struct TALER_TESTING_Command templates[] = {
   1790     cmd_transfer_to_exchange ("create-reserve-20x",
   1791                               "EUR:20.04"),
   1792     cmd_exec_wirewatch ("wirewatch-20x"),
   1793     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-20x",
   1794                                                  "EUR:20.04",
   1795                                                  payer_payto,
   1796                                                  exchange_payto,
   1797                                                  "create-reserve-20x"),
   1798     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xa",
   1799                                        "create-reserve-20x",
   1800                                        "EUR:5",
   1801                                        0,
   1802                                        MHD_HTTP_OK),
   1803     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xb",
   1804                                        "create-reserve-20x",
   1805                                        "EUR:5",
   1806                                        0,
   1807                                        MHD_HTTP_OK),
   1808     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xc",
   1809                                        "create-reserve-20x",
   1810                                        "EUR:5",
   1811                                        0,
   1812                                        MHD_HTTP_OK),
   1813     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xd",
   1814                                        "create-reserve-20x",
   1815                                        "EUR:5",
   1816                                        0,
   1817                                        MHD_HTTP_OK),
   1818     TALER_TESTING_cmd_status ("withdraw-status-20x",
   1819                               "create-reserve-20x",
   1820                               "EUR:0",
   1821                               MHD_HTTP_OK),
   1822     TALER_TESTING_cmd_merchant_get_templates ("get-templates-empty",
   1823                                               merchant_url,
   1824                                               MHD_HTTP_OK,
   1825                                               NULL),
   1826     TALER_TESTING_cmd_merchant_post_templates ("post-templates-t1",
   1827                                                merchant_url,
   1828                                                "template-1",
   1829                                                "a template",
   1830                                                MHD_HTTP_NO_CONTENT),
   1831     TALER_TESTING_cmd_merchant_post_templates ("post-templates-t1-idem",
   1832                                                merchant_url,
   1833                                                "template-1",
   1834                                                "a template",
   1835                                                MHD_HTTP_NO_CONTENT),
   1836     TALER_TESTING_cmd_merchant_post_templates ("post-templates-t1-non-idem",
   1837                                                merchant_url,
   1838                                                "template-1",
   1839                                                "a different template",
   1840                                                MHD_HTTP_CONFLICT),
   1841     TALER_TESTING_cmd_merchant_get_templates ("get-templates-t1",
   1842                                               merchant_url,
   1843                                               MHD_HTTP_OK,
   1844                                               "post-templates-t1",
   1845                                               NULL),
   1846     TALER_TESTING_cmd_merchant_get_template ("get-template-t1",
   1847                                              merchant_url,
   1848                                              "template-1",
   1849                                              MHD_HTTP_OK,
   1850                                              "post-templates-t1"),
   1851     TALER_TESTING_cmd_merchant_wallet_get_template (
   1852       "wallet-get-template-fixed",
   1853       merchant_url,
   1854       "template-1",
   1855       0,
   1856       NULL,
   1857       NULL,
   1858       false,
   1859       0,
   1860       NULL,
   1861       NULL,
   1862       NULL,
   1863       0,
   1864       0,
   1865       EXCHANGE_URL,
   1866       "x-taler-bank",
   1867       MHD_HTTP_OK),
   1868     TALER_TESTING_cmd_merchant_post_templates2 (
   1869       "post-templates-pay-forever",
   1870       merchant_url,
   1871       "template-pay-forever",
   1872       "template with an invalid infinite pay duration",
   1873       NULL,
   1874       GNUNET_JSON_PACK (
   1875         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1876         GNUNET_JSON_pack_time_rel ("pay_duration",
   1877                                    GNUNET_TIME_UNIT_FOREVER_REL)),
   1878       MHD_HTTP_BAD_REQUEST),
   1879     TALER_TESTING_cmd_merchant_post_templates ("post-templates-t2",
   1880                                                merchant_url,
   1881                                                "template-2",
   1882                                                "a template",
   1883                                                MHD_HTTP_NO_CONTENT),
   1884     TALER_TESTING_cmd_merchant_patch_template (
   1885       "patch-templates-t2",
   1886       merchant_url,
   1887       "template-2",
   1888       "another template",
   1889       NULL,
   1890       GNUNET_JSON_PACK (
   1891         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1892         GNUNET_JSON_pack_time_rel ("pay_duration",
   1893                                    GNUNET_TIME_UNIT_MINUTES)),
   1894       MHD_HTTP_NO_CONTENT),
   1895     TALER_TESTING_cmd_merchant_get_template ("get-template-t2",
   1896                                              merchant_url,
   1897                                              "template-2",
   1898                                              MHD_HTTP_OK,
   1899                                              "patch-templates-t2"),
   1900     TALER_TESTING_cmd_merchant_patch_template (
   1901       "patch-templates-t2-pay-forever",
   1902       merchant_url,
   1903       "template-2",
   1904       "template with an invalid infinite pay duration",
   1905       NULL,
   1906       GNUNET_JSON_PACK (
   1907         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1908         GNUNET_JSON_pack_time_rel ("pay_duration",
   1909                                    GNUNET_TIME_UNIT_FOREVER_REL)),
   1910       MHD_HTTP_BAD_REQUEST),
   1911     TALER_TESTING_cmd_merchant_get_template (
   1912       "get-template-t2-after-pay-forever",
   1913       merchant_url,
   1914       "template-2",
   1915       MHD_HTTP_OK,
   1916       "patch-templates-t2"),
   1917     TALER_TESTING_cmd_merchant_get_template ("get-template-nx",
   1918                                              merchant_url,
   1919                                              "template-nx",
   1920                                              MHD_HTTP_NOT_FOUND,
   1921                                              NULL),
   1922     TALER_TESTING_cmd_merchant_post_otp_devices (
   1923       "post-otp-device",
   1924       merchant_url,
   1925       "otp-dev",
   1926       "my OTP device",
   1927       "FEE4P2J",
   1928       TALER_MCA_WITH_PRICE,
   1929       0,
   1930       MHD_HTTP_NO_CONTENT),
   1931     TALER_TESTING_cmd_merchant_patch_template (
   1932       "patch-templates-t3-nx",
   1933       merchant_url,
   1934       "template-3",
   1935       "updated template",
   1936       "otp-dev",
   1937       GNUNET_JSON_PACK (
   1938         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1939         GNUNET_JSON_pack_time_rel ("pay_duration",
   1940                                    GNUNET_TIME_UNIT_MINUTES)),
   1941       MHD_HTTP_NOT_FOUND),
   1942     /* Bind template-2 to an existing OTP device ... */
   1943     TALER_TESTING_cmd_merchant_patch_template (
   1944       "patch-templates-t2-otp",
   1945       merchant_url,
   1946       "template-2",
   1947       "a template with an OTP device",
   1948       "otp-dev",
   1949       GNUNET_JSON_PACK (
   1950         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1951         GNUNET_JSON_pack_time_rel ("pay_duration",
   1952                                    GNUNET_TIME_UNIT_MINUTES)),
   1953       MHD_HTTP_NO_CONTENT),
   1954     /* ... a PATCH naming an unknown OTP device must be refused
   1955        with 404 and must NOT clear the existing binding (#5) */
   1956     TALER_TESTING_cmd_merchant_patch_template (
   1957       "patch-templates-t2-otp-nx",
   1958       merchant_url,
   1959       "template-2",
   1960       "a template that must not be stored",
   1961       "otp-dev-nx",
   1962       GNUNET_JSON_PACK (
   1963         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1964         GNUNET_JSON_pack_time_rel ("pay_duration",
   1965                                    GNUNET_TIME_UNIT_MINUTES)),
   1966       MHD_HTTP_NOT_FOUND),
   1967     /* ... hence the template must still match the successful PATCH */
   1968     TALER_TESTING_cmd_merchant_get_template ("get-template-t2-otp",
   1969                                              merchant_url,
   1970                                              "template-2",
   1971                                              MHD_HTTP_OK,
   1972                                              "patch-templates-t2-otp"),
   1973     TALER_TESTING_cmd_merchant_post_templates2 (
   1974       "post-templates-t3-amount",
   1975       merchant_url,
   1976       "template-amount",
   1977       "a different template with an amount",
   1978       NULL,
   1979       GNUNET_JSON_PACK (
   1980         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1981         GNUNET_JSON_pack_time_rel ("pay_duration",
   1982                                    GNUNET_TIME_UNIT_MINUTES),
   1983         GNUNET_JSON_pack_string ("amount",
   1984                                  "EUR:4")),
   1985       MHD_HTTP_NO_CONTENT),
   1986     TALER_TESTING_cmd_merchant_post_templates2 (
   1987       "post-templates-pay-default-omitted",
   1988       merchant_url,
   1989       "template-pay-default-omitted",
   1990       "template without a pay duration",
   1991       NULL,
   1992       GNUNET_JSON_PACK (
   1993         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1994         GNUNET_JSON_pack_string ("summary",
   1995                                  "use the instance pay delay"),
   1996         GNUNET_JSON_pack_string ("amount",
   1997                                  "EUR:1")),
   1998       MHD_HTTP_NO_CONTENT),
   1999     TALER_TESTING_cmd_merchant_post_using_templates_with_expected_pay_duration (
   2000       "using-templates-pay-default-omitted",
   2001       "post-templates-pay-default-omitted",
   2002       NULL,
   2003       merchant_url,
   2004       "pay-default-omitted",
   2005       NULL,
   2006       NULL,
   2007       GNUNET_TIME_UNIT_ZERO_TS,
   2008       GNUNET_TIME_UNIT_FOREVER_TS,
   2009       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
   2010                                      2),
   2011       MHD_HTTP_OK),
   2012     TALER_TESTING_cmd_merchant_post_templates2 (
   2013       "post-templates-pay-default-zero",
   2014       merchant_url,
   2015       "template-pay-default-zero",
   2016       "template with a zero pay duration",
   2017       NULL,
   2018       GNUNET_JSON_PACK (
   2019         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   2020         GNUNET_JSON_pack_time_rel ("pay_duration",
   2021                                    GNUNET_TIME_UNIT_ZERO),
   2022         GNUNET_JSON_pack_string ("summary",
   2023                                  "use the instance pay delay"),
   2024         GNUNET_JSON_pack_string ("amount",
   2025                                  "EUR:1")),
   2026       MHD_HTTP_NO_CONTENT),
   2027     TALER_TESTING_cmd_merchant_post_using_templates_with_expected_pay_duration (
   2028       "using-templates-pay-default-zero",
   2029       "post-templates-pay-default-zero",
   2030       NULL,
   2031       merchant_url,
   2032       "pay-default-zero",
   2033       NULL,
   2034       NULL,
   2035       GNUNET_TIME_UNIT_ZERO_TS,
   2036       GNUNET_TIME_UNIT_FOREVER_TS,
   2037       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
   2038                                      2),
   2039       MHD_HTTP_OK),
   2040     TALER_TESTING_cmd_merchant_post_using_templates (
   2041       "using-templates-t1",
   2042       "post-templates-t1",
   2043       NULL,
   2044       merchant_url,
   2045       "1",
   2046       "summary-1",
   2047       "EUR:9.98",
   2048       GNUNET_TIME_UNIT_ZERO_TS,
   2049       GNUNET_TIME_UNIT_FOREVER_TS,
   2050       MHD_HTTP_OK),
   2051     TALER_TESTING_cmd_merchant_post_using_templates (
   2052       "using-templates-t1-amount-missing",
   2053       "post-templates-t1",
   2054       NULL,
   2055       merchant_url,
   2056       "2",
   2057       "summary-1",
   2058       NULL,
   2059       GNUNET_TIME_UNIT_ZERO_TS,
   2060       GNUNET_TIME_UNIT_FOREVER_TS,
   2061       MHD_HTTP_CONFLICT),
   2062     TALER_TESTING_cmd_merchant_post_using_templates (
   2063       "using-templates-t1-summary-missing",
   2064       "post-templates-t1",
   2065       NULL,
   2066       merchant_url,
   2067       "3",
   2068       NULL,
   2069       "EUR:10",
   2070       GNUNET_TIME_UNIT_ZERO_TS,
   2071       GNUNET_TIME_UNIT_FOREVER_TS,
   2072       MHD_HTTP_CONFLICT),
   2073     TALER_TESTING_cmd_merchant_post_using_templates (
   2074       "using-templates-t1-amount-conflict",
   2075       "post-templates-t3-amount",
   2076       NULL,
   2077       merchant_url,
   2078       "4",
   2079       "summary-1",
   2080       "EUR:10",
   2081       GNUNET_TIME_UNIT_ZERO_TS,
   2082       GNUNET_TIME_UNIT_FOREVER_TS,
   2083       MHD_HTTP_CONFLICT),
   2084     TALER_TESTING_cmd_merchant_post_using_templates (
   2085       "using-templates-t1-amount-duplicate",
   2086       "post-templates-t3-amount",
   2087       NULL,
   2088       merchant_url,
   2089       "4",
   2090       "summary-1",
   2091       "EUR:4",
   2092       GNUNET_TIME_UNIT_ZERO_TS,
   2093       GNUNET_TIME_UNIT_FOREVER_TS,
   2094       MHD_HTTP_CONFLICT),
   2095     TALER_TESTING_cmd_merchant_pay_order ("pay-100",
   2096                                           merchant_url,
   2097                                           MHD_HTTP_OK,
   2098                                           "using-templates-t1",
   2099                                           "withdraw-coin-xa;withdraw-coin-xb",
   2100                                           "EUR:4.99",
   2101                                           "EUR:4.99",
   2102                                           NULL),
   2103     TALER_TESTING_cmd_merchant_delete_template ("get-templates-empty",
   2104                                                 merchant_url,
   2105                                                 "t1",
   2106                                                 MHD_HTTP_NOT_FOUND),
   2107     TALER_TESTING_cmd_merchant_delete_template ("get-templates-empty",
   2108                                                 merchant_url,
   2109                                                 "template-1",
   2110                                                 MHD_HTTP_NO_CONTENT),
   2111     TALER_TESTING_cmd_merchant_post_using_templates (
   2112       "post-templates-t1-deleted",
   2113       "post-templates-t1",
   2114       NULL,
   2115       merchant_url,
   2116       "0",
   2117       "summary-1",
   2118       "EUR:5",
   2119       GNUNET_TIME_UNIT_ZERO_TS,
   2120       GNUNET_TIME_UNIT_FOREVER_TS,
   2121       MHD_HTTP_NOT_FOUND),
   2122     TALER_TESTING_cmd_merchant_post_otp_devices (
   2123       "post-otp-device",
   2124       merchant_url,
   2125       "otp-dev-2",
   2126       "my OTP device",
   2127       "secret",
   2128       TALER_MCA_WITH_PRICE,
   2129       0,
   2130       MHD_HTTP_NO_CONTENT),
   2131     TALER_TESTING_cmd_merchant_post_templates2 (
   2132       "post-templates-with-pos-key",
   2133       merchant_url,
   2134       "template-key",
   2135       "a different template with POS KEY",
   2136       "otp-dev-2",
   2137       GNUNET_JSON_PACK (
   2138         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   2139         GNUNET_JSON_pack_time_rel ("pay_duration",
   2140                                    GNUNET_TIME_UNIT_MINUTES)),
   2141       MHD_HTTP_NO_CONTENT),
   2142 
   2143     TALER_TESTING_cmd_merchant_post_using_templates (
   2144       "using-templates-pos-key",
   2145       "post-templates-with-pos-key",
   2146       "post-otp-device",
   2147       merchant_url,
   2148       "1",
   2149       "summary-1-pos",
   2150       "EUR:9.98",
   2151       GNUNET_TIME_UNIT_ZERO_TS,
   2152       GNUNET_TIME_UNIT_FOREVER_TS,
   2153       MHD_HTTP_OK),
   2154     TALER_TESTING_cmd_merchant_pay_order ("pay-with-pos",
   2155                                           merchant_url,
   2156                                           MHD_HTTP_OK,
   2157                                           "using-templates-pos-key",
   2158                                           "withdraw-coin-xc;withdraw-coin-xd",
   2159                                           "EUR:4.99",
   2160                                           "EUR:4.99",
   2161                                           NULL),
   2162     cmd_transfer_to_exchange ("create-reserve-20y",
   2163                               "EUR:10.02"),
   2164     cmd_exec_wirewatch ("wirewatch-20y"),
   2165     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-20y",
   2166                                                  "EUR:10.02",
   2167                                                  payer_payto,
   2168                                                  exchange_payto,
   2169                                                  "create-reserve-20y"),
   2170     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-yk",
   2171                                        "create-reserve-20y",
   2172                                        "EUR:5",
   2173                                        0,
   2174                                        MHD_HTTP_OK),
   2175     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-ykb",
   2176                                        "create-reserve-20y",
   2177                                        "EUR:5",
   2178                                        0,
   2179                                        MHD_HTTP_OK),
   2180     TALER_TESTING_cmd_status ("withdraw-status-20y",
   2181                               "create-reserve-20y",
   2182                               "EUR:0",
   2183                               MHD_HTTP_OK),
   2184     TALER_TESTING_cmd_merchant_post_products_with_unit_prices (
   2185       "post-products-inv-1",
   2186       merchant_url,
   2187       "inv-product-1",
   2188       "Inventory Product One",
   2189       "test-unit",
   2190       (const char *[]) { "EUR:1", "KUDOS:1" },
   2191       2,
   2192       MHD_HTTP_NO_CONTENT),
   2193     TALER_TESTING_cmd_merchant_post_products_with_unit_prices (
   2194       "post-products-inv-2",
   2195       merchant_url,
   2196       "inv-product-2",
   2197       "Inventory Product Two",
   2198       "test-unit",
   2199       (const char *[]) { "EUR:2", "KUDOS:2" },
   2200       2,
   2201       MHD_HTTP_NO_CONTENT),
   2202     TALER_TESTING_cmd_merchant_post_templates2 (
   2203       "post-templates-inv-one",
   2204       merchant_url,
   2205       "template-inv-one",
   2206       "inventory template one",
   2207       NULL,
   2208       GNUNET_JSON_PACK (
   2209         GNUNET_JSON_pack_string ("template_type",
   2210                                  "inventory-cart"),
   2211         GNUNET_JSON_pack_string ("summary",
   2212                                  "inventory template"),
   2213         GNUNET_JSON_pack_time_rel ("pay_duration",
   2214                                    GNUNET_TIME_UNIT_MINUTES),
   2215         GNUNET_JSON_pack_array_steal (
   2216           "selected_products",
   2217           make_selected_products ("inv-product-1",
   2218                                   "inv-product-2")),
   2219         GNUNET_JSON_pack_bool ("choose_one",
   2220                                true)),
   2221       MHD_HTTP_NO_CONTENT),
   2222     TALER_TESTING_cmd_merchant_wallet_get_template (
   2223       "wallet-get-template-inv-one",
   2224       merchant_url,
   2225       "template-inv-one",
   2226       0,
   2227       NULL,
   2228       NULL,
   2229       false,
   2230       0,
   2231       NULL,
   2232       NULL,
   2233       NULL,
   2234       0,
   2235       0,
   2236       EXCHANGE_URL,
   2237       "x-taler-bank",
   2238       MHD_HTTP_OK),
   2239     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2240       "using-templates-inv-one",
   2241       "post-templates-inv-one",
   2242       NULL,
   2243       merchant_url,
   2244       "inv-1",
   2245       GNUNET_JSON_PACK (
   2246         GNUNET_JSON_pack_string ("amount",
   2247                                  "EUR:1"),
   2248         GNUNET_JSON_pack_string ("template_type",
   2249                                  "inventory-cart"),
   2250         GNUNET_JSON_pack_array_steal (
   2251           "inventory_selection",
   2252           make_inventory_selection ("inv-product-1",
   2253                                     "1.0",
   2254                                     NULL,
   2255                                     NULL))),
   2256       MHD_HTTP_OK),
   2257     TALER_TESTING_cmd_merchant_post_templates2 (
   2258       "post-templates-inv-multi",
   2259       merchant_url,
   2260       "template-inv-multi",
   2261       "inventory template multi",
   2262       NULL,
   2263       GNUNET_JSON_PACK (
   2264         GNUNET_JSON_pack_string ("template_type",
   2265                                  "inventory-cart"),
   2266         GNUNET_JSON_pack_string ("summary",
   2267                                  "inventory template multi"),
   2268         GNUNET_JSON_pack_time_rel ("pay_duration",
   2269                                    GNUNET_TIME_UNIT_MINUTES),
   2270         GNUNET_JSON_pack_array_steal (
   2271           "selected_products",
   2272           make_selected_products ("inv-product-1",
   2273                                   "inv-product-2"))),
   2274       MHD_HTTP_NO_CONTENT),
   2275     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2276       "using-templates-inv-multi",
   2277       "post-templates-inv-multi",
   2278       NULL,
   2279       merchant_url,
   2280       "inv-2",
   2281       GNUNET_JSON_PACK (
   2282         GNUNET_JSON_pack_string ("amount",
   2283                                  "EUR:3"),
   2284         GNUNET_JSON_pack_string ("template_type",
   2285                                  "inventory-cart"),
   2286         GNUNET_JSON_pack_array_steal (
   2287           "inventory_selection",
   2288           make_inventory_selection ("inv-product-1",
   2289                                     "1.0",
   2290                                     "inv-product-2",
   2291                                     "1.0"))),
   2292       MHD_HTTP_OK),
   2293     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2294       "using-templates-inv-one-empty",
   2295       "post-templates-inv-one",
   2296       NULL,
   2297       merchant_url,
   2298       "inv-1-empty",
   2299       GNUNET_JSON_PACK (
   2300         GNUNET_JSON_pack_string ("amount",
   2301                                  "EUR:1"),
   2302         GNUNET_JSON_pack_string ("template_type",
   2303                                  "inventory-cart"),
   2304         GNUNET_JSON_pack_array_steal (
   2305           "inventory_selection",
   2306           json_array ())),
   2307       MHD_HTTP_CONFLICT),
   2308     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2309       "using-templates-inv-one-two",
   2310       "post-templates-inv-one",
   2311       NULL,
   2312       merchant_url,
   2313       "inv-1-two",
   2314       GNUNET_JSON_PACK (
   2315         GNUNET_JSON_pack_string ("amount",
   2316                                  "EUR:3"),
   2317         GNUNET_JSON_pack_string ("template_type",
   2318                                  "inventory-cart"),
   2319         GNUNET_JSON_pack_array_steal (
   2320           "inventory_selection",
   2321           make_inventory_selection ("inv-product-1",
   2322                                     "1.0",
   2323                                     "inv-product-2",
   2324                                     "1.0"))),
   2325       MHD_HTTP_CONFLICT),
   2326     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2327       "using-templates-inv-one-tip",
   2328       "post-templates-inv-one",
   2329       NULL,
   2330       merchant_url,
   2331       "inv-1-tip",
   2332       GNUNET_JSON_PACK (
   2333         GNUNET_JSON_pack_string ("amount",
   2334                                  "EUR:1"),
   2335         GNUNET_JSON_pack_string ("tip",
   2336                                  "EUR:1"),
   2337         GNUNET_JSON_pack_string ("template_type",
   2338                                  "inventory-cart"),
   2339         GNUNET_JSON_pack_array_steal (
   2340           "inventory_selection",
   2341           make_inventory_selection ("inv-product-1",
   2342                                     "1.0",
   2343                                     NULL,
   2344                                     NULL))),
   2345       MHD_HTTP_CONFLICT),
   2346     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2347       "using-templates-inv-one-tip-ok",
   2348       "post-templates-inv-one",
   2349       NULL,
   2350       merchant_url,
   2351       "inv-1-tip-ok",
   2352       GNUNET_JSON_PACK (
   2353         GNUNET_JSON_pack_string ("amount",
   2354                                  "EUR:2"),
   2355         GNUNET_JSON_pack_string ("tip",
   2356                                  "EUR:1"),
   2357         GNUNET_JSON_pack_string ("template_type",
   2358                                  "inventory-cart"),
   2359         GNUNET_JSON_pack_array_steal (
   2360           "inventory_selection",
   2361           make_inventory_selection ("inv-product-1",
   2362                                     "1.0",
   2363                                     NULL,
   2364                                     NULL))),
   2365       MHD_HTTP_OK),
   2366     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2367       "using-templates-inv-one-unknown",
   2368       "post-templates-inv-one",
   2369       NULL,
   2370       merchant_url,
   2371       "inv-1-unknown",
   2372       GNUNET_JSON_PACK (
   2373         GNUNET_JSON_pack_string ("amount",
   2374                                  "EUR:1"),
   2375         GNUNET_JSON_pack_string ("template_type",
   2376                                  "inventory-cart"),
   2377         GNUNET_JSON_pack_array_steal (
   2378           "inventory_selection",
   2379           make_inventory_selection ("inv-product-404",
   2380                                     "1.0",
   2381                                     NULL,
   2382                                     NULL))),
   2383       MHD_HTTP_NOT_FOUND),
   2384     TALER_TESTING_cmd_merchant_post_templates2 (
   2385       "post-templates-inv-only",
   2386       merchant_url,
   2387       "template-inv-only",
   2388       "inventory template only",
   2389       NULL,
   2390       GNUNET_JSON_PACK (
   2391         GNUNET_JSON_pack_string ("template_type",
   2392                                  "inventory-cart"),
   2393         GNUNET_JSON_pack_string ("summary",
   2394                                  "inventory template only"),
   2395         GNUNET_JSON_pack_time_rel ("pay_duration",
   2396                                    GNUNET_TIME_UNIT_MINUTES),
   2397         GNUNET_JSON_pack_array_steal (
   2398           "selected_products",
   2399           make_selected_products ("inv-product-1",
   2400                                   NULL))),
   2401       MHD_HTTP_NO_CONTENT),
   2402     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2403       "using-templates-inv-only-wrong",
   2404       "post-templates-inv-only",
   2405       NULL,
   2406       merchant_url,
   2407       "inv-only-wrong",
   2408       GNUNET_JSON_PACK (
   2409         GNUNET_JSON_pack_string ("amount",
   2410                                  "EUR:2"),
   2411         GNUNET_JSON_pack_string ("template_type",
   2412                                  "inventory-cart"),
   2413         GNUNET_JSON_pack_array_steal (
   2414           "inventory_selection",
   2415           make_inventory_selection ("inv-product-2",
   2416                                     "1.0",
   2417                                     NULL,
   2418                                     NULL))),
   2419       MHD_HTTP_CONFLICT),
   2420     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2421       "using-templates-inv-multi-amount-mismatch",
   2422       "post-templates-inv-multi",
   2423       NULL,
   2424       merchant_url,
   2425       "inv-2-mismatch",
   2426       GNUNET_JSON_PACK (
   2427         GNUNET_JSON_pack_string ("amount",
   2428                                  "EUR:4"),
   2429         GNUNET_JSON_pack_string ("template_type",
   2430                                  "inventory-cart"),
   2431         GNUNET_JSON_pack_array_steal (
   2432           "inventory_selection",
   2433           make_inventory_selection ("inv-product-1",
   2434                                     "1.0",
   2435                                     "inv-product-2",
   2436                                     "1.0"))),
   2437       MHD_HTTP_CONFLICT),
   2438     TALER_TESTING_cmd_merchant_post_units ("post-unit-special",
   2439                                            merchant_url,
   2440                                            "special-unit",
   2441                                            "Special Unit",
   2442                                            "sunit",
   2443                                            true,
   2444                                            1,
   2445                                            true,
   2446                                            json_pack ("{s:s}",
   2447                                                       "en",
   2448                                                       "Special Unit"),
   2449                                            json_pack ("{s:s}",
   2450                                                       "en",
   2451                                                       "sunit"),
   2452                                            MHD_HTTP_NO_CONTENT),
   2453     TALER_TESTING_cmd_merchant_post_categories ("post-category-special",
   2454                                                 merchant_url,
   2455                                                 "Category Special",
   2456                                                 json_pack ("{s:s}",
   2457                                                            "en",
   2458                                                            "Category Special"),
   2459                                                 1,
   2460                                                 MHD_HTTP_OK),
   2461     TALER_TESTING_cmd_merchant_post_categories ("post-category-special-2",
   2462                                                 merchant_url,
   2463                                                 "Category Special Two",
   2464                                                 json_pack ("{s:s}",
   2465                                                            "en",
   2466                                                            "Category Special Two"),
   2467                                                 2,
   2468                                                 MHD_HTTP_OK),
   2469     TALER_TESTING_cmd_merchant_post_products_with_categories (
   2470       "post-products-inv-unit-1",
   2471       merchant_url,
   2472       "inv-unit-product-1",
   2473       "Inventory Unit Product One",
   2474       "special-unit",
   2475       "EUR:5",
   2476       1,
   2477       (const uint64_t[]) { 1 },
   2478       true,
   2479       1,
   2480       MHD_HTTP_NO_CONTENT),
   2481     TALER_TESTING_cmd_merchant_post_products2 (
   2482       "post-products-inv-unit-2",
   2483       merchant_url,
   2484       "inv-unit-product-2",
   2485       "Inventory Unit Product Two",
   2486       json_pack ("{s:s}", "en", "Inventory Unit Product Two"),
   2487       "test-unit",
   2488       "EUR:1.2",
   2489       "",
   2490       json_array (),
   2491       -1, /* total stock: infinite */
   2492       0,  /* minimum age */
   2493       json_pack ("{s:s}", "street", "my street"),
   2494       GNUNET_TIME_UNIT_ZERO_TS,
   2495       MHD_HTTP_NO_CONTENT),
   2496     TALER_TESTING_cmd_merchant_post_products_with_categories (
   2497       "post-products-inv-unit-3",
   2498       merchant_url,
   2499       "inv-unit-product-3",
   2500       "Inventory Unit Product Three",
   2501       "test-unit",
   2502       "EUR:9",
   2503       1,
   2504       (const uint64_t[]) { 2 },
   2505       false,
   2506       0,
   2507       MHD_HTTP_NO_CONTENT),
   2508     TALER_TESTING_cmd_merchant_post_templates2 (
   2509       "post-templates-inv-cat-prod-unit",
   2510       merchant_url,
   2511       "template-inv-cat-prod-unit",
   2512       "inventory template category+product unit",
   2513       NULL,
   2514       GNUNET_JSON_PACK (
   2515         GNUNET_JSON_pack_string ("template_type",
   2516                                  "inventory-cart"),
   2517         GNUNET_JSON_pack_string ("summary",
   2518                                  "inventory template category+product unit"),
   2519         GNUNET_JSON_pack_time_rel ("pay_duration",
   2520                                    GNUNET_TIME_UNIT_MINUTES),
   2521         GNUNET_JSON_pack_array_steal (
   2522           "selected_categories",
   2523           make_selected_categories (1,
   2524                                     0)),
   2525         GNUNET_JSON_pack_array_steal (
   2526           "selected_products",
   2527           make_selected_products ("inv-unit-product-2",
   2528                                   "inv-unit-product-3"))),
   2529       MHD_HTTP_NO_CONTENT),
   2530     TALER_TESTING_cmd_merchant_wallet_get_template (
   2531       "wallet-get-template-inv-cat-prod-unit",
   2532       merchant_url,
   2533       "template-inv-cat-prod-unit",
   2534       3,
   2535       "inv-unit-product-1",
   2536       "special-unit",
   2537       true,
   2538       1,
   2539       json_pack ("{s:s}",
   2540                  "en",
   2541                  "sunit"),
   2542       "inv-unit-product-2",
   2543       "inv-unit-product-3",
   2544       1,
   2545       2,
   2546       EXCHANGE_URL,
   2547       "x-taler-bank",
   2548       MHD_HTTP_OK),
   2549     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2550       "using-templates-inv-cat-prod-unit",
   2551       "post-templates-inv-cat-prod-unit",
   2552       NULL,
   2553       merchant_url,
   2554       "inv-cat-prod-unit",
   2555       GNUNET_JSON_PACK (
   2556         GNUNET_JSON_pack_string ("amount",
   2557                                  "EUR:3.2"),
   2558         GNUNET_JSON_pack_string ("template_type",
   2559                                  "inventory-cart"),
   2560         GNUNET_JSON_pack_array_steal (
   2561           "inventory_selection",
   2562           make_inventory_selection ("inv-unit-product-1",
   2563                                     "0.4",
   2564                                     "inv-unit-product-2",
   2565                                     "1"))),
   2566       MHD_HTTP_OK),
   2567     TALER_TESTING_cmd_merchant_pay_order_choices (
   2568       "pay-inv-cat-prod-unit",
   2569       merchant_url,
   2570       MHD_HTTP_OK,
   2571       "using-templates-inv-cat-prod-unit",
   2572       "withdraw-coin-yk",
   2573       "EUR:3.2",
   2574       "EUR:3.2",
   2575       NULL,
   2576       0,
   2577       NULL),
   2578 
   2579 
   2580     TALER_TESTING_cmd_end ()
   2581   };
   2582 
   2583   struct TALER_TESTING_Command webhooks[] = {
   2584     TALER_TESTING_cmd_merchant_get_webhooks ("get-webhooks-empty",
   2585                                              merchant_url,
   2586                                              MHD_HTTP_OK,
   2587                                              NULL),
   2588     TALER_TESTING_cmd_merchant_post_webhooks ("post-webhooks-w1",
   2589                                               merchant_url,
   2590                                               "webhook-1",
   2591                                               "Paid",
   2592                                               MHD_HTTP_NO_CONTENT),
   2593     TALER_TESTING_cmd_merchant_post_webhooks ("post-webhooks-w1-idem",
   2594                                               merchant_url,
   2595                                               "webhook-1",
   2596                                               "Paid",
   2597                                               MHD_HTTP_NO_CONTENT),
   2598     TALER_TESTING_cmd_merchant_post_webhooks ("post-webhooks-w1-non-idem",
   2599                                               merchant_url,
   2600                                               "webhook-1",
   2601                                               "Refund",
   2602                                               MHD_HTTP_CONFLICT),
   2603     TALER_TESTING_cmd_merchant_get_webhooks ("get-webhooks-w1",
   2604                                              merchant_url,
   2605                                              MHD_HTTP_OK,
   2606                                              "post-webhooks-w1",
   2607                                              NULL),
   2608     TALER_TESTING_cmd_merchant_get_webhook ("get-webhook-w1",
   2609                                             merchant_url,
   2610                                             "webhook-1",
   2611                                             MHD_HTTP_OK,
   2612                                             "post-webhooks-w1"),
   2613     TALER_TESTING_cmd_merchant_post_webhooks ("post-webhooks-w2",
   2614                                               merchant_url,
   2615                                               "webhook-2",
   2616                                               "Paid",
   2617                                               MHD_HTTP_NO_CONTENT),
   2618     TALER_TESTING_cmd_merchant_patch_webhook ("patch-webhooks-w2",
   2619                                               merchant_url,
   2620                                               "webhook-2",
   2621                                               "Refund2",
   2622                                               "http://localhost:38188/",
   2623                                               "POST",
   2624                                               "Authorization:WHWOXZXPLL",
   2625                                               "Amount",
   2626                                               MHD_HTTP_NO_CONTENT),
   2627     TALER_TESTING_cmd_merchant_get_webhook ("get-webhook-w2",
   2628                                             merchant_url,
   2629                                             "webhook-2",
   2630                                             MHD_HTTP_OK,
   2631                                             "patch-webhooks-w2"),
   2632     TALER_TESTING_cmd_merchant_get_webhook ("get-webhook-nx",
   2633                                             merchant_url,
   2634                                             "webhook-nx",
   2635                                             MHD_HTTP_NOT_FOUND,
   2636                                             NULL),
   2637     TALER_TESTING_cmd_merchant_patch_webhook ("patch-webhooks-w3-nx",
   2638                                               merchant_url,
   2639                                               "webhook-3",
   2640                                               "Paid2",
   2641                                               "https://example.com",
   2642                                               "POST",
   2643                                               "Authorization:WHWOXZXPLL",
   2644                                               "Amount",
   2645                                               MHD_HTTP_NOT_FOUND),
   2646     TALER_TESTING_cmd_merchant_delete_webhook ("get-webhooks-empty",
   2647                                                merchant_url,
   2648                                                "w1",
   2649                                                MHD_HTTP_NOT_FOUND),
   2650     TALER_TESTING_cmd_merchant_delete_webhook ("get-webhooks-empty",
   2651                                                merchant_url,
   2652                                                "webhook-1",
   2653                                                MHD_HTTP_NO_CONTENT),
   2654     TALER_TESTING_cmd_end ()
   2655   };
   2656   struct TALER_TESTING_Command inventory_webhooks[] = {
   2657     TALER_TESTING_cmd_testserver (
   2658       "launch-http-server-for-inventory-webhooks",
   2659       12346),
   2660     TALER_TESTING_cmd_merchant_post_webhooks2 (
   2661       "post-webhooks-inventory-added",
   2662       merchant_url,
   2663       "webhook-inventory-added",
   2664       "inventory_added",
   2665       "http://localhost:12346/",
   2666       "POST",
   2667       "Taler-test-header: inventory",
   2668       "inventory-added",
   2669       MHD_HTTP_NO_CONTENT),
   2670     TALER_TESTING_cmd_merchant_post_webhooks2 (
   2671       "post-webhooks-inventory-updated",
   2672       merchant_url,
   2673       "webhook-inventory-updated",
   2674       "inventory_updated",
   2675       "http://localhost:12346/",
   2676       "POST",
   2677       "Taler-test-header: inventory",
   2678       "inventory-updated",
   2679       MHD_HTTP_NO_CONTENT),
   2680     TALER_TESTING_cmd_merchant_post_webhooks2 (
   2681       "post-webhooks-inventory-deleted",
   2682       merchant_url,
   2683       "webhook-inventory-deleted",
   2684       "inventory_deleted",
   2685       "http://localhost:12346/",
   2686       "POST",
   2687       "Taler-test-header: inventory",
   2688       "inventory-deleted",
   2689       MHD_HTTP_NO_CONTENT),
   2690     TALER_TESTING_cmd_merchant_post_products (
   2691       "post-product-inventory-hook",
   2692       merchant_url,
   2693       "product-inventory-hook",
   2694       "webhook inventory product",
   2695       "EUR:1",
   2696       MHD_HTTP_NO_CONTENT),
   2697     cmd_webhook ("pending-webhooks-inventory-added"),
   2698     TALER_TESTING_cmd_checkserver2 (
   2699       "check-inventory-webhook-added",
   2700       "launch-http-server-for-inventory-webhooks",
   2701       0,
   2702       "/",
   2703       "POST",
   2704       NULL,
   2705       "inventory-added"),
   2706     TALER_TESTING_cmd_merchant_patch_product (
   2707       "patch-product-inventory-hook",
   2708       merchant_url,
   2709       "product-inventory-hook",
   2710       "webhook inventory product patched",
   2711       json_object (),
   2712       "unit",
   2713       "EUR:2",
   2714       "",
   2715       json_array (),
   2716       5,
   2717       0,
   2718       json_object (),
   2719       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES),
   2720       MHD_HTTP_NO_CONTENT),
   2721     cmd_webhook ("pending-webhooks-inventory-updated"),
   2722     TALER_TESTING_cmd_checkserver2 (
   2723       "check-inventory-webhook-updated",
   2724       "launch-http-server-for-inventory-webhooks",
   2725       1,
   2726       "/",
   2727       "POST",
   2728       NULL,
   2729       "inventory-updated"),
   2730     TALER_TESTING_cmd_merchant_delete_product (
   2731       "delete-product-inventory-hook",
   2732       merchant_url,
   2733       "product-inventory-hook",
   2734       MHD_HTTP_NO_CONTENT),
   2735     cmd_webhook ("pending-webhooks-inventory-deleted"),
   2736     TALER_TESTING_cmd_checkserver2 (
   2737       "check-inventory-webhook-deleted",
   2738       "launch-http-server-for-inventory-webhooks",
   2739       2,
   2740       "/",
   2741       "POST",
   2742       NULL,
   2743       "inventory-deleted"),
   2744     TALER_TESTING_cmd_end ()
   2745   };
   2746   struct TALER_TESTING_Command repurchase[] = {
   2747     cmd_transfer_to_exchange (
   2748       "create-reserve-30x",
   2749       "EUR:30.06"),
   2750     cmd_exec_wirewatch (
   2751       "wirewatch-30x"),
   2752     TALER_TESTING_cmd_check_bank_admin_transfer (
   2753       "check_bank_transfer-30x",
   2754       "EUR:30.06",
   2755       payer_payto,
   2756       exchange_payto,
   2757       "create-reserve-30x"),
   2758     TALER_TESTING_cmd_withdraw_amount (
   2759       "withdraw-coin-rep",
   2760       "create-reserve-30x",
   2761       "EUR:5",
   2762       0,
   2763       MHD_HTTP_OK),
   2764     TALER_TESTING_cmd_merchant_post_orders3 (
   2765       "post-order-repurchase-original",
   2766       cred.cfg,
   2767       merchant_url,
   2768       MHD_HTTP_OK,
   2769       "repurchase-original",
   2770       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_HOURS),
   2771       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES),
   2772       "https://fulfillment.example.com/",
   2773       "EUR:1.0"),
   2774     TALER_TESTING_cmd_merchant_pay_order (
   2775       "repurchase-pay-first",
   2776       merchant_url,
   2777       MHD_HTTP_OK,
   2778       "post-order-repurchase-original",
   2779       "withdraw-coin-rep",
   2780       "EUR:1.00",
   2781       "EUR:0.99",
   2782       "repurchase-session"),
   2783     TALER_TESTING_cmd_wallet_get_order (
   2784       "repurchase-wallet-check-primary-order",
   2785       merchant_url,
   2786       "post-order-repurchase-original",
   2787       true,
   2788       false,
   2789       false,
   2790       MHD_HTTP_OK),
   2791     TALER_TESTING_cmd_merchant_get_order3 (
   2792       "repurchase-check-primary-payment",
   2793       merchant_url,
   2794       "post-order-repurchase-original",
   2795       TALER_MERCHANT_OSC_PAID,
   2796       "repurchase-session",
   2797       NULL,
   2798       MHD_HTTP_OK),
   2799     TALER_TESTING_cmd_merchant_get_order3 (
   2800       "repurchase-check-primary-payment-bad-binding",
   2801       merchant_url,
   2802       "post-order-repurchase-original",
   2803       TALER_MERCHANT_OSC_CLAIMED, /* someone else has it! */
   2804       "wrong-session",
   2805       NULL,
   2806       MHD_HTTP_OK),
   2807     TALER_TESTING_cmd_merchant_post_orders3 (
   2808       "post-order-repurchase-secondary",
   2809       cred.cfg,
   2810       merchant_url,
   2811       MHD_HTTP_OK,
   2812       "repurchase-secondary",
   2813       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_HOURS),
   2814       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES),
   2815       "https://fulfillment.example.com/",
   2816       "EUR:1.0"),
   2817     TALER_TESTING_cmd_merchant_get_order3 (
   2818       "repurchase-check-secondary-payment",
   2819       merchant_url,
   2820       "post-order-repurchase-secondary",
   2821       TALER_MERCHANT_OSC_UNPAID,
   2822       "repurchase-session",
   2823       NULL,
   2824       MHD_HTTP_OK),
   2825     TALER_TESTING_cmd_merchant_get_order3 (
   2826       "repurchase-check-secondary-payment",
   2827       merchant_url,
   2828       "post-order-repurchase-secondary",
   2829       TALER_MERCHANT_OSC_UNPAID,
   2830       "repurchase-session",
   2831       "post-order-repurchase-original",
   2832       MHD_HTTP_OK),
   2833     TALER_TESTING_cmd_wallet_get_order2 (
   2834       "repurchase-wallet-check-order-secondary",
   2835       merchant_url,
   2836       "post-order-repurchase-secondary",
   2837       "repurchase-session",
   2838       false,
   2839       false,
   2840       false,
   2841       "post-order-repurchase-original",
   2842       MHD_HTTP_PAYMENT_REQUIRED),
   2843     TALER_TESTING_cmd_wallet_get_order2 (
   2844       "repurchase-wallet-check-order-secondary-bad-session",
   2845       merchant_url,
   2846       "post-order-repurchase-secondary",
   2847       "wrong-session",
   2848       false,
   2849       false,
   2850       false,
   2851       NULL,
   2852       MHD_HTTP_PAYMENT_REQUIRED),
   2853     TALER_TESTING_cmd_merchant_order_refund (
   2854       "refund-repurchased",
   2855       merchant_url,
   2856       "refund repurchase",
   2857       "repurchase-original",
   2858       "EUR:1.0",
   2859       MHD_HTTP_OK),
   2860     TALER_TESTING_cmd_wallet_get_order2 (
   2861       "repurchase-wallet-check-primary-order-refunded-no-session",
   2862       merchant_url,
   2863       "post-order-repurchase-original",
   2864       NULL,
   2865       true,
   2866       true,
   2867       true,
   2868       "post-order-repurchase-original",
   2869       MHD_HTTP_OK),
   2870     TALER_TESTING_cmd_wallet_get_order2 (
   2871       "repurchase-wallet-check-primary-order-refunded",
   2872       merchant_url,
   2873       "post-order-repurchase-original",
   2874       "repurchase-session",
   2875       true,
   2876       true,
   2877       true,
   2878       "post-order-repurchase-original",
   2879       MHD_HTTP_OK),
   2880     TALER_TESTING_cmd_merchant_get_order3 (
   2881       "repurchase-check-refunded",
   2882       merchant_url,
   2883       "post-order-repurchase-secondary",
   2884       TALER_MERCHANT_OSC_CLAIMED,
   2885       "repurchase-session",
   2886       NULL,
   2887       MHD_HTTP_OK),
   2888 
   2889     TALER_TESTING_cmd_end ()
   2890   };
   2891 
   2892   struct TALER_TESTING_Command tokens[] = {
   2893     /**
   2894      * Move money to the exchange's bank account.
   2895      */
   2896     cmd_transfer_to_exchange ("create-reserve-tokens",
   2897                               "EUR:20.03"),
   2898     /**
   2899      * Make a reserve exist, according to the previous transfer.
   2900      */
   2901     cmd_exec_wirewatch ("wirewatch-1"),
   2902     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-tokens",
   2903                                                  "EUR:20.03",
   2904                                                  payer_payto,
   2905                                                  exchange_payto,
   2906                                                  "create-reserve-tokens"),
   2907     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1",
   2908                                        "create-reserve-tokens",
   2909                                        "EUR:5",
   2910                                        0,
   2911                                        MHD_HTTP_OK),
   2912     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
   2913                                        "create-reserve-tokens",
   2914                                        "EUR:5",
   2915                                        0,
   2916                                        MHD_HTTP_OK),
   2917     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-3",
   2918                                        "create-reserve-tokens",
   2919                                        "EUR:5",
   2920                                        0,
   2921                                        MHD_HTTP_OK),
   2922     TALER_TESTING_cmd_merchant_post_tokenfamilies (
   2923       "create-upcoming-tokenfamily",
   2924       merchant_url,
   2925       MHD_HTTP_NO_CONTENT,
   2926       "subscription-upcoming",
   2927       "Upcoming Subscription",
   2928       "An upcoming subscription that is not valid yet.",
   2929       NULL,
   2930       /* In one day */
   2931       GNUNET_TIME_absolute_to_timestamp (
   2932         GNUNET_TIME_absolute_add (
   2933           GNUNET_TIME_timestamp_get ().abs_time,
   2934           GNUNET_TIME_UNIT_DAYS)),
   2935       /* In a year */
   2936       GNUNET_TIME_absolute_to_timestamp (
   2937         GNUNET_TIME_absolute_add (
   2938           GNUNET_TIME_timestamp_get ().abs_time,
   2939           GNUNET_TIME_UNIT_YEARS)),
   2940       GNUNET_TIME_UNIT_MONTHS,
   2941       GNUNET_TIME_UNIT_MONTHS,
   2942       "subscription"),
   2943     TALER_TESTING_cmd_merchant_post_orders_choices (
   2944       "create-order-with-upcoming-output",
   2945       cred.cfg,
   2946       merchant_url,
   2947       MHD_HTTP_OK,
   2948       "subscription-upcoming",
   2949       "A choice in the contract",
   2950       NULL,
   2951       0,
   2952       1,
   2953       "5-upcoming-output",
   2954       GNUNET_TIME_UNIT_ZERO_TS,
   2955       GNUNET_TIME_UNIT_FOREVER_TS,
   2956       "EUR:5.0"),
   2957     TALER_TESTING_cmd_merchant_post_tokenfamilies (
   2958       "create-tokenfamily",
   2959       merchant_url,
   2960       MHD_HTTP_NO_CONTENT,
   2961       "subscription-1",
   2962       "Subscription",
   2963       "A subscription.",
   2964       NULL,
   2965       GNUNET_TIME_UNIT_ZERO_TS,
   2966       GNUNET_TIME_relative_to_timestamp (
   2967         GNUNET_TIME_UNIT_YEARS),
   2968       GNUNET_TIME_UNIT_MONTHS,
   2969       GNUNET_TIME_UNIT_MONTHS,
   2970       "subscription"),
   2971     TALER_TESTING_cmd_merchant_post_orders_choices (
   2972       "create-order-with-output",
   2973       cred.cfg,
   2974       merchant_url,
   2975       MHD_HTTP_OK,
   2976       "subscription-1",
   2977       "A choice in the contract",
   2978       NULL,
   2979       0,
   2980       1,
   2981       "5-output",
   2982       GNUNET_TIME_UNIT_ZERO_TS,
   2983       GNUNET_TIME_UNIT_FOREVER_TS,
   2984       "EUR:5.0"),
   2985     TALER_TESTING_cmd_merchant_pay_order_choices (
   2986       "pay-order-with-output",
   2987       merchant_url,
   2988       MHD_HTTP_OK,
   2989       "create-order-with-output",
   2990       "withdraw-coin-1",
   2991       "EUR:5",
   2992       "EUR:4.99",
   2993       NULL,
   2994       0,
   2995       NULL),
   2996     TALER_TESTING_cmd_merchant_post_orders_choices (
   2997       "create-order-with-input-and-output",
   2998       cred.cfg,
   2999       merchant_url,
   3000       MHD_HTTP_OK,
   3001       "subscription-1",
   3002       "A choice in the contract",
   3003       NULL,
   3004       1,
   3005       1,
   3006       "5-input-output",
   3007       GNUNET_TIME_UNIT_ZERO_TS,
   3008       GNUNET_TIME_UNIT_FOREVER_TS,
   3009       "EUR:0.0"),
   3010     TALER_TESTING_cmd_merchant_pay_order_choices (
   3011       "pay-order-with-input-and-output",
   3012       merchant_url,
   3013       MHD_HTTP_OK,
   3014       "create-order-with-input-and-output",
   3015       "",
   3016       "EUR:0",
   3017       "EUR:0",
   3018       NULL,
   3019       0,
   3020       "pay-order-with-output"),
   3021     /* Paying a free v1 order a second time, but naming a different
   3022        choice, must not look like that other choice was completed. */
   3023     TALER_TESTING_cmd_merchant_post_orders_v1 (
   3024       "create-v1-double-pay",
   3025       merchant_url,
   3026       MHD_HTTP_OK,
   3027       "v1-double-pay",
   3028       GNUNET_TIME_UNIT_ZERO_TS,
   3029       GNUNET_TIME_UNIT_FOREVER_TS,
   3030       "[{\"amount\":\"EUR:0\",\"inputs\":[],\"outputs\":[]},"
   3031       " {\"amount\":\"EUR:0\",\"inputs\":[],\"outputs\":[]}]"),
   3032     TALER_TESTING_cmd_merchant_claim_order ("claim-v1-double-pay",
   3033                                             merchant_url,
   3034                                             MHD_HTTP_OK,
   3035                                             "create-v1-double-pay",
   3036                                             NULL),
   3037     TALER_TESTING_cmd_merchant_pay_order_choices (
   3038       "pay-v1-double-choice0",
   3039       merchant_url,
   3040       MHD_HTTP_OK,
   3041       "claim-v1-double-pay",
   3042       "",
   3043       "EUR:0",
   3044       "EUR:0",
   3045       NULL,
   3046       0,
   3047       NULL),
   3048     TALER_TESTING_cmd_merchant_pay_order_choices (
   3049       "pay-v1-double-choice1",
   3050       merchant_url,
   3051       MHD_HTTP_CONFLICT,
   3052       "claim-v1-double-pay",
   3053       "",
   3054       "EUR:0",
   3055       "EUR:0",
   3056       NULL,
   3057       1,
   3058       NULL),
   3059     // TALER_TESTING_cmd_merchant_pay_order_choices ("idempotent-pay-order-with-input-and-output",
   3060     //                                               merchant_url,
   3061     //                                               MHD_HTTP_OK,
   3062     //                                               "create-order-with-input-and-output",
   3063     //                                               "",
   3064     //                                               "EUR:0",
   3065     //                                               "EUR:0",
   3066     //                                               NULL,
   3067     //                                               0,
   3068     //                                               "pay-order-with-output"),
   3069     TALER_TESTING_cmd_merchant_post_orders_choices (
   3070       "create-another-order-with-input-and-output",
   3071       cred.cfg,
   3072       merchant_url,
   3073       MHD_HTTP_OK,
   3074       "subscription-1",
   3075       "A choice in the contract",
   3076       NULL,
   3077       1,
   3078       1,
   3079       "5-input-output-2",
   3080       GNUNET_TIME_UNIT_ZERO_TS,
   3081       GNUNET_TIME_UNIT_FOREVER_TS,
   3082       "EUR:0.0"),
   3083     TALER_TESTING_cmd_merchant_pay_order_choices ("double-spend-token",
   3084                                                   merchant_url,
   3085                                                   MHD_HTTP_CONFLICT,
   3086                                                   "create-another-order-with-input-and-output",
   3087                                                   "",
   3088                                                   "EUR:0",
   3089                                                   "EUR:0",
   3090                                                   NULL,
   3091                                                   0,
   3092                                                   "pay-order-with-output"),
   3093     TALER_TESTING_cmd_end ()
   3094   };
   3095 
   3096   const struct DONAU_BearerToken bearer = {
   3097     .token = NULL
   3098   };
   3099 
   3100   struct TALER_TESTING_Command donau[] = {
   3101     TALER_TESTING_cmd_set_var (
   3102       "donau",
   3103       TALER_TESTING_cmd_get_donau ("get-donau",
   3104                                    cred.cfg,
   3105                                    true /* wait for response */)),
   3106     TALER_TESTING_cmd_charity_post_merchant ("post-charity",
   3107                                              "example",
   3108                                              "https://example.com/",
   3109                                              "EUR:50", // max_per_year
   3110                                              &bearer,
   3111                                              "create-another-order-with-input-and-output",
   3112                                              // reusing the merchant_reference for merchant_pub
   3113                                              MHD_HTTP_CREATED),
   3114     TALER_TESTING_cmd_charity_post_merchant ("post-charity-idempotent",
   3115                                              "example",
   3116                                              "https://example.com/",
   3117                                              "EUR:50", // max_per_year
   3118                                              &bearer,
   3119                                              "create-another-order-with-input-and-output",
   3120                                              // reusing the merchant_reference for merchant_pub
   3121                                              MHD_HTTP_CREATED),
   3122     TALER_TESTING_cmd_merchant_post_donau_instance (
   3123       "post-donau-instance",
   3124       merchant_url,
   3125       "create-another-order-with-input-and-output",
   3126       MHD_HTTP_NO_CONTENT),
   3127     TALER_TESTING_cmd_merchant_post_donau_instance (
   3128       "post-donau-instance-idempotent",
   3129       merchant_url,
   3130       "create-another-order-with-input-and-output",
   3131       MHD_HTTP_NO_CONTENT),
   3132     TALER_TESTING_cmd_merchant_get_donau_instances (
   3133       "get-donau-instances-after-insert",
   3134       merchant_url,
   3135       1,
   3136       MHD_HTTP_OK),
   3137     TALER_TESTING_cmd_exec_donaukeyupdate ("run-merchant-donaukeyupdate",
   3138                                            config_file),
   3139     TALER_TESTING_cmd_merchant_get_donau_instances (
   3140       "get-donau-instance",
   3141       merchant_url,
   3142       1,
   3143       MHD_HTTP_OK),
   3144     TALER_TESTING_cmd_merchant_post_orders_donau (
   3145       "create-donau-order",
   3146       cred.cfg,
   3147       merchant_url,
   3148       MHD_HTTP_OK,
   3149       "donau",
   3150       GNUNET_TIME_UNIT_ZERO_TS,
   3151       GNUNET_TIME_UNIT_FOREVER_TS,
   3152       "EUR:1"),
   3153     TALER_TESTING_cmd_merchant_pay_order_donau (
   3154       "pay-donau-order",
   3155       merchant_url,
   3156       MHD_HTTP_OK,
   3157       "create-donau-order",
   3158       "withdraw-coin-3",
   3159       "EUR:1", /* full amount */
   3160       "EUR:0.99", /* amount without fees */
   3161       "EUR:1", /* donation amount */
   3162       NULL,
   3163       0,
   3164       "post-charity",
   3165       GNUNET_TIME_get_current_year (),
   3166       "7560001010000",
   3167       "1234"
   3168       ),
   3169     TALER_TESTING_cmd_merchant_delete_donau_instance (
   3170       "delete-donau-instance",
   3171       merchant_url,
   3172       1,
   3173       MHD_HTTP_NO_CONTENT),
   3174     TALER_TESTING_cmd_merchant_get_donau_instances (
   3175       "get-donau-instances-after-delete",
   3176       merchant_url,
   3177       0,
   3178       MHD_HTTP_OK),
   3179     TALER_TESTING_cmd_end ()
   3180   };
   3181 
   3182   /* Products with categories.  Runs last, as it adds a category and
   3183      products which would otherwise show up in the category- and
   3184      product-based expectations of the 'templates' batch. */
   3185   struct TALER_TESTING_Command product_categories[] = {
   3186     /* 3rd category: the 'templates' batch already created two. */
   3187     TALER_TESTING_cmd_merchant_post_categories ("post-category-pc",
   3188                                                 merchant_url,
   3189                                                 "Category Products",
   3190                                                 json_pack ("{s:s}",
   3191                                                            "en",
   3192                                                            "Category Products"),
   3193                                                 3,
   3194                                                 MHD_HTTP_OK),
   3195     /* Unknown category must yield 404, not a DB failure (500). */
   3196     TALER_TESTING_cmd_merchant_post_products_with_categories (
   3197       "post-products-pc-cat-nx",
   3198       merchant_url,
   3199       "pc-product-nx",
   3200       "product with unknown category",
   3201       "test-unit",
   3202       "EUR:3",
   3203       1,
   3204       (const uint64_t[]) { 424242 },
   3205       false,
   3206       0,
   3207       MHD_HTTP_NOT_FOUND),
   3208     /* Category serials are positive; 0 is malformed. */
   3209     TALER_TESTING_cmd_merchant_post_products_with_categories (
   3210       "post-products-pc-cat-zero",
   3211       merchant_url,
   3212       "pc-product-zero",
   3213       "product with zero category",
   3214       "test-unit",
   3215       "EUR:3",
   3216       1,
   3217       (const uint64_t[]) { 0 },
   3218       false,
   3219       0,
   3220       MHD_HTTP_BAD_REQUEST),
   3221     TALER_TESTING_cmd_merchant_get_product (
   3222       "get-product-pc-nx",
   3223       merchant_url,
   3224       "pc-product-nx",
   3225       MHD_HTTP_NOT_FOUND,
   3226       NULL),
   3227     TALER_TESTING_cmd_merchant_post_products_with_categories (
   3228       "post-products-pc",
   3229       merchant_url,
   3230       "pc-product",
   3231       "product with category",
   3232       "test-unit",
   3233       "EUR:3",
   3234       1,
   3235       (const uint64_t[]) { 3 },
   3236       false,
   3237       0,
   3238       MHD_HTTP_NO_CONTENT),
   3239     /* Same for PATCH: unknown category must yield 404, not 500.  The
   3240        rejected update must not have been applied either, hence the
   3241        deviating description and the GET checking against the POST. */
   3242     TALER_TESTING_cmd_merchant_patch_product_with_categories (
   3243       "patch-products-pc-cat-nx",
   3244       merchant_url,
   3245       "pc-product",
   3246       "product with unapplied update",
   3247       "test-unit",
   3248       "EUR:3",
   3249       1,
   3250       (const uint64_t[]) { 424242 },
   3251       MHD_HTTP_NOT_FOUND),
   3252     TALER_TESTING_cmd_merchant_get_product (
   3253       "get-product-pc-unchanged",
   3254       merchant_url,
   3255       "pc-product",
   3256       MHD_HTTP_OK,
   3257       "post-products-pc"),
   3258     TALER_TESTING_cmd_merchant_patch_product_with_categories (
   3259       "patch-products-pc-cat-zero",
   3260       merchant_url,
   3261       "pc-product",
   3262       "product with unapplied update",
   3263       "test-unit",
   3264       "EUR:3",
   3265       1,
   3266       (const uint64_t[]) { 0 },
   3267       MHD_HTTP_BAD_REQUEST),
   3268     TALER_TESTING_cmd_merchant_get_product (
   3269       "get-product-pc-unchanged-2",
   3270       merchant_url,
   3271       "pc-product",
   3272       MHD_HTTP_OK,
   3273       "post-products-pc"),
   3274     /* Duplicate categories are de-duplicated, not rejected. */
   3275     TALER_TESTING_cmd_merchant_patch_product_with_categories (
   3276       "patch-products-pc-cat-dup",
   3277       merchant_url,
   3278       "pc-product",
   3279       "product with category",
   3280       "test-unit",
   3281       "EUR:3",
   3282       2,
   3283       (const uint64_t[]) { 3, 3 },
   3284       MHD_HTTP_NO_CONTENT),
   3285     TALER_TESTING_cmd_merchant_patch_product_with_categories (
   3286       "patch-products-pc-cat-ok",
   3287       merchant_url,
   3288       "pc-product",
   3289       "product with category",
   3290       "test-unit",
   3291       "EUR:3",
   3292       1,
   3293       (const uint64_t[]) { 3 },
   3294       MHD_HTTP_NO_CONTENT),
   3295     TALER_TESTING_cmd_merchant_get_product (
   3296       "get-product-pc",
   3297       merchant_url,
   3298       "pc-product",
   3299       MHD_HTTP_OK,
   3300       "patch-products-pc-cat-ok"),
   3301     TALER_TESTING_cmd_end ()
   3302   };
   3303 
   3304   struct TALER_TESTING_Command partial_payments[] = {
   3305     /* "taler" is reserved and must be rejected */
   3306     TALER_TESTING_cmd_merchant_post_orders_external (
   3307       "create-dd96-bad-taler",
   3308       merchant_url,
   3309       MHD_HTTP_BAD_REQUEST,
   3310       "dd96-bad-taler",
   3311       GNUNET_TIME_UNIT_ZERO_TS,
   3312       GNUNET_TIME_UNIT_FOREVER_TS,
   3313       "EUR:2",
   3314       "[{\"method\":\"taler\",\"id\":\"t1\",\"amount\":\"EUR:1\"}]"),
   3315     /* mixed currencies must be rejected */
   3316     TALER_TESTING_cmd_merchant_post_orders_external (
   3317       "create-dd96-bad-currency",
   3318       merchant_url,
   3319       MHD_HTTP_BAD_REQUEST,
   3320       "dd96-bad-currency",
   3321       GNUNET_TIME_UNIT_ZERO_TS,
   3322       GNUNET_TIME_UNIT_FOREVER_TS,
   3323       "EUR:2",
   3324       "[{\"method\":\"cash\",\"id\":\"c1\",\"amount\":\"USD:1\"}]"),
   3325     /* nested method-specific fields must be rejected */
   3326     TALER_TESTING_cmd_merchant_post_orders_external (
   3327       "create-dd96-bad-nested",
   3328       merchant_url,
   3329       MHD_HTTP_BAD_REQUEST,
   3330       "dd96-bad-nested",
   3331       GNUNET_TIME_UNIT_ZERO_TS,
   3332       GNUNET_TIME_UNIT_FOREVER_TS,
   3333       "EUR:2",
   3334       "[{\"method\":\"cash\",\"id\":\"c1\",\"amount\":\"EUR:1\","
   3335       "\"details\":{\"register\":1}}]"),
   3336     /* valid mixed order with flat method-specific fields */
   3337     TALER_TESTING_cmd_merchant_post_orders_external (
   3338       "create-dd96-mixed",
   3339       merchant_url,
   3340       MHD_HTTP_OK,
   3341       "dd96-mixed",
   3342       GNUNET_TIME_UNIT_ZERO_TS,
   3343       GNUNET_TIME_UNIT_FOREVER_TS,
   3344       "EUR:2",
   3345       "[{\"method\":\"cash\",\"id\":\"cash1\",\"amount\":\"EUR:3\","
   3346       "\"cashier_number\":\"7\"}]"),
   3347     /* normal deletion of orders with external payments is refused */
   3348     TALER_TESTING_cmd_merchant_delete_order2 ("delete-dd96-mixed-noforce",
   3349                                               merchant_url,
   3350                                               "dd96-mixed",
   3351                                               false,
   3352                                               MHD_HTTP_CONFLICT),
   3353     /* ... but forced deletion works */
   3354     TALER_TESTING_cmd_merchant_delete_order2 ("delete-dd96-mixed-force",
   3355                                               merchant_url,
   3356                                               "dd96-mixed",
   3357                                               true,
   3358                                               MHD_HTTP_NO_CONTENT),
   3359     /* collect of unknown orders fails */
   3360     TALER_TESTING_cmd_merchant_collect_order ("collect-dd96-nx",
   3361                                               merchant_url,
   3362                                               "dd96-nx",
   3363                                               NULL,
   3364                                               -1,
   3365                                               MHD_HTTP_NOT_FOUND),
   3366     /* collect of orders with a nonzero Taler amount fails */
   3367     TALER_TESTING_cmd_merchant_post_orders_external (
   3368       "create-dd96-nonzero",
   3369       merchant_url,
   3370       MHD_HTTP_OK,
   3371       "dd96-nonzero",
   3372       GNUNET_TIME_UNIT_ZERO_TS,
   3373       GNUNET_TIME_UNIT_FOREVER_TS,
   3374       "EUR:2",
   3375       "[{\"method\":\"cash\",\"id\":\"cash1\",\"amount\":\"EUR:3\"}]"),
   3376     TALER_TESTING_cmd_merchant_collect_order ("collect-dd96-nonzero",
   3377                                               merchant_url,
   3378                                               "dd96-nonzero",
   3379                                               NULL,
   3380                                               -1,
   3381                                               MHD_HTTP_CONFLICT),
   3382     /* collect of orders claimed by a wallet fails */
   3383     TALER_TESTING_cmd_merchant_post_orders ("create-dd96-claimed",
   3384                                             cred.cfg,
   3385                                             merchant_url,
   3386                                             MHD_HTTP_OK,
   3387                                             "dd96-claimed",
   3388                                             GNUNET_TIME_UNIT_ZERO_TS,
   3389                                             GNUNET_TIME_UNIT_FOREVER_TS,
   3390                                             "EUR:0"),
   3391     TALER_TESTING_cmd_merchant_collect_order ("collect-dd96-claimed",
   3392                                               merchant_url,
   3393                                               "dd96-claimed",
   3394                                               NULL,
   3395                                               -1,
   3396                                               MHD_HTTP_CONFLICT),
   3397     /* collect a zero-Taler order settled fully via cash */
   3398     TALER_TESTING_cmd_merchant_post_orders_external (
   3399       "create-dd96-free",
   3400       merchant_url,
   3401       MHD_HTTP_OK,
   3402       "dd96-free",
   3403       GNUNET_TIME_UNIT_ZERO_TS,
   3404       GNUNET_TIME_UNIT_FOREVER_TS,
   3405       "EUR:0",
   3406       "[{\"method\":\"cash\",\"id\":\"cash1\",\"amount\":\"EUR:3\"}]"),
   3407     TALER_TESTING_cmd_merchant_collect_order ("collect-dd96-free",
   3408                                               merchant_url,
   3409                                               "dd96-free",
   3410                                               "pos-1",
   3411                                               -1,
   3412                                               MHD_HTTP_OK),
   3413     /* collect is idempotent */
   3414     TALER_TESTING_cmd_merchant_collect_order ("collect-dd96-free-again",
   3415                                               merchant_url,
   3416                                               "dd96-free",
   3417                                               "pos-1",
   3418                                               -1,
   3419                                               MHD_HTTP_OK),
   3420     /* v0 orders have no choices, so naming one is a client error;
   3421        use a fresh order as an already collected one replays instead */
   3422     TALER_TESTING_cmd_merchant_post_orders_external (
   3423       "create-dd96-v0-choice",
   3424       merchant_url,
   3425       MHD_HTTP_OK,
   3426       "dd96-v0-choice",
   3427       GNUNET_TIME_UNIT_ZERO_TS,
   3428       GNUNET_TIME_UNIT_FOREVER_TS,
   3429       "EUR:0",
   3430       "[{\"method\":\"cash\",\"id\":\"cash1\",\"amount\":\"EUR:1\"}]"),
   3431     TALER_TESTING_cmd_merchant_collect_order ("collect-dd96-v0-with-choice",
   3432                                               merchant_url,
   3433                                               "dd96-v0-choice",
   3434                                               NULL,
   3435                                               0,
   3436                                               MHD_HTTP_BAD_REQUEST),
   3437     /* a free v1 order with two choices to pick from */
   3438     TALER_TESTING_cmd_merchant_post_orders_v1 (
   3439       "create-dd96-v1-free",
   3440       merchant_url,
   3441       MHD_HTTP_OK,
   3442       "dd96-v1-free",
   3443       GNUNET_TIME_UNIT_ZERO_TS,
   3444       GNUNET_TIME_UNIT_FOREVER_TS,
   3445       "[{\"amount\":\"EUR:0\",\"inputs\":[],\"outputs\":[]},"
   3446       " {\"amount\":\"EUR:0\",\"inputs\":[],\"outputs\":[]}]"),
   3447     /* the backend must not pick a choice on its own */
   3448     TALER_TESTING_cmd_merchant_collect_order ("collect-dd96-v1-no-choice",
   3449                                               merchant_url,
   3450                                               "dd96-v1-free",
   3451                                               NULL,
   3452                                               -1,
   3453                                               MHD_HTTP_BAD_REQUEST),
   3454     /* nor accept a choice that does not exist */
   3455     TALER_TESTING_cmd_merchant_collect_order ("collect-dd96-v1-oob",
   3456                                               merchant_url,
   3457                                               "dd96-v1-free",
   3458                                               NULL,
   3459                                               7,
   3460                                               MHD_HTTP_BAD_REQUEST),
   3461     /* explicitly selecting a choice collects the order */
   3462     TALER_TESTING_cmd_merchant_collect_order ("collect-dd96-v1-choice1",
   3463                                               merchant_url,
   3464                                               "dd96-v1-free",
   3465                                               "pos-1",
   3466                                               1,
   3467                                               MHD_HTTP_OK),
   3468     /* Re-collecting an order that is already paid, but naming another
   3469        choice, describes a payment that never happened and is refused. */
   3470     TALER_TESTING_cmd_merchant_collect_order ("collect-dd96-v1-other-choice",
   3471                                               merchant_url,
   3472                                               "dd96-v1-free",
   3473                                               "pos-1",
   3474                                               0,
   3475                                               MHD_HTTP_CONFLICT),
   3476     /* ... the order still has to be the one that was actually paid */
   3477     TALER_TESTING_cmd_merchant_check_order_external (
   3478       "check-dd96-v1-choice",
   3479       merchant_url,
   3480       "dd96-v1-free",
   3481       0,
   3482       0,
   3483       1),
   3484     /* record external refunds against the order total of EUR:3 */
   3485     TALER_TESTING_cmd_merchant_refund_external (
   3486       "refund-external-dd96-1",
   3487       merchant_url,
   3488       "dd96-free",
   3489       "{\"method\":\"cash\",\"id\":\"ref1\",\"amount\":\"EUR:0.6\","
   3490       "\"reason\":\"customer return\"}",
   3491       MHD_HTTP_OK),
   3492     /* re-recording the same refund ID with the same body is idempotent
   3493        and must not consume the refundable amount twice */
   3494     TALER_TESTING_cmd_merchant_refund_external (
   3495       "refund-external-dd96-1-again",
   3496       merchant_url,
   3497       "dd96-free",
   3498       "{\"method\":\"cash\",\"id\":\"ref1\",\"amount\":\"EUR:0.6\","
   3499       "\"reason\":\"customer return\"}",
   3500       MHD_HTTP_OK),
   3501     /* the same refund ID with different details is a conflict */
   3502     TALER_TESTING_cmd_merchant_refund_external (
   3503       "refund-external-dd96-1-conflict",
   3504       merchant_url,
   3505       "dd96-free",
   3506       "{\"method\":\"cash\",\"id\":\"ref1\",\"amount\":\"EUR:0.5\","
   3507       "\"reason\":\"customer return\"}",
   3508       MHD_HTTP_CONFLICT),
   3509     /* refund through a different method than the payment; without an
   3510        explicit ID the backend assigns one */
   3511     TALER_TESTING_cmd_merchant_refund_external (
   3512       "refund-external-dd96-2",
   3513       merchant_url,
   3514       "dd96-free",
   3515       "{\"method\":\"card\",\"id\":\"r1\",\"payment_id\":\"cash1\",\"amount\":\"EUR:2.4\","
   3516       "\"reason\":\"customer return\"}",
   3517       MHD_HTTP_OK),
   3518     /* exceeding the order total must be rejected */
   3519     TALER_TESTING_cmd_merchant_refund_external (
   3520       "refund-external-dd96-over",
   3521       merchant_url,
   3522       "dd96-free",
   3523       "{\"method\":\"cash\",\"id\":\"r2\",\"amount\":\"EUR:0.5\","
   3524       "\"reason\":\"customer return\"}",
   3525       MHD_HTTP_CONFLICT),
   3526     /* wrong currency must be rejected */
   3527     TALER_TESTING_cmd_merchant_refund_external (
   3528       "refund-external-dd96-currency",
   3529       merchant_url,
   3530       "dd96-free",
   3531       "{\"method\":\"cash\",\"id\":\"r3\",\"amount\":\"USD:0.5\","
   3532       "\"reason\":\"customer return\"}",
   3533       MHD_HTTP_CONFLICT),
   3534     /* method "taler" must be rejected */
   3535     TALER_TESTING_cmd_merchant_refund_external (
   3536       "refund-external-dd96-taler",
   3537       merchant_url,
   3538       "dd96-free",
   3539       "{\"method\":\"taler\",\"id\":\"r4\",\"amount\":\"EUR:0.5\","
   3540       "\"reason\":\"customer return\"}",
   3541       MHD_HTTP_BAD_REQUEST),
   3542     /* The order status must report the external payment it was settled
   3543        with and the two external refunds that were accepted for it; the
   3544        replayed and the rejected requests must not have added entries. */
   3545     TALER_TESTING_cmd_merchant_check_order_external (
   3546       "check-dd96-free-external",
   3547       merchant_url,
   3548       "dd96-free",
   3549       1,
   3550       2,
   3551       -1),
   3552     /* The combined refund cap must also hold when an external refund is
   3553        followed by an increase of the Taler refund. */
   3554     TALER_TESTING_cmd_merchant_post_orders (
   3555       "create-dd96-taler-refund-cap",
   3556       cred.cfg,
   3557       merchant_url,
   3558       MHD_HTTP_OK,
   3559       "dd96-taler-refund-cap",
   3560       GNUNET_TIME_UNIT_ZERO_TS,
   3561       GNUNET_TIME_UNIT_FOREVER_TS,
   3562       "EUR:5"),
   3563     TALER_TESTING_cmd_merchant_pay_order (
   3564       "pay-dd96-taler-refund-cap",
   3565       merchant_url,
   3566       MHD_HTTP_OK,
   3567       "create-dd96-taler-refund-cap",
   3568       "withdraw-coin-2r",
   3569       "EUR:5",
   3570       "EUR:4.99",
   3571       NULL),
   3572     TALER_TESTING_cmd_merchant_order_refund (
   3573       "refund-taler-dd96-cap-1",
   3574       merchant_url,
   3575       "customer return",
   3576       "dd96-taler-refund-cap",
   3577       "EUR:1",
   3578       MHD_HTTP_OK),
   3579     TALER_TESTING_cmd_merchant_refund_external (
   3580       "refund-external-dd96-cap-3",
   3581       merchant_url,
   3582       "dd96-taler-refund-cap",
   3583       "{\"method\":\"cash\",\"id\":\"r5\",\"amount\":\"EUR:3\","
   3584       "\"reason\":\"returned in cash\"}",
   3585       MHD_HTTP_OK),
   3586     /* A Taler refund of EUR:3 would make the combined refund EUR:6
   3587        for an order whose total is only EUR:5. */
   3588     TALER_TESTING_cmd_merchant_order_refund (
   3589       "refund-taler-dd96-cap-over",
   3590       merchant_url,
   3591       "customer return",
   3592       "dd96-taler-refund-cap",
   3593       "EUR:3",
   3594       MHD_HTTP_CONFLICT),
   3595     /* external refunds also work on pure-Taler orders, e.g. for
   3596        bookkeeping cash returns after the Taler refund deadline;
   3597        order "1r" was paid with EUR:5 and refunded EUR:1 via Taler,
   3598        leaving EUR:4 that may still be refunded externally */
   3599     TALER_TESTING_cmd_merchant_refund_external (
   3600       "refund-external-dd96-taler-order",
   3601       merchant_url,
   3602       "1r",
   3603       "{\"method\":\"cash\",\"id\":\"r6\",\"amount\":\"EUR:3.5\","
   3604       "\"reason\":\"returned in cash after refund deadline\"}",
   3605       MHD_HTTP_OK),
   3606     /* ... but the combined cap still holds: 1 + 3.5 + 1 > 5 */
   3607     TALER_TESTING_cmd_merchant_refund_external (
   3608       "refund-external-dd96-taler-order-over",
   3609       merchant_url,
   3610       "1r",
   3611       "{\"method\":\"cash\",\"id\":\"r7\",\"amount\":\"EUR:1\","
   3612       "\"reason\":\"returned in cash after refund deadline\"}",
   3613       MHD_HTTP_CONFLICT),
   3614     /* unpaid orders must be rejected */
   3615     TALER_TESTING_cmd_merchant_refund_external (
   3616       "refund-external-dd96-unpaid",
   3617       merchant_url,
   3618       "dd96-claimed",
   3619       "{\"method\":\"cash\",\"id\":\"r8\",\"amount\":\"EUR:0.5\","
   3620       "\"reason\":\"customer return\"}",
   3621       MHD_HTTP_CONFLICT),
   3622     /* unknown orders must be rejected */
   3623     TALER_TESTING_cmd_merchant_refund_external (
   3624       "refund-external-dd96-nx",
   3625       merchant_url,
   3626       "dd96-nx",
   3627       "{\"method\":\"cash\",\"id\":\"r9\",\"amount\":\"EUR:0.5\","
   3628       "\"reason\":\"customer return\"}",
   3629       MHD_HTTP_NOT_FOUND),
   3630     TALER_TESTING_cmd_end ()
   3631   };
   3632 
   3633   struct TALER_TESTING_Command commands[] = {
   3634     /* general setup */
   3635     TALER_TESTING_cmd_run_fakebank (
   3636       "run-fakebank",
   3637       cred.cfg,
   3638       "exchange-account-exchange"),
   3639     TALER_TESTING_cmd_system_start (
   3640       "start-taler",
   3641       config_file,
   3642       "-emaD",
   3643       "-u", "exchange-account-exchange",
   3644       "-r", "merchant-exchange-test",
   3645       NULL),
   3646     TALER_TESTING_cmd_get_exchange (
   3647       "get-exchange",
   3648       cred.cfg,
   3649       NULL,
   3650       true,
   3651       true),
   3652     TALER_TESTING_cmd_batch (
   3653       "orders-id",
   3654       get_private_order_id),
   3655     TALER_TESTING_cmd_config (
   3656       "config",
   3657       merchant_url,
   3658       MHD_HTTP_OK),
   3659     TALER_TESTING_cmd_merchant_get_instances (
   3660       "instances-empty",
   3661       merchant_url,
   3662       MHD_HTTP_OK,
   3663       NULL),
   3664     TALER_TESTING_cmd_merchant_post_instances (
   3665       "instance-create-default-setup",
   3666       merchant_url,
   3667       "admin",
   3668       MHD_HTTP_NO_CONTENT),
   3669     TALER_TESTING_cmd_merchant_post_account (
   3670       "instance-create-default-account",
   3671       merchant_url,
   3672       merchant_payto,
   3673       NULL, NULL,
   3674       MHD_HTTP_OK),
   3675     TALER_TESTING_cmd_merchant_post_instances (
   3676       "instance-create-i1",
   3677       merchant_url,
   3678       "i1",
   3679       MHD_HTTP_NO_CONTENT),
   3680     TALER_TESTING_cmd_merchant_get_instances (
   3681       "instances-get-i1",
   3682       merchant_url,
   3683       MHD_HTTP_OK,
   3684       "instance-create-i1",
   3685       "instance-create-default-setup",
   3686       NULL),
   3687     TALER_TESTING_cmd_merchant_get_instance (
   3688       "instances-get-i1",
   3689       merchant_url,
   3690       "i1",
   3691       MHD_HTTP_OK,
   3692       "instance-create-i1"),
   3693     TALER_TESTING_cmd_merchant_patch_instance (
   3694       "instance-patch-i1",
   3695       merchant_url,
   3696       "i1",
   3697       "bob-the-merchant",
   3698       json_pack ("{s:s}",
   3699                  "street",
   3700                  "bobstreet"),
   3701       json_pack ("{s:s}",
   3702                  "street",
   3703                  "bobjuryst"),
   3704       true,
   3705       GNUNET_TIME_UNIT_ZERO, /* wire transfer */
   3706       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
   3707                                      2), /* small pay delay */
   3708       MHD_HTTP_NO_CONTENT),
   3709     TALER_TESTING_cmd_merchant_get_instance (
   3710       "instances-get-i1-2",
   3711       merchant_url,
   3712       "i1",
   3713       MHD_HTTP_OK,
   3714       "instance-patch-i1"),
   3715     TALER_TESTING_cmd_merchant_get_instance (
   3716       "instances-get-i2-nx",
   3717       merchant_url,
   3718       "i2",
   3719       MHD_HTTP_NOT_FOUND,
   3720       NULL),
   3721     TALER_TESTING_cmd_merchant_post_instances2 (
   3722       "instance-create-ACL",
   3723       merchant_url,
   3724       "i-acl",
   3725       "controlled instance",
   3726       json_pack ("{s:s}", "city",
   3727                  "shopcity"),
   3728       json_pack ("{s:s}", "city",
   3729                  "lawyercity"),
   3730       true,
   3731       GNUNET_TIME_UNIT_ZERO, /* wire transfer */
   3732       GNUNET_TIME_UNIT_SECONDS, /* pay delay */
   3733       // FIXME: change this back once
   3734       // we have a update auth test CMD
   3735       // RFC_8959_PREFIX "EXAMPLE",
   3736       NULL,
   3737       MHD_HTTP_NO_CONTENT),
   3738     TALER_TESTING_cmd_merchant_patch_instance (
   3739       "instance-patch-ACL",
   3740       merchant_url,
   3741       "i-acl",
   3742       "controlled instance",
   3743       json_pack ("{s:s}",
   3744                  "street",
   3745                  "bobstreet"),
   3746       json_pack ("{s:s}",
   3747                  "street",
   3748                  "bobjuryst"),
   3749       true,
   3750       GNUNET_TIME_UNIT_ZERO, /* wire transfer */
   3751       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
   3752                                      2), /* small pay delay */
   3753       MHD_HTTP_NO_CONTENT),
   3754     TALER_TESTING_cmd_merchant_post_instances (
   3755       "instance-create-i2",
   3756       merchant_url,
   3757       "i2",
   3758       MHD_HTTP_NO_CONTENT),
   3759     TALER_TESTING_cmd_merchant_post_instances (
   3760       "instance-create-i2-idem",
   3761       merchant_url,
   3762       "i2",
   3763       MHD_HTTP_NO_CONTENT),
   3764     TALER_TESTING_cmd_merchant_delete_instance (
   3765       "instance-delete-i2",
   3766       merchant_url,
   3767       "i2",
   3768       MHD_HTTP_NO_CONTENT),
   3769     TALER_TESTING_cmd_merchant_get_instance (
   3770       "instances-get-i2-post-deletion",
   3771       merchant_url,
   3772       "i2",
   3773       MHD_HTTP_NOT_FOUND,
   3774       NULL),
   3775     TALER_TESTING_cmd_merchant_purge_instance (
   3776       "instance-delete-then-purge-i2",
   3777       merchant_url,
   3778       "i2",
   3779       MHD_HTTP_NO_CONTENT),
   3780     TALER_TESTING_cmd_merchant_purge_instance (
   3781       "instance-purge-i1",
   3782       merchant_url,
   3783       "i1",
   3784       MHD_HTTP_NO_CONTENT),
   3785     TALER_TESTING_cmd_merchant_delete_instance (
   3786       "instance-purge-then-delete-i1",
   3787       merchant_url,
   3788       "i1",
   3789       MHD_HTTP_NOT_FOUND),
   3790     TALER_TESTING_cmd_merchant_purge_instance (
   3791       "instance-purge-i-acl-middle",
   3792       merchant_url,
   3793       "i-acl",
   3794       MHD_HTTP_NO_CONTENT),
   3795     TALER_TESTING_cmd_merchant_purge_instance (
   3796       "instance-purge-default-middle",
   3797       merchant_url,
   3798       "admin",
   3799       MHD_HTTP_NO_CONTENT),
   3800     TALER_TESTING_cmd_merchant_post_instances (
   3801       "instance-create-default-after-purge",
   3802       merchant_url,
   3803       "admin",
   3804       MHD_HTTP_NO_CONTENT),
   3805     TALER_TESTING_cmd_merchant_post_account (
   3806       "instance-create-default-account-after-purge",
   3807       merchant_url,
   3808       merchant_payto,
   3809       NULL, NULL,
   3810       MHD_HTTP_OK),
   3811     TALER_TESTING_cmd_merchant_get_products (
   3812       "get-products-empty",
   3813       merchant_url,
   3814       MHD_HTTP_OK,
   3815       NULL),
   3816     TALER_TESTING_cmd_merchant_post_products (
   3817       "post-products-p1",
   3818       merchant_url,
   3819       "product-1",
   3820       "a product",
   3821       "EUR:1",
   3822       MHD_HTTP_NO_CONTENT),
   3823     TALER_TESTING_cmd_merchant_post_products (
   3824       "post-products-p1-idem",
   3825       merchant_url,
   3826       "product-1",
   3827       "a product",
   3828       "EUR:1",
   3829       MHD_HTTP_NO_CONTENT),
   3830     TALER_TESTING_cmd_merchant_post_products (
   3831       "post-products-p1-non-idem",
   3832       merchant_url,
   3833       "product-1",
   3834       "a different product",
   3835       "EUR:1",
   3836       MHD_HTTP_CONFLICT),
   3837     TALER_TESTING_cmd_merchant_get_products (
   3838       "get-products-p1",
   3839       merchant_url,
   3840       MHD_HTTP_OK,
   3841       "post-products-p1",
   3842       NULL),
   3843     TALER_TESTING_cmd_merchant_get_product (
   3844       "get-product-p1",
   3845       merchant_url,
   3846       "product-1",
   3847       MHD_HTTP_OK,
   3848       "post-products-p1"),
   3849     TALER_TESTING_cmd_merchant_post_products2 (
   3850       "post-products-img",
   3851       merchant_url,
   3852       "product-img",
   3853       "product with image",
   3854       json_pack ("{s:s}", "en", "product with image"),
   3855       "test-unit",
   3856       "EUR:1",
   3857       "data:image/jpeg;base64,RAWDATA",
   3858       json_array (),
   3859       4,
   3860       0,
   3861       json_pack ("{s:s}", "street", "my street"),
   3862       GNUNET_TIME_UNIT_ZERO_TS,
   3863       MHD_HTTP_NO_CONTENT),
   3864     TALER_TESTING_cmd_get_product_image (
   3865       "get-product-image-img",
   3866       merchant_url,
   3867       "post-products-img",
   3868       "5831ca012639a29df949c3b1e5cd436bac0a5b26a5340ccd95df394b7a8742d6",
   3869       MHD_HTTP_OK),
   3870     TALER_TESTING_cmd_get_product_image (
   3871       "get-product-image-invalid",
   3872       merchant_url,
   3873       NULL,
   3874       "not-a-valid-hash",
   3875       MHD_HTTP_BAD_REQUEST),
   3876     TALER_TESTING_cmd_get_product_image (
   3877       "get-product-image-empty",
   3878       merchant_url,
   3879       NULL,
   3880       "",
   3881       MHD_HTTP_BAD_REQUEST),
   3882     TALER_TESTING_cmd_get_product_image (
   3883       "get-product-image-not-found",
   3884       merchant_url,
   3885       NULL,
   3886       "5831ca012639a29df949c3b1e5cd436bac0a5b26a5340ccd95df394b7a8742d7",
   3887       MHD_HTTP_NOT_FOUND),
   3888     TALER_TESTING_cmd_merchant_post_products (
   3889       "post-products-p2",
   3890       merchant_url,
   3891       "product-2",
   3892       "a product",
   3893       "EUR:1",
   3894       MHD_HTTP_NO_CONTENT),
   3895     TALER_TESTING_cmd_merchant_patch_product (
   3896       "patch-products-p2",
   3897       merchant_url,
   3898       "product-2",
   3899       "another product",
   3900       json_pack ("{s:s}", "en", "text"),
   3901       "kg",
   3902       "EUR:1",
   3903       "data:image/jpeg;base64,RAWDATA",
   3904       json_array (),
   3905       40,
   3906       0,
   3907       json_pack ("{s:s}",
   3908                  "street",
   3909                  "pstreet"),
   3910       GNUNET_TIME_relative_to_timestamp (
   3911         GNUNET_TIME_UNIT_MINUTES),
   3912       MHD_HTTP_NO_CONTENT),
   3913     TALER_TESTING_cmd_merchant_get_product (
   3914       "get-product-p2",
   3915       merchant_url,
   3916       "product-2",
   3917       MHD_HTTP_OK,
   3918       "patch-products-p2"),
   3919     TALER_TESTING_cmd_merchant_get_product (
   3920       "get-product-nx",
   3921       merchant_url,
   3922       "product-nx",
   3923       MHD_HTTP_NOT_FOUND,
   3924       NULL),
   3925     TALER_TESTING_cmd_merchant_patch_product (
   3926       "patch-products-p3-nx",
   3927       merchant_url,
   3928       "product-3",
   3929       "nx updated product",
   3930       json_pack ("{s:s}", "en", "text"),
   3931       "kg",
   3932       "EUR:1",
   3933       "data:image/jpeg;base64,RAWDATA",
   3934       json_array (),
   3935       40,
   3936       0,
   3937       json_pack ("{s:s}",
   3938                  "street",
   3939                  "pstreet"),
   3940       GNUNET_TIME_relative_to_timestamp (
   3941         GNUNET_TIME_UNIT_MINUTES),
   3942       MHD_HTTP_NOT_FOUND),
   3943     TALER_TESTING_cmd_merchant_delete_product (
   3944       "get-products-empty",
   3945       merchant_url,
   3946       "p1",
   3947       MHD_HTTP_NOT_FOUND),
   3948     TALER_TESTING_cmd_merchant_delete_product (
   3949       "get-products-empty",
   3950       merchant_url,
   3951       "product-1",
   3952       MHD_HTTP_NO_CONTENT),
   3953     TALER_TESTING_cmd_merchant_lock_product (
   3954       "lock-product-p2",
   3955       merchant_url,
   3956       "product-2",
   3957       GNUNET_TIME_UNIT_MINUTES,
   3958       2,
   3959       MHD_HTTP_NO_CONTENT),
   3960     TALER_TESTING_cmd_merchant_lock_product (
   3961       "lock-product-nx",
   3962       merchant_url,
   3963       "product-nx",
   3964       GNUNET_TIME_UNIT_MINUTES,
   3965       2,
   3966       MHD_HTTP_NOT_FOUND),
   3967     TALER_TESTING_cmd_merchant_lock_product (
   3968       "lock-product-too-much",
   3969       merchant_url,
   3970       "product-2",
   3971       GNUNET_TIME_UNIT_MINUTES,
   3972       39,
   3973       MHD_HTTP_GONE),
   3974     TALER_TESTING_cmd_merchant_delete_product (
   3975       "delete-product-locked",
   3976       merchant_url,
   3977       "product-2",
   3978       MHD_HTTP_CONFLICT),
   3979     TALER_TESTING_cmd_batch ("pay",
   3980                              pay),
   3981     TALER_TESTING_cmd_batch ("double-spending",
   3982                              double_spending),
   3983     TALER_TESTING_cmd_batch ("pay-again",
   3984                              pay_again),
   3985     TALER_TESTING_cmd_batch ("pay-abort",
   3986                              pay_abort),
   3987     TALER_TESTING_cmd_batch ("refund",
   3988                              refund),
   3989     TALER_TESTING_cmd_batch ("templates",
   3990                              templates),
   3991     TALER_TESTING_cmd_batch ("webhooks",
   3992                              webhooks),
   3993     TALER_TESTING_cmd_batch ("inventory-webhooks",
   3994                              inventory_webhooks),
   3995     TALER_TESTING_cmd_batch ("auth",
   3996                              auth),
   3997     TALER_TESTING_cmd_batch ("repurchase",
   3998                              repurchase),
   3999     TALER_TESTING_cmd_batch ("tokens",
   4000                              tokens),
   4001     TALER_TESTING_cmd_batch ("donau",
   4002                              donau),
   4003     TALER_TESTING_cmd_batch ("partial-payments",
   4004                              partial_payments),
   4005     TALER_TESTING_cmd_batch ("product-categories",
   4006                              product_categories),
   4007     TALER_TESTING_cmd_merchant_get_statisticsamount ("stats-refund",
   4008                                                      merchant_url,
   4009                                                      "refunds-granted",
   4010                                                      6,
   4011                                                      0,
   4012                                                      MHD_HTTP_OK),
   4013     TALER_TESTING_cmd_merchant_get_statisticscounter ("stats-tokens-issued",
   4014                                                       merchant_url,
   4015                                                       "tokens-issued",
   4016                                                       6,
   4017                                                       1,
   4018                                                       MHD_HTTP_OK),
   4019     TALER_TESTING_cmd_merchant_get_statisticscounter ("stats-tokens-used",
   4020                                                       merchant_url,
   4021                                                       "tokens-used",
   4022                                                       6,
   4023                                                       1,
   4024                                                       MHD_HTTP_OK),
   4025 
   4026     /**
   4027      * End the suite.
   4028      */
   4029     TALER_TESTING_cmd_end ()
   4030   };
   4031 
   4032   TALER_TESTING_run (is,
   4033                      commands);
   4034 }
   4035 
   4036 
   4037 int
   4038 main (int argc,
   4039       char *const *argv)
   4040 {
   4041   {
   4042     char *cipher;
   4043 
   4044     cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
   4045     GNUNET_assert (NULL != cipher);
   4046     GNUNET_asprintf (&config_file,
   4047                      "test_merchant_api-%s.conf",
   4048                      cipher);
   4049     GNUNET_free (cipher);
   4050   }
   4051   payer_payto.full_payto =
   4052     (char *) "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME
   4053     "?receiver-name=" USER_ACCOUNT_NAME;
   4054   exchange_payto.full_payto =
   4055     (char *) "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME
   4056     "?receiver-name="
   4057     EXCHANGE_ACCOUNT_NAME;
   4058   merchant_payto.full_payto =
   4059     (char *) "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME
   4060     "?receiver-name=" MERCHANT_ACCOUNT_NAME;
   4061   merchant_url = "http://localhost:8080/";
   4062   GNUNET_asprintf (&merchant_url_i1a,
   4063                    "%sinstances/i1a/",
   4064                    merchant_url);
   4065   return TALER_TESTING_main (argv,
   4066                              "INFO",
   4067                              config_file,
   4068                              "exchange-account-exchange",
   4069                              TALER_TESTING_BS_FAKEBANK,
   4070                              &cred,
   4071                              &run,
   4072                              NULL);
   4073 }
   4074 
   4075 
   4076 /* end of test_merchant_api.c */