merchant

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

test_merchant_api.c (148936B)


      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     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-1-pre-exists",
    507                                             cred.cfg,
    508                                             merchant_url,
    509                                             MHD_HTTP_CONFLICT,
    510                                             "1",
    511                                             GNUNET_TIME_UNIT_ZERO_TS,
    512                                             GNUNET_TIME_UNIT_FOREVER_TS,
    513                                             "EUR:5.0"),
    514     TALER_TESTING_cmd_poll_orders_conclude ("poll-orders-1-conclude",
    515                                             MHD_HTTP_OK,
    516                                             "poll-orders-1-start"),
    517     TALER_TESTING_cmd_merchant_get_orders ("get-orders-1",
    518                                            merchant_url,
    519                                            MHD_HTTP_OK,
    520                                            "create-proposal-1x",
    521                                            "create-proposal-1",
    522                                            NULL),
    523     TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1",
    524                                         merchant_url,
    525                                         "create-proposal-1",
    526                                         false,
    527                                         false,
    528                                         false,
    529                                         MHD_HTTP_PAYMENT_REQUIRED),
    530     TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1",
    531                                           merchant_url,
    532                                           "create-proposal-1",
    533                                           TALER_MERCHANT_OSC_CLAIMED,
    534                                           false,
    535                                           MHD_HTTP_OK,
    536                                           NULL),
    537     TALER_TESTING_cmd_wallet_poll_order_start ("poll-order-wallet-start-1",
    538                                                merchant_url,
    539                                                "create-proposal-1",
    540                                                POLL_ORDER_TIMEOUT,
    541                                                NULL),
    542     TALER_TESTING_cmd_wallet_poll_order_start2 ("poll-order-wallet-start-1x",
    543                                                 merchant_url,
    544                                                 "create-proposal-1x",
    545                                                 POLL_ORDER_SHORT_TIMEOUT,
    546                                                 NULL, /* no refund */
    547                                                 "session-0"),
    548     TALER_TESTING_cmd_poll_order_start ("poll-order-merchant-1-start",
    549                                         merchant_url,
    550                                         "1",
    551                                         POLL_ORDER_TIMEOUT),
    552     TALER_TESTING_cmd_merchant_pay_order ("deposit-simple",
    553                                           merchant_url,
    554                                           MHD_HTTP_OK,
    555                                           "create-proposal-1",
    556                                           "withdraw-coin-1",
    557                                           "EUR:5",
    558                                           "EUR:4.99",
    559                                           "session-0"),
    560     TALER_TESTING_cmd_poll_order_conclude ("poll-order-merchant-1-conclude",
    561                                            MHD_HTTP_OK,
    562                                            "poll-order-merchant-1-start"),
    563     TALER_TESTING_cmd_wallet_poll_order_conclude ("poll-order-1-conclude",
    564                                                   MHD_HTTP_OK,
    565                                                   NULL,
    566                                                   "poll-order-wallet-start-1"),
    567     /* Check for webhook */
    568     cmd_webhook ("pending-webhooks-pay-w1"),
    569     /* Check webhook did anything: have a command that inspects traits of the testserver
    570        and check if the traits have the right values set! */
    571     TALER_TESTING_cmd_checkserver ("check-http-server-for-webhooks",
    572                                    "launch-http-server-for-webhooks",
    573                                    0),
    574     /* Here we expect to run into a timeout, as we do not pay this one */
    575     TALER_TESTING_cmd_wallet_poll_order_conclude2 ("poll-order-1x-conclude",
    576                                                    MHD_HTTP_PAYMENT_REQUIRED,
    577                                                    NULL,
    578                                                    "poll-order-wallet-start-1x",
    579                                                    "1"),
    580     TALER_TESTING_cmd_merchant_post_orders_paid ("verify-order-1-paid",
    581                                                  merchant_url,
    582                                                  "deposit-simple",
    583                                                  "session-1",
    584                                                  MHD_HTTP_OK),
    585     TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1-2",
    586                                         merchant_url,
    587                                         "create-proposal-1",
    588                                         true,
    589                                         false,
    590                                         false,
    591                                         MHD_HTTP_OK),
    592     TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1-2a",
    593                                           merchant_url,
    594                                           "create-proposal-1",
    595                                           TALER_MERCHANT_OSC_PAID,
    596                                           false,
    597                                           MHD_HTTP_OK,
    598                                           NULL),
    599     TALER_TESTING_cmd_merchant_get_orders ("get-orders-1-paid",
    600                                            merchant_url,
    601                                            MHD_HTTP_OK,
    602                                            "create-proposal-1x",
    603                                            "create-proposal-1",
    604                                            NULL),
    605     TALER_TESTING_cmd_merchant_pay_order ("replay-simple",
    606                                           merchant_url,
    607                                           MHD_HTTP_OK,
    608                                           "create-proposal-1",
    609                                           "withdraw-coin-1",
    610                                           "EUR:5",
    611                                           "EUR:4.99",
    612                                           "session-0"),
    613     TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-1"),
    614     TALER_TESTING_cmd_sleep (
    615       "Wait for wire transfer deadline",
    616       3),
    617     CMD_EXEC_AGGREGATOR ("run-aggregator"),
    618     TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-498c",
    619                                            EXCHANGE_URL,
    620                                            "EUR:4.98",
    621                                            exchange_payto,
    622                                            merchant_payto),
    623     TALER_TESTING_cmd_merchant_post_transfer ("post-transfer-1",
    624                                               &cred.ba,
    625                                               merchant_payto,
    626                                               merchant_url,
    627                                               "EUR:4.98",
    628                                               MHD_HTTP_NO_CONTENT,
    629                                               "deposit-simple",
    630                                               NULL),
    631     TALER_TESTING_cmd_depositcheck ("run taler-merchant-depositcheck-1",
    632                                     config_file),
    633     TALER_TESTING_cmd_run_tme ("run taler-merchant-reconciliation-1",
    634                                config_file),
    635     /* Check for settled webhook after reconciliation */
    636     cmd_webhook ("pending-webhooks-settled-w1"),
    637     TALER_TESTING_cmd_checkserver2 ("check-http-server-for-settled-webhook",
    638                                     "launch-http-server-for-webhooks",
    639                                     1,
    640                                     "/",
    641                                     "POST",
    642                                     "settled",
    643                                     "order-settled"),
    644     TALER_TESTING_cmd_merchant_post_transfer2 ("post-transfer-bad",
    645                                                merchant_url,
    646                                                merchant_payto,
    647                                                "EUR:4.98",
    648                                                NULL,
    649                                                /*non-routable IP address
    650                                                so we are sure to not get
    651                                                any reply*/
    652                                                "http://192.0.2.1/404/",
    653                                                MHD_HTTP_NO_CONTENT),
    654     TALER_TESTING_cmd_merchant_get_transfers ("get-transfers-1",
    655                                               merchant_url,
    656                                               merchant_payto,
    657                                               MHD_HTTP_OK,
    658                                               "post-transfer-1",
    659                                               "post-transfer-bad",
    660                                               NULL),
    661     TALER_TESTING_cmd_merchant_delete_transfer ("delete-transfer-1",
    662                                                 merchant_url,
    663                                                 "post-transfer-bad",
    664                                                 MHD_HTTP_NO_CONTENT),
    665     TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-2b",
    666                                            merchant_url,
    667                                            "create-proposal-1",
    668                                            TALER_MERCHANT_OSC_PAID,
    669                                            true,
    670                                            order_1_transfers, /* "post-transfer-1" */
    671                                            false,
    672                                            NULL,
    673                                            NULL,
    674                                            MHD_HTTP_OK),
    675     TALER_TESTING_cmd_merchant_forget_order ("forget-1",
    676                                              merchant_url,
    677                                              MHD_HTTP_NO_CONTENT,
    678                                              "create-proposal-1",
    679                                              NULL,
    680                                              "$.dummy_obj",
    681                                              NULL),
    682     TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-forget-1",
    683                                            merchant_url,
    684                                            "create-proposal-1",
    685                                            TALER_MERCHANT_OSC_PAID,
    686                                            true,
    687                                            order_1_transfers,
    688                                            false,
    689                                            NULL,
    690                                            order_1_forgets_1,
    691                                            MHD_HTTP_OK),
    692     TALER_TESTING_cmd_merchant_forget_order ("forget-unforgettable",
    693                                              merchant_url,
    694                                              MHD_HTTP_CONFLICT,
    695                                              "create-proposal-1",
    696                                              NULL,
    697                                              "$.amount",
    698                                              NULL),
    699     TALER_TESTING_cmd_merchant_forget_order ("forget-order-nx",
    700                                              merchant_url,
    701                                              MHD_HTTP_NOT_FOUND,
    702                                              NULL,
    703                                              "nx-order",
    704                                              "$.dummy_obj",
    705                                              NULL),
    706     TALER_TESTING_cmd_merchant_forget_order ("forget-order-array-elem",
    707                                              merchant_url,
    708                                              MHD_HTTP_NO_CONTENT,
    709                                              "create-proposal-1",
    710                                              NULL,
    711                                              "$.dummy_array[0].item",
    712                                              NULL),
    713     TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-forget-2",
    714                                            merchant_url,
    715                                            "create-proposal-1",
    716                                            TALER_MERCHANT_OSC_PAID,
    717                                            true,
    718                                            order_1_transfers,
    719                                            false,
    720                                            NULL,
    721                                            order_1_forgets_2,
    722                                            MHD_HTTP_OK),
    723     TALER_TESTING_cmd_merchant_forget_order ("forget-order-array-wc",
    724                                              merchant_url,
    725                                              MHD_HTTP_NO_CONTENT,
    726                                              "create-proposal-1",
    727                                              NULL,
    728                                              "$.dummy_array[*].item",
    729                                              NULL),
    730     TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1-forget-3",
    731                                            merchant_url,
    732                                            "create-proposal-1",
    733                                            TALER_MERCHANT_OSC_PAID,
    734                                            true,
    735                                            order_1_transfers,
    736                                            false,
    737                                            NULL,
    738                                            order_1_forgets_3,
    739                                            MHD_HTTP_OK),
    740     TALER_TESTING_cmd_merchant_forget_order ("forget-order-malformed",
    741                                              merchant_url,
    742                                              MHD_HTTP_BAD_REQUEST,
    743                                              "create-proposal-1",
    744                                              NULL,
    745                                              "$.dummy_array[abc].item",
    746                                              NULL),
    747     TALER_TESTING_cmd_merchant_post_products ("post-products-p3",
    748                                               merchant_url,
    749                                               "product-3",
    750                                               "a product",
    751                                               "EUR:1",
    752                                               MHD_HTTP_NO_CONTENT),
    753     TALER_TESTING_cmd_merchant_post_products2 ("post-product-piece",
    754                                                merchant_url,
    755                                                "product-piece",
    756                                                "a product sold by piece",
    757                                                NULL,
    758                                                "Piece",
    759                                                "EUR:1",
    760                                                "",
    761                                                NULL,
    762                                                4,
    763                                                0,
    764                                                NULL,
    765                                                GNUNET_TIME_UNIT_ZERO_TS,
    766                                                MHD_HTTP_NO_CONTENT),
    767     TALER_TESTING_cmd_merchant_post_products_with_unit_prices (
    768       "post-products-dup-currency",
    769       merchant_url,
    770       "product-dup-currency",
    771       "duplicate currency product",
    772       "test-unit",
    773       (const char *[]) { "EUR:1", "EUR:2" },
    774       2,
    775       MHD_HTTP_BAD_REQUEST),
    776     TALER_TESTING_cmd_merchant_post_products2 ("post-products-p4",
    777                                                merchant_url,
    778                                                "product-4age",
    779                                                "an age-restricted product",
    780                                                NULL,
    781                                                "unit",
    782                                                "EUR:1",
    783                                                "", /* image */
    784                                                NULL,
    785                                                4,
    786                                                16 /* minimum age */,
    787                                                NULL,
    788                                                GNUNET_TIME_UNIT_FOREVER_TS,
    789                                                MHD_HTTP_NO_CONTENT),
    790     TALER_TESTING_cmd_merchant_post_products3 ("post-products-frac",
    791                                                merchant_url,
    792                                                "product-frac",
    793                                                "fractional product",
    794                                                json_pack ("{s:s}",
    795                                                           "en",
    796                                                           "fractional product"),
    797                                                "kg",
    798                                                "EUR:1.5",
    799                                                "",
    800                                                json_array (),
    801                                                1,
    802                                                (TALER_MERCHANT_UNIT_FRAC_BASE
    803                                                 * 3)
    804                                                / 4,
    805                                                true,
    806                                                0,
    807                                                NULL,
    808                                                GNUNET_TIME_UNIT_ZERO_TS,
    809                                                MHD_HTTP_NO_CONTENT),
    810     TALER_TESTING_cmd_merchant_get_product ("get-product-frac-post",
    811                                             merchant_url,
    812                                             "product-frac",
    813                                             MHD_HTTP_OK,
    814                                             "post-products-frac"),
    815     TALER_TESTING_cmd_merchant_patch_product_with_unit_prices (
    816       "patch-products-dup-currency",
    817       merchant_url,
    818       "product-3",
    819       "a product",
    820       "can",
    821       (const char *[]) { "EUR:1", "EUR:2" },
    822       2,
    823       MHD_HTTP_BAD_REQUEST),
    824     TALER_TESTING_cmd_merchant_patch_product ("patch-products-p3",
    825                                               merchant_url,
    826                                               "product-3",
    827                                               "a product",
    828                                               json_object (),
    829                                               "can",
    830                                               "EUR:1",
    831                                               "data:image/jpeg;base64,RAWDATA",
    832                                               json_array (),
    833                                               5,
    834                                               0,
    835                                               json_object (),
    836                                               GNUNET_TIME_relative_to_timestamp
    837                                               (
    838                                                 GNUNET_TIME_UNIT_MINUTES),
    839                                               MHD_HTTP_NO_CONTENT),
    840     TALER_TESTING_cmd_merchant_patch_product2 ("patch-product-frac",
    841                                                merchant_url,
    842                                                "product-frac",
    843                                                "fractional product patched",
    844                                                json_pack ("{s:s}",
    845                                                           "en",
    846                                                           "fractional product patched"),
    847                                                "kg",
    848                                                "EUR:1.6",
    849                                                "",
    850                                                json_array (),
    851                                                2,
    852                                                TALER_MERCHANT_UNIT_FRAC_BASE / 4
    853                                                ,
    854                                                true,
    855                                                0,
    856                                                json_object (),
    857                                                GNUNET_TIME_relative_to_timestamp
    858                                                (
    859                                                  GNUNET_TIME_UNIT_MINUTES),
    860                                                MHD_HTTP_NO_CONTENT),
    861     TALER_TESTING_cmd_merchant_get_product ("get-product-frac-patched",
    862                                             merchant_url,
    863                                             "product-frac",
    864                                             MHD_HTTP_OK,
    865                                             "patch-product-frac"),
    866     TALER_TESTING_cmd_merchant_delete_unit ("delete-unit-piece-denied",
    867                                             merchant_url,
    868                                             "Piece",
    869                                             MHD_HTTP_CONFLICT),
    870     TALER_TESTING_cmd_merchant_post_units ("post-unit-piece-conflict",
    871                                            merchant_url,
    872                                            "Piece",
    873                                            "piece",
    874                                            "pc",
    875                                            false,
    876                                            0,
    877                                            true,
    878                                            NULL,
    879                                            NULL,
    880                                            MHD_HTTP_CONFLICT),
    881     /* Per-instance override of a *builtin* unit (#12); only the policy
    882        flags may be changed, hence all name arguments must be NULL. */
    883     TALER_TESTING_cmd_merchant_patch_unit ("patch-unit-builtin",
    884                                            merchant_url,
    885                                            "SizeUnitCm",
    886                                            NULL,
    887                                            NULL,
    888                                            NULL,
    889                                            NULL,
    890                                            false,
    891                                            0,
    892                                            true,
    893                                            MHD_HTTP_NO_CONTENT),
    894     TALER_TESTING_cmd_merchant_get_unit ("get-unit-builtin-patched",
    895                                          merchant_url,
    896                                          "SizeUnitCm",
    897                                          MHD_HTTP_OK,
    898                                          "patch-unit-builtin"),
    899     /* second PATCH must update the existing override row */
    900     TALER_TESTING_cmd_merchant_patch_unit ("patch-unit-builtin-again",
    901                                            merchant_url,
    902                                            "SizeUnitCm",
    903                                            NULL,
    904                                            NULL,
    905                                            NULL,
    906                                            NULL,
    907                                            true,
    908                                            2,
    909                                            true,
    910                                            MHD_HTTP_NO_CONTENT),
    911     TALER_TESTING_cmd_merchant_get_unit ("get-unit-builtin-repatched",
    912                                          merchant_url,
    913                                          "SizeUnitCm",
    914                                          MHD_HTTP_OK,
    915                                          "patch-unit-builtin-again"),
    916     /* renaming a builtin unit remains a conflict */
    917     TALER_TESTING_cmd_merchant_patch_unit ("patch-unit-builtin-rename-denied",
    918                                            merchant_url,
    919                                            "SizeUnitCm",
    920                                            "centimetres",
    921                                            "cm",
    922                                            NULL,
    923                                            NULL,
    924                                            true,
    925                                            2,
    926                                            true,
    927                                            MHD_HTTP_CONFLICT),
    928     TALER_TESTING_cmd_merchant_post_units ("post-unit-bucket",
    929                                            merchant_url,
    930                                            "BucketCustomUnit",
    931                                            "bucket",
    932                                            "bkt",
    933                                            false,
    934                                            0,
    935                                            true,
    936                                            json_pack ("{s:s}", "en", "bucket"),
    937                                            json_pack ("{s:s}", "en", "bkt"),
    938                                            MHD_HTTP_NO_CONTENT),
    939     TALER_TESTING_cmd_merchant_get_unit ("get-unit-bucket",
    940                                          merchant_url,
    941                                          "BucketCustomUnit",
    942                                          MHD_HTTP_OK,
    943                                          "post-unit-bucket"),
    944     TALER_TESTING_cmd_merchant_get_units ("get-units-bucket-list",
    945                                           merchant_url,
    946                                           MHD_HTTP_OK,
    947                                           "post-unit-bucket",
    948                                           NULL),
    949     TALER_TESTING_cmd_merchant_patch_unit ("patch-unit-bucket",
    950                                            merchant_url,
    951                                            "BucketCustomUnit",
    952                                            "bucket-updated",
    953                                            "bkt-upd",
    954                                            json_pack ("{s:s}", "en",
    955                                                       "bucket-updated"),
    956                                            json_pack ("{s:s}", "en", "bkt-upd"),
    957                                            true,
    958                                            0,
    959                                            false,
    960                                            MHD_HTTP_NO_CONTENT),
    961     TALER_TESTING_cmd_merchant_get_unit ("get-unit-bucket-patched",
    962                                          merchant_url,
    963                                          "BucketCustomUnit",
    964                                          MHD_HTTP_OK,
    965                                          "patch-unit-bucket"),
    966     TALER_TESTING_cmd_merchant_get_units ("get-units-bucket-updated",
    967                                           merchant_url,
    968                                           MHD_HTTP_OK,
    969                                           "patch-unit-bucket",
    970                                           NULL),
    971     TALER_TESTING_cmd_merchant_delete_unit ("delete-unit-bucket",
    972                                             merchant_url,
    973                                             "BucketCustomUnit",
    974                                             MHD_HTTP_NO_CONTENT),
    975     TALER_TESTING_cmd_merchant_get_unit ("get-unit-bucket-deleted",
    976                                          merchant_url,
    977                                          "BucketCustomUnit",
    978                                          MHD_HTTP_NOT_FOUND,
    979                                          NULL),
    980     TALER_TESTING_cmd_merchant_post_units ("post-unit-unicorn",
    981                                            merchant_url,
    982                                            "UnitUnicorn",
    983                                            "unicorn",
    984                                            "uni",
    985                                            true,
    986                                            1,
    987                                            true,
    988                                            json_pack ("{s:s}", "en", "unicorn"),
    989                                            json_pack ("{s:s}", "en", "uni"),
    990                                            MHD_HTTP_NO_CONTENT),
    991     TALER_TESTING_cmd_merchant_post_products2 ("post-product-unicorn",
    992                                                merchant_url,
    993                                                "product-unicorn",
    994                                                "a unicorn snack",
    995                                                json_pack ("{s:s}",
    996                                                           "en",
    997                                                           "a unicorn snack"),
    998                                                "UnitUnicorn",
    999                                                "EUR:3.5",
   1000                                                "",
   1001                                                json_array (),
   1002                                                7,
   1003                                                0,
   1004                                                json_object (),
   1005                                                GNUNET_TIME_UNIT_ZERO_TS,
   1006                                                MHD_HTTP_NO_CONTENT),
   1007     TALER_TESTING_cmd_merchant_get_product2 ("get-product-unicorn-default",
   1008                                              merchant_url,
   1009                                              "product-unicorn",
   1010                                              MHD_HTTP_OK,
   1011                                              "post-product-unicorn",
   1012                                              &expect_unicorn_defaults),
   1013     TALER_TESTING_cmd_merchant_patch_unit ("patch-unit-unicorn",
   1014                                            merchant_url,
   1015                                            "UnitUnicorn",
   1016                                            NULL,
   1017                                            NULL,
   1018                                            NULL,
   1019                                            NULL,
   1020                                            false,
   1021                                            0,
   1022                                            true,
   1023                                            MHD_HTTP_NO_CONTENT),
   1024     TALER_TESTING_cmd_merchant_get_product2 ("get-product-unicorn-patched",
   1025                                              merchant_url,
   1026                                              "product-unicorn",
   1027                                              MHD_HTTP_OK,
   1028                                              "post-product-unicorn",
   1029                                              &expect_unicorn_patched),
   1030     TALER_TESTING_cmd_merchant_delete_product ("delete-product-unicorn",
   1031                                                merchant_url,
   1032                                                "product-unicorn",
   1033                                                MHD_HTTP_NO_CONTENT),
   1034     TALER_TESTING_cmd_merchant_delete_unit ("delete-unit-unicorn",
   1035                                             merchant_url,
   1036                                             "UnitUnicorn",
   1037                                             MHD_HTTP_NO_CONTENT),
   1038     TALER_TESTING_cmd_merchant_lock_product ("lock-product-p3",
   1039                                              merchant_url,
   1040                                              "product-3",
   1041                                              GNUNET_TIME_UNIT_MINUTES,
   1042                                              2,
   1043                                              MHD_HTTP_NO_CONTENT),
   1044     TALER_TESTING_cmd_merchant_lock_product2 (
   1045       "lock-product-p3-float-denied",
   1046       merchant_url,
   1047       "product-3",
   1048       GNUNET_TIME_UNIT_MINUTES,
   1049       1,
   1050       TALER_MERCHANT_UNIT_FRAC_BASE / 2,
   1051       true,
   1052       MHD_HTTP_BAD_REQUEST),
   1053     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-float-denied",
   1054                                              cred.cfg,
   1055                                              merchant_url,
   1056                                              MHD_HTTP_BAD_REQUEST,
   1057                                              "order-p3-float-denied",
   1058                                              GNUNET_TIME_UNIT_ZERO_TS,
   1059                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1060                                              true,
   1061                                              "EUR:5.0",
   1062                                              "x-taler-bank",
   1063                                              "product-3/1.5",
   1064                                              "",
   1065                                              NULL),
   1066     TALER_TESTING_cmd_merchant_patch_product2 (
   1067       "patch-product-3-allow-float",
   1068       merchant_url,
   1069       "product-3",
   1070       "a product allow fractional",
   1071       json_pack ("{s:s}",
   1072                  "en",
   1073                  "a product allow fractional"),
   1074       "can",
   1075       "EUR:1",
   1076       "data:image/jpeg;base64,RAWDATA",
   1077       json_array (),
   1078       5,
   1079       0,
   1080       true,
   1081       0,
   1082       json_object (),
   1083       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES),
   1084       MHD_HTTP_NO_CONTENT),
   1085     cmd_transfer_to_exchange ("create-reserve-p3-float",
   1086                               "EUR:5.01"),
   1087     cmd_exec_wirewatch ("wirewatch-p3-float"),
   1088     TALER_TESTING_cmd_check_bank_admin_transfer (
   1089       "check_bank_transfer-p3-float",
   1090       "EUR:5.01",
   1091       payer_payto,
   1092       exchange_payto,
   1093       "create-reserve-p3-float"),
   1094     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-p3-float",
   1095                                        "create-reserve-p3-float",
   1096                                        "EUR:5",
   1097                                        0,
   1098                                        MHD_HTTP_OK),
   1099     TALER_TESTING_cmd_merchant_lock_product2 (
   1100       "lock-product-p3-float",
   1101       merchant_url,
   1102       "product-3",
   1103       GNUNET_TIME_UNIT_MINUTES,
   1104       1,
   1105       TALER_MERCHANT_UNIT_FRAC_BASE / 2,
   1106       true,
   1107       MHD_HTTP_NO_CONTENT),
   1108     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-float",
   1109                                              cred.cfg,
   1110                                              merchant_url,
   1111                                              MHD_HTTP_OK,
   1112                                              "order-p3-float",
   1113                                              GNUNET_TIME_UNIT_ZERO_TS,
   1114                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1115                                              true,
   1116                                              "EUR:5.0",
   1117                                              "x-taler-bank",
   1118                                              "product-3/1.5",
   1119                                              "",
   1120                                              NULL),
   1121     TALER_TESTING_cmd_merchant_claim_order ("claim-order-p3-float",
   1122                                             merchant_url,
   1123                                             MHD_HTTP_OK,
   1124                                             "create-proposal-p3-float",
   1125                                             NULL),
   1126     TALER_TESTING_cmd_merchant_pay_order ("pay-order-p3-float",
   1127                                           merchant_url,
   1128                                           MHD_HTTP_OK,
   1129                                           "create-proposal-p3-float",
   1130                                           "withdraw-coin-p3-float",
   1131                                           "EUR:5",
   1132                                           "EUR:4.99",
   1133                                           "session-p3-float"),
   1134     TALER_TESTING_cmd_sleep (
   1135       "Wait for wire transfer deadline-p3-float",
   1136       3),
   1137     CMD_EXEC_AGGREGATOR ("run-aggregator-p3-float"),
   1138     TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-p3-float",
   1139                                            EXCHANGE_URL,
   1140                                            "EUR:4.98",
   1141                                            exchange_payto,
   1142                                            merchant_payto),
   1143     TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-p3-float-paid",
   1144                                           merchant_url,
   1145                                           "create-proposal-p3-float",
   1146                                           TALER_MERCHANT_OSC_PAID,
   1147                                           false,
   1148                                           MHD_HTTP_OK,
   1149                                           NULL),
   1150     TALER_TESTING_cmd_merchant_patch_product2 (
   1151       "patch-product-3-restore",
   1152       merchant_url,
   1153       "product-3",
   1154       "a product",
   1155       json_pack ("{s:s}",
   1156                  "en",
   1157                  "a product"),
   1158       "can",
   1159       "EUR:1",
   1160       "data:image/jpeg;base64,RAWDATA",
   1161       json_array (),
   1162       5,
   1163       0,
   1164       false,
   1165       0,
   1166       json_object (),
   1167       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES),
   1168       MHD_HTTP_NO_CONTENT),
   1169     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-wm-nx",
   1170                                              cred.cfg,
   1171                                              merchant_url,
   1172                                              MHD_HTTP_NOT_FOUND,
   1173                                              "order-p3",
   1174                                              GNUNET_TIME_UNIT_ZERO_TS,
   1175                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1176                                              true,
   1177                                              "EUR:5.0",
   1178                                              "unsupported-wire-method",
   1179                                              "product-3/2",
   1180                                              "", /* locks */
   1181                                              NULL),
   1182     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3-pd-nx",
   1183                                              cred.cfg,
   1184                                              merchant_url,
   1185                                              MHD_HTTP_NOT_FOUND,
   1186                                              "order-p3",
   1187                                              GNUNET_TIME_UNIT_ZERO_TS,
   1188                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1189                                              true,
   1190                                              "EUR:5.0",
   1191                                              "x-taler-bank",
   1192                                              "unknown-product/2",
   1193                                              "",
   1194                                              NULL),
   1195     TALER_TESTING_cmd_merchant_post_orders2 (
   1196       "create-proposal-p3-not-enough-stock",
   1197       cred.cfg,
   1198       merchant_url,
   1199       MHD_HTTP_GONE,
   1200       "order-p3",
   1201       GNUNET_TIME_UNIT_ZERO_TS,
   1202       GNUNET_TIME_UNIT_FOREVER_TS,
   1203       true,
   1204       "EUR:5.0",
   1205       "x-taler-bank",
   1206       "product-3/24",
   1207       "",
   1208       NULL),
   1209     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p3",
   1210                                              cred.cfg,
   1211                                              merchant_url,
   1212                                              MHD_HTTP_OK,
   1213                                              "order-p3",
   1214                                              GNUNET_TIME_UNIT_ZERO_TS,
   1215                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1216                                              false,
   1217                                              "EUR:5.0",
   1218                                              "x-taler-bank",
   1219                                              "product-3/3",
   1220                                              "lock-product-p3",
   1221                                              NULL),
   1222     TALER_TESTING_cmd_merchant_post_orders2 ("create-proposal-p4-age",
   1223                                              cred.cfg,
   1224                                              merchant_url,
   1225                                              MHD_HTTP_OK,
   1226                                              "order-p4-age",
   1227                                              GNUNET_TIME_UNIT_ZERO_TS,
   1228                                              GNUNET_TIME_UNIT_FOREVER_TS,
   1229                                              false,
   1230                                              "EUR:5.0",
   1231                                              "x-taler-bank",
   1232                                              "product-4age",
   1233                                              "", /* locks */
   1234                                              NULL),
   1235     TALER_TESTING_cmd_merchant_get_order4 ("get-order-merchant-p4-age",
   1236                                            merchant_url,
   1237                                            "create-proposal-p4-age",
   1238                                            TALER_MERCHANT_OSC_CLAIMED,
   1239                                            16,
   1240                                            MHD_HTTP_OK),
   1241     TALER_TESTING_cmd_merchant_delete_order ("delete-order-paid",
   1242                                              merchant_url,
   1243                                              "1",
   1244                                              MHD_HTTP_CONFLICT),
   1245     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-no-id",
   1246                                             cred.cfg,
   1247                                             merchant_url,
   1248                                             MHD_HTTP_OK,
   1249                                             NULL,
   1250                                             GNUNET_TIME_UNIT_ZERO_TS,
   1251                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1252                                             "EUR:5.0"),
   1253     TALER_TESTING_cmd_merchant_delete_webhook ("post-webhooks-pay-w1",
   1254                                                merchant_url,
   1255                                                "webhook-pay-1",
   1256                                                MHD_HTTP_NO_CONTENT),
   1257     TALER_TESTING_cmd_merchant_delete_webhook ("post-webhooks-settled-w1",
   1258                                                merchant_url,
   1259                                                "webhook-settled-1",
   1260                                                MHD_HTTP_NO_CONTENT),
   1261     TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-2"),
   1262     TALER_TESTING_cmd_end ()
   1263   };
   1264   struct TALER_TESTING_Command double_spending[] = {
   1265     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-2",
   1266                                             cred.cfg,
   1267                                             merchant_url,
   1268                                             MHD_HTTP_OK,
   1269                                             "2",
   1270                                             GNUNET_TIME_UNIT_ZERO_TS,
   1271                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1272                                             "EUR:5.0"),
   1273     TALER_TESTING_cmd_merchant_claim_order ("fetch-proposal-2",
   1274                                             merchant_url,
   1275                                             MHD_HTTP_OK,
   1276                                             "create-proposal-2",
   1277                                             NULL),
   1278     TALER_TESTING_cmd_merchant_pay_order ("deposit-double-2",
   1279                                           merchant_url,
   1280                                           MHD_HTTP_CONFLICT,
   1281                                           "create-proposal-2",
   1282                                           "withdraw-coin-1",
   1283                                           "EUR:5",
   1284                                           "EUR:4.99",
   1285                                           NULL),
   1286     TALER_TESTING_cmd_end ()
   1287   };
   1288 
   1289   const char *order_1r_refunds[] = {
   1290     "refund-increase-1r",
   1291     "refund-increase-1r-2",
   1292     NULL
   1293   };
   1294   struct TALER_TESTING_Command refund[] = {
   1295     cmd_transfer_to_exchange ("create-reserve-1r",
   1296                               "EUR:10.02"),
   1297     /**
   1298      * Make a reserve exist, according to the previous transfer.
   1299      */
   1300     cmd_exec_wirewatch ("wirewatch-1r"),
   1301     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-2r",
   1302                                                  "EUR:10.02",
   1303                                                  payer_payto,
   1304                                                  exchange_payto,
   1305                                                  "create-reserve-1r"),
   1306     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1r",
   1307                                        "create-reserve-1r",
   1308                                        "EUR:5",
   1309                                        0,
   1310                                        MHD_HTTP_OK),
   1311     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2r",
   1312                                        "create-reserve-1r",
   1313                                        "EUR:5",
   1314                                        0,
   1315                                        MHD_HTTP_OK),
   1316     /**
   1317      * Check the reserve is depleted.
   1318      */
   1319     TALER_TESTING_cmd_status ("withdraw-status-1r",
   1320                               "create-reserve-1r",
   1321                               "EUR:0",
   1322                               MHD_HTTP_OK),
   1323     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-1r",
   1324                                             cred.cfg,
   1325                                             merchant_url,
   1326                                             MHD_HTTP_OK,
   1327                                             "1r",
   1328                                             GNUNET_TIME_UNIT_ZERO_TS,
   1329                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1330                                             "EUR:5.0"),
   1331     TALER_TESTING_cmd_wallet_poll_order_start ("poll-order-wallet-refund-1-low",
   1332                                                merchant_url,
   1333                                                "create-proposal-1r",
   1334                                                POLL_ORDER_TIMEOUT,
   1335                                                "EUR:0.01"),
   1336     TALER_TESTING_cmd_wallet_poll_order_start (
   1337       "poll-order-wallet-refund-1-high",
   1338       merchant_url,
   1339       "create-proposal-1r",
   1340       POLL_ORDER_TIMEOUT,
   1341       "EUR:0.2"),
   1342     TALER_TESTING_cmd_merchant_pay_order ("pay-for-refund-1r",
   1343                                           merchant_url,
   1344                                           MHD_HTTP_OK,
   1345                                           "create-proposal-1r",
   1346                                           "withdraw-coin-1r",
   1347                                           "EUR:5",
   1348                                           "EUR:4.99",
   1349                                           NULL),
   1350     TALER_TESTING_cmd_poll_order_start ("poll-payment-refund-1",
   1351                                         merchant_url,
   1352                                         "1r", /* proposal name, not cmd ref! */
   1353                                         POLL_ORDER_TIMEOUT),
   1354     TALER_TESTING_cmd_merchant_order_refund ("refund-increase-1r",
   1355                                              merchant_url,
   1356                                              "refund test",
   1357                                              "1r", /* order ID */
   1358                                              "EUR:0.1",
   1359                                              MHD_HTTP_OK),
   1360     TALER_TESTING_cmd_wallet_poll_order_conclude ("poll-order-1-conclude-low",
   1361                                                   MHD_HTTP_OK,
   1362                                                   "EUR:0.1",
   1363                                                   "poll-order-wallet-refund-1-low"),
   1364     TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1r",
   1365                                         merchant_url,
   1366                                         "create-proposal-1r",
   1367                                         true,
   1368                                         true,
   1369                                         true,
   1370                                         MHD_HTTP_OK),
   1371     TALER_TESTING_cmd_merchant_order_refund ("refund-increase-1r-2",
   1372                                              merchant_url,
   1373                                              "refund test 2",
   1374                                              "1r", /* order ID */
   1375                                              "EUR:1.0",
   1376                                              MHD_HTTP_OK),
   1377     TALER_TESTING_cmd_wallet_poll_order_conclude ("poll-order-1-conclude-high",
   1378                                                   MHD_HTTP_OK,
   1379                                                   "EUR:1.0",
   1380                                                   "poll-order-wallet-refund-1-high"),
   1381     TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1r-2",
   1382                                         merchant_url,
   1383                                         "create-proposal-1r",
   1384                                         true,
   1385                                         true,
   1386                                         true,
   1387                                         MHD_HTTP_OK),
   1388     TALER_TESTING_cmd_wallet_order_refund ("obtain-refund-1r",
   1389                                            merchant_url,
   1390                                            "create-proposal-1r",
   1391                                            MHD_HTTP_OK,
   1392                                            "refund-increase-1r",
   1393                                            "refund-increase-1r-2",
   1394                                            NULL),
   1395     TALER_TESTING_cmd_wallet_get_order ("get-order-wallet-1r-3",
   1396                                         merchant_url,
   1397                                         "create-proposal-1r",
   1398                                         true,
   1399                                         true,
   1400                                         false,
   1401                                         MHD_HTTP_OK),
   1402     TALER_TESTING_cmd_merchant_get_order ("get-order-merchant-1r",
   1403                                           merchant_url,
   1404                                           "create-proposal-1r",
   1405                                           TALER_MERCHANT_OSC_PAID,
   1406                                           true,
   1407                                           MHD_HTTP_OK,
   1408                                           "refund-increase-1r",
   1409                                           "refund-increase-1r-2",
   1410                                           NULL),
   1411     TALER_TESTING_cmd_merchant_get_order2 ("get-order-merchant-1r-2",
   1412                                            merchant_url,
   1413                                            "create-proposal-1r",
   1414                                            TALER_MERCHANT_OSC_PAID,
   1415                                            false,
   1416                                            NULL,
   1417                                            true,
   1418                                            order_1r_refunds,
   1419                                            NULL,
   1420                                            MHD_HTTP_OK),
   1421     TALER_TESTING_cmd_poll_order_conclude ("poll-payment-refund-conclude-1",
   1422                                            MHD_HTTP_OK,
   1423                                            "poll-payment-refund-1"),
   1424 
   1425     /* Test /refund on a contract that was never paid.  */
   1426     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-not-to-be-paid",
   1427                                             cred.cfg,
   1428                                             merchant_url,
   1429                                             MHD_HTTP_OK,
   1430                                             "1-unpaid",
   1431                                             GNUNET_TIME_UNIT_ZERO_TS,
   1432                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1433                                             "EUR:5.0"),
   1434     /* Try to increase an unpaid proposal.  */
   1435     TALER_TESTING_cmd_merchant_order_refund ("refund-increase-unpaid-proposal",
   1436                                              merchant_url,
   1437                                              "refund test",
   1438                                              "1-unpaid",
   1439                                              "EUR:0.1",
   1440                                              MHD_HTTP_CONFLICT),
   1441     /* Try to increase a non existent proposal.  */
   1442     TALER_TESTING_cmd_merchant_order_refund (
   1443       "refund-increase-nonexistent-proposal",
   1444       merchant_url,
   1445       "refund test",
   1446       "non-existent-id",
   1447       "EUR:0.1",
   1448       MHD_HTTP_NOT_FOUND),
   1449     /*
   1450        The following block will (1) create a new
   1451        reserve, then (2) a proposal, then (3) pay for
   1452        it, and finally (4) attempt to pick up a refund
   1453        from it without any increasing taking place
   1454        in the first place.
   1455     */
   1456     cmd_transfer_to_exchange ("create-reserve-unincreased-refund",
   1457                               "EUR:5.01"),
   1458     cmd_exec_wirewatch ("wirewatch-unincreased-refund"),
   1459     TALER_TESTING_cmd_check_bank_admin_transfer (
   1460       "check_bank_transfer-unincreased-refund",
   1461       "EUR:5.01",
   1462       payer_payto,
   1463       exchange_payto,
   1464       "create-reserve-unincreased-refund"),
   1465     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-unincreased-refund",
   1466                                        "create-reserve-unincreased-refund",
   1467                                        "EUR:5",
   1468                                        0,
   1469                                        MHD_HTTP_OK),
   1470     TALER_TESTING_cmd_merchant_post_orders (
   1471       "create-proposal-unincreased-refund",
   1472       cred.cfg,
   1473       merchant_url,
   1474       MHD_HTTP_OK,
   1475       "unincreased-proposal",
   1476       GNUNET_TIME_UNIT_ZERO_TS,
   1477       GNUNET_TIME_UNIT_FOREVER_TS,
   1478       "EUR:5.0"),
   1479     TALER_TESTING_cmd_merchant_pay_order ("pay-unincreased-proposal",
   1480                                           merchant_url,
   1481                                           MHD_HTTP_OK,
   1482                                           "create-proposal-unincreased-refund",
   1483                                           "withdraw-coin-unincreased-refund",
   1484                                           "EUR:5",
   1485                                           "EUR:4.99",
   1486                                           NULL),
   1487     TALER_TESTING_cmd_sleep (
   1488       "Wait for wire transfer deadline",
   1489       3),
   1490     CMD_EXEC_AGGREGATOR ("run-aggregator-unincreased-refund"),
   1491     TALER_TESTING_cmd_check_bank_transfer (
   1492       "check_bank_transfer-paid-unincreased-refund",
   1493       EXCHANGE_URL,
   1494       "EUR:8.97", /* '4.98 from above', plus 4.99 from 'pay-for-refund-1r'
   1495                      and MINUS 0.1 MINUS 0.9 from
   1496                      'refund-increase-1r' and 'refund-increase-1r-2' */
   1497       exchange_payto,
   1498       merchant_payto),
   1499     TALER_TESTING_cmd_end ()
   1500   };
   1501 
   1502   struct TALER_TESTING_Command auth[] = {
   1503     TALER_TESTING_cmd_merchant_post_instances ("instance-create-i1a",
   1504                                                merchant_url,
   1505                                                "i1a",
   1506                                                MHD_HTTP_NO_CONTENT),
   1507     TALER_TESTING_cmd_merchant_post_account (
   1508       "instance-create-i1a-account",
   1509       merchant_url_i1a,
   1510       merchant_payto,
   1511       NULL, NULL,
   1512       MHD_HTTP_OK),
   1513     TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-1",
   1514                                             merchant_url_i1a,
   1515                                             "nx-product",
   1516                                             MHD_HTTP_NOT_FOUND,
   1517                                             NULL),
   1518     TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-1",
   1519                                              merchant_url_i1a,
   1520                                              MHD_HTTP_OK,
   1521                                              NULL),
   1522     TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-2",
   1523                                             merchant_url_i1a,
   1524                                             "nx-product",
   1525                                             MHD_HTTP_NOT_FOUND,
   1526                                             NULL),
   1527     TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-2",
   1528                                              merchant_url_i1a,
   1529                                              MHD_HTTP_OK,
   1530                                              NULL),
   1531     TALER_TESTING_cmd_merchant_post_instance_auth (
   1532       "instance-create-i1a-auth-ok",
   1533       merchant_url,
   1534       "i1a",
   1535       "my-secret",
   1536       MHD_HTTP_NO_CONTENT),
   1537     TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-3",
   1538                                             merchant_url_i1a,
   1539                                             "nx-product",
   1540                                             MHD_HTTP_UNAUTHORIZED,
   1541                                             NULL),
   1542     TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-3",
   1543                                              merchant_url_i1a,
   1544                                              MHD_HTTP_UNAUTHORIZED,
   1545                                              NULL),
   1546     TALER_TESTING_cmd_set_authorization ("set-auth-valid",
   1547                                          "Basic aTFhOm15LXNlY3JldA=="),
   1548     TALER_TESTING_cmd_merchant_post_instance_token (
   1549       "instance-create-i1a-token-ok",
   1550       merchant_url,
   1551       "i1a",
   1552       "write", /* scope */
   1553       GNUNET_TIME_UNIT_DAYS, /* duration */
   1554       GNUNET_YES, /* refreshable */
   1555       MHD_HTTP_OK),
   1556     TALER_TESTING_cmd_set_authorization ("unset-auth-valid",
   1557                                          NULL), // Unset header
   1558     TALER_TESTING_cmd_merchant_set_instance_token (
   1559       "instance-create-i1a-token-set",
   1560       "instance-create-i1a-token-ok"),
   1561     TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-4",
   1562                                             merchant_url_i1a,
   1563                                             "nx-product",
   1564                                             MHD_HTTP_NOT_FOUND,
   1565                                             NULL),
   1566     TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-4",
   1567                                              merchant_url_i1a,
   1568                                              MHD_HTTP_OK,
   1569                                              NULL),
   1570     TALER_TESTING_cmd_merchant_delete_instance_token (
   1571       "instance-create-i1a-token-delete",
   1572       merchant_url,
   1573       "i1a",
   1574       MHD_HTTP_NO_CONTENT),
   1575     TALER_TESTING_cmd_merchant_get_product ("get-nx-product-i1a-5",
   1576                                             merchant_url_i1a,
   1577                                             "nx-product",
   1578                                             MHD_HTTP_UNAUTHORIZED,
   1579                                             NULL),
   1580     TALER_TESTING_cmd_merchant_get_products ("get-i1a-products-empty-5",
   1581                                              merchant_url_i1a,
   1582                                              MHD_HTTP_UNAUTHORIZED,
   1583                                              NULL),
   1584     TALER_TESTING_cmd_merchant_purge_instance ("instance-delete-i1a-fail",
   1585                                                merchant_url_i1a,
   1586                                                NULL,
   1587                                                MHD_HTTP_UNAUTHORIZED),
   1588     TALER_TESTING_cmd_set_authorization ("set-token-auth-valid-again",
   1589                                          "Basic aTFhOm15LXNlY3JldA=="),
   1590     TALER_TESTING_cmd_merchant_post_instance_token (
   1591       "set-auth-valid-again",
   1592       merchant_url,
   1593       "i1a",
   1594       "write", /* scope */
   1595       GNUNET_TIME_UNIT_DAYS, /* duration */
   1596       GNUNET_YES, /* refreshable */
   1597       MHD_HTTP_OK),
   1598     TALER_TESTING_cmd_set_authorization ("unset-auth-valid2",
   1599                                          NULL), // Unset header
   1600     TALER_TESTING_cmd_merchant_set_instance_token (
   1601       "instance-create-i1a-token-set-again",
   1602       "set-auth-valid-again"),
   1603     TALER_TESTING_cmd_merchant_post_instance_auth (
   1604       "instance-create-i1a-auth-ok-idempotent",
   1605       merchant_url_i1a,
   1606       NULL,
   1607       RFC_8959_PREFIX "my-other-secret",
   1608       MHD_HTTP_NO_CONTENT),
   1609     TALER_TESTING_cmd_merchant_post_instance_auth (
   1610       "instance-create-i1a-clear-auth",
   1611       merchant_url_i1a,
   1612       NULL,
   1613       NULL,
   1614       MHD_HTTP_NO_CONTENT),
   1615     TALER_TESTING_cmd_set_authorization ("set-auth-none",
   1616                                          NULL),
   1617     TALER_TESTING_cmd_merchant_purge_instance ("instance-delete-i1a",
   1618                                                merchant_url_i1a,
   1619                                                NULL,
   1620                                                MHD_HTTP_NO_CONTENT),
   1621     TALER_TESTING_cmd_end ()
   1622   };
   1623 
   1624   struct TALER_TESTING_Command pay_again[] = {
   1625     cmd_transfer_to_exchange ("create-reserve-20",
   1626                               "EUR:20.04"),
   1627     cmd_exec_wirewatch ("wirewatch-20"),
   1628     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-10",
   1629                                                  "EUR:20.04",
   1630                                                  payer_payto,
   1631                                                  exchange_payto,
   1632                                                  "create-reserve-20"),
   1633     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-10a",
   1634                                        "create-reserve-20",
   1635                                        "EUR:5",
   1636                                        0,
   1637                                        MHD_HTTP_OK),
   1638     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-10b",
   1639                                        "create-reserve-20",
   1640                                        "EUR:5",
   1641                                        0,
   1642                                        MHD_HTTP_OK),
   1643     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-10c",
   1644                                        "create-reserve-20",
   1645                                        "EUR:5",
   1646                                        0,
   1647                                        MHD_HTTP_OK),
   1648     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-10d",
   1649                                        "create-reserve-20",
   1650                                        "EUR:5",
   1651                                        0,
   1652                                        MHD_HTTP_OK),
   1653     TALER_TESTING_cmd_status ("withdraw-status-20",
   1654                               "create-reserve-20",
   1655                               "EUR:0",
   1656                               MHD_HTTP_OK),
   1657     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-10",
   1658                                             cred.cfg,
   1659                                             merchant_url,
   1660                                             MHD_HTTP_OK,
   1661                                             "10",
   1662                                             GNUNET_TIME_UNIT_ZERO_TS,
   1663                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1664                                             "EUR:10.0"),
   1665     TALER_TESTING_cmd_merchant_pay_order ("pay-fail-partial-double-10",
   1666                                           merchant_url,
   1667                                           MHD_HTTP_CONFLICT,
   1668                                           "create-proposal-10",
   1669                                           "withdraw-coin-10a;withdraw-coin-1",
   1670                                           "EUR:5",
   1671                                           "EUR:4.99",
   1672                                           NULL),
   1673     TALER_TESTING_cmd_merchant_pay_order ("pay-again-10",
   1674                                           merchant_url,
   1675                                           MHD_HTTP_OK,
   1676                                           "create-proposal-10",
   1677                                           "withdraw-coin-10a;withdraw-coin-10b",
   1678                                           "EUR:5",
   1679                                           "EUR:4.99",
   1680                                           NULL),
   1681     TALER_TESTING_cmd_merchant_pay_order ("pay-too-much-10",
   1682                                           merchant_url,
   1683                                           MHD_HTTP_CONFLICT,
   1684                                           "create-proposal-10",
   1685                                           "withdraw-coin-10c;withdraw-coin-10d",
   1686                                           "EUR:5",
   1687                                           "EUR:4.99",
   1688                                           NULL),
   1689     TALER_TESTING_cmd_sleep (
   1690       "Wait for wire transfer deadline",
   1691       3),
   1692     CMD_EXEC_AGGREGATOR ("run-aggregator-10"),
   1693     TALER_TESTING_cmd_check_bank_transfer ("check_bank_transfer-9.97-10",
   1694                                            EXCHANGE_URL,
   1695                                            "EUR:9.97",
   1696                                            exchange_payto,
   1697                                            merchant_payto),
   1698     TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-10"),
   1699     TALER_TESTING_cmd_end ()
   1700   };
   1701 
   1702   struct TALER_TESTING_Command pay_abort[] = {
   1703     cmd_transfer_to_exchange ("create-reserve-11",
   1704                               "EUR:10.02"),
   1705     cmd_exec_wirewatch ("wirewatch-11"),
   1706     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-11",
   1707                                                  "EUR:10.02",
   1708                                                  payer_payto,
   1709                                                  exchange_payto,
   1710                                                  "create-reserve-11"),
   1711     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-11a",
   1712                                        "create-reserve-11",
   1713                                        "EUR:5",
   1714                                        0,
   1715                                        MHD_HTTP_OK),
   1716     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-11b",
   1717                                        "create-reserve-11",
   1718                                        "EUR:5",
   1719                                        0,
   1720                                        MHD_HTTP_OK),
   1721     TALER_TESTING_cmd_status ("withdraw-status-11",
   1722                               "create-reserve-11",
   1723                               "EUR:0",
   1724                               MHD_HTTP_OK),
   1725     TALER_TESTING_cmd_merchant_post_orders ("create-proposal-11",
   1726                                             cred.cfg,
   1727                                             merchant_url,
   1728                                             MHD_HTTP_OK,
   1729                                             "11",
   1730                                             GNUNET_TIME_UNIT_ZERO_TS,
   1731                                             GNUNET_TIME_UNIT_FOREVER_TS,
   1732                                             "EUR:10.0"),
   1733     TALER_TESTING_cmd_merchant_pay_order ("pay-fail-partial-double-11-good",
   1734                                           merchant_url,
   1735                                           MHD_HTTP_BAD_REQUEST,
   1736                                           "create-proposal-11",
   1737                                           "withdraw-coin-11a",
   1738                                           "EUR:5",
   1739                                           "EUR:4.99",
   1740                                           NULL),
   1741     TALER_TESTING_cmd_merchant_pay_order ("pay-fail-partial-double-11-bad",
   1742                                           merchant_url,
   1743                                           MHD_HTTP_CONFLICT,
   1744                                           "create-proposal-11",
   1745                                           "withdraw-coin-1",
   1746                                           "EUR:5",
   1747                                           "EUR:4.99",
   1748                                           NULL),
   1749     TALER_TESTING_cmd_merchant_order_abort ("pay-abort-11",
   1750                                             merchant_url,
   1751                                             "pay-fail-partial-double-11-good",
   1752                                             MHD_HTTP_OK),
   1753     TALER_TESTING_cmd_sleep (
   1754       "Wait for wire transfer deadline",
   1755       3),
   1756     CMD_EXEC_AGGREGATOR ("run-aggregator-11"),
   1757     TALER_TESTING_cmd_check_bank_empty ("check_bank_empty-11"),
   1758     TALER_TESTING_cmd_end ()
   1759   };
   1760 
   1761   struct TALER_TESTING_Command templates[] = {
   1762     cmd_transfer_to_exchange ("create-reserve-20x",
   1763                               "EUR:20.04"),
   1764     cmd_exec_wirewatch ("wirewatch-20x"),
   1765     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-20x",
   1766                                                  "EUR:20.04",
   1767                                                  payer_payto,
   1768                                                  exchange_payto,
   1769                                                  "create-reserve-20x"),
   1770     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xa",
   1771                                        "create-reserve-20x",
   1772                                        "EUR:5",
   1773                                        0,
   1774                                        MHD_HTTP_OK),
   1775     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xb",
   1776                                        "create-reserve-20x",
   1777                                        "EUR:5",
   1778                                        0,
   1779                                        MHD_HTTP_OK),
   1780     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xc",
   1781                                        "create-reserve-20x",
   1782                                        "EUR:5",
   1783                                        0,
   1784                                        MHD_HTTP_OK),
   1785     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-xd",
   1786                                        "create-reserve-20x",
   1787                                        "EUR:5",
   1788                                        0,
   1789                                        MHD_HTTP_OK),
   1790     TALER_TESTING_cmd_status ("withdraw-status-20x",
   1791                               "create-reserve-20x",
   1792                               "EUR:0",
   1793                               MHD_HTTP_OK),
   1794     TALER_TESTING_cmd_merchant_get_templates ("get-templates-empty",
   1795                                               merchant_url,
   1796                                               MHD_HTTP_OK,
   1797                                               NULL),
   1798     TALER_TESTING_cmd_merchant_post_templates ("post-templates-t1",
   1799                                                merchant_url,
   1800                                                "template-1",
   1801                                                "a template",
   1802                                                MHD_HTTP_NO_CONTENT),
   1803     TALER_TESTING_cmd_merchant_post_templates ("post-templates-t1-idem",
   1804                                                merchant_url,
   1805                                                "template-1",
   1806                                                "a template",
   1807                                                MHD_HTTP_NO_CONTENT),
   1808     TALER_TESTING_cmd_merchant_post_templates ("post-templates-t1-non-idem",
   1809                                                merchant_url,
   1810                                                "template-1",
   1811                                                "a different template",
   1812                                                MHD_HTTP_CONFLICT),
   1813     TALER_TESTING_cmd_merchant_get_templates ("get-templates-t1",
   1814                                               merchant_url,
   1815                                               MHD_HTTP_OK,
   1816                                               "post-templates-t1",
   1817                                               NULL),
   1818     TALER_TESTING_cmd_merchant_get_template ("get-template-t1",
   1819                                              merchant_url,
   1820                                              "template-1",
   1821                                              MHD_HTTP_OK,
   1822                                              "post-templates-t1"),
   1823     TALER_TESTING_cmd_merchant_post_templates ("post-templates-t2",
   1824                                                merchant_url,
   1825                                                "template-2",
   1826                                                "a template",
   1827                                                MHD_HTTP_NO_CONTENT),
   1828     TALER_TESTING_cmd_merchant_patch_template (
   1829       "patch-templates-t2",
   1830       merchant_url,
   1831       "template-2",
   1832       "another template",
   1833       NULL,
   1834       GNUNET_JSON_PACK (
   1835         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1836         GNUNET_JSON_pack_time_rel ("pay_duration",
   1837                                    GNUNET_TIME_UNIT_MINUTES)),
   1838       MHD_HTTP_NO_CONTENT),
   1839     TALER_TESTING_cmd_merchant_get_template ("get-template-t2",
   1840                                              merchant_url,
   1841                                              "template-2",
   1842                                              MHD_HTTP_OK,
   1843                                              "patch-templates-t2"),
   1844     TALER_TESTING_cmd_merchant_get_template ("get-template-nx",
   1845                                              merchant_url,
   1846                                              "template-nx",
   1847                                              MHD_HTTP_NOT_FOUND,
   1848                                              NULL),
   1849     TALER_TESTING_cmd_merchant_post_otp_devices (
   1850       "post-otp-device",
   1851       merchant_url,
   1852       "otp-dev",
   1853       "my OTP device",
   1854       "FEE4P2J",
   1855       TALER_MCA_WITH_PRICE,
   1856       0,
   1857       MHD_HTTP_NO_CONTENT),
   1858     TALER_TESTING_cmd_merchant_patch_template (
   1859       "patch-templates-t3-nx",
   1860       merchant_url,
   1861       "template-3",
   1862       "updated template",
   1863       "otp-dev",
   1864       GNUNET_JSON_PACK (
   1865         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1866         GNUNET_JSON_pack_time_rel ("pay_duration",
   1867                                    GNUNET_TIME_UNIT_MINUTES)),
   1868       MHD_HTTP_NOT_FOUND),
   1869     /* Bind template-2 to an existing OTP device ... */
   1870     TALER_TESTING_cmd_merchant_patch_template (
   1871       "patch-templates-t2-otp",
   1872       merchant_url,
   1873       "template-2",
   1874       "a template with an OTP device",
   1875       "otp-dev",
   1876       GNUNET_JSON_PACK (
   1877         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1878         GNUNET_JSON_pack_time_rel ("pay_duration",
   1879                                    GNUNET_TIME_UNIT_MINUTES)),
   1880       MHD_HTTP_NO_CONTENT),
   1881     /* ... a PATCH naming an unknown OTP device must be refused
   1882        with 404 and must NOT clear the existing binding (#5) */
   1883     TALER_TESTING_cmd_merchant_patch_template (
   1884       "patch-templates-t2-otp-nx",
   1885       merchant_url,
   1886       "template-2",
   1887       "a template that must not be stored",
   1888       "otp-dev-nx",
   1889       GNUNET_JSON_PACK (
   1890         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   1891         GNUNET_JSON_pack_time_rel ("pay_duration",
   1892                                    GNUNET_TIME_UNIT_MINUTES)),
   1893       MHD_HTTP_NOT_FOUND),
   1894     /* ... hence the template must still match the successful PATCH */
   1895     TALER_TESTING_cmd_merchant_get_template ("get-template-t2-otp",
   1896                                              merchant_url,
   1897                                              "template-2",
   1898                                              MHD_HTTP_OK,
   1899                                              "patch-templates-t2-otp"),
   1900     TALER_TESTING_cmd_merchant_post_templates2 (
   1901       "post-templates-t3-amount",
   1902       merchant_url,
   1903       "template-amount",
   1904       "a different template with an amount",
   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_MINUTES),
   1910         GNUNET_JSON_pack_string ("amount",
   1911                                  "EUR:4")),
   1912       MHD_HTTP_NO_CONTENT),
   1913     TALER_TESTING_cmd_merchant_post_using_templates (
   1914       "using-templates-t1",
   1915       "post-templates-t1",
   1916       NULL,
   1917       merchant_url,
   1918       "1",
   1919       "summary-1",
   1920       "EUR:9.98",
   1921       GNUNET_TIME_UNIT_ZERO_TS,
   1922       GNUNET_TIME_UNIT_FOREVER_TS,
   1923       MHD_HTTP_OK),
   1924     TALER_TESTING_cmd_merchant_post_using_templates (
   1925       "using-templates-t1-amount-missing",
   1926       "post-templates-t1",
   1927       NULL,
   1928       merchant_url,
   1929       "2",
   1930       "summary-1",
   1931       NULL,
   1932       GNUNET_TIME_UNIT_ZERO_TS,
   1933       GNUNET_TIME_UNIT_FOREVER_TS,
   1934       MHD_HTTP_CONFLICT),
   1935     TALER_TESTING_cmd_merchant_post_using_templates (
   1936       "using-templates-t1-summary-missing",
   1937       "post-templates-t1",
   1938       NULL,
   1939       merchant_url,
   1940       "3",
   1941       NULL,
   1942       "EUR:10",
   1943       GNUNET_TIME_UNIT_ZERO_TS,
   1944       GNUNET_TIME_UNIT_FOREVER_TS,
   1945       MHD_HTTP_CONFLICT),
   1946     TALER_TESTING_cmd_merchant_post_using_templates (
   1947       "using-templates-t1-amount-conflict",
   1948       "post-templates-t3-amount",
   1949       NULL,
   1950       merchant_url,
   1951       "4",
   1952       "summary-1",
   1953       "EUR:10",
   1954       GNUNET_TIME_UNIT_ZERO_TS,
   1955       GNUNET_TIME_UNIT_FOREVER_TS,
   1956       MHD_HTTP_CONFLICT),
   1957     TALER_TESTING_cmd_merchant_post_using_templates (
   1958       "using-templates-t1-amount-duplicate",
   1959       "post-templates-t3-amount",
   1960       NULL,
   1961       merchant_url,
   1962       "4",
   1963       "summary-1",
   1964       "EUR:4",
   1965       GNUNET_TIME_UNIT_ZERO_TS,
   1966       GNUNET_TIME_UNIT_FOREVER_TS,
   1967       MHD_HTTP_CONFLICT),
   1968     TALER_TESTING_cmd_merchant_pay_order ("pay-100",
   1969                                           merchant_url,
   1970                                           MHD_HTTP_OK,
   1971                                           "using-templates-t1",
   1972                                           "withdraw-coin-xa;withdraw-coin-xb",
   1973                                           "EUR:4.99",
   1974                                           "EUR:4.99",
   1975                                           NULL),
   1976     TALER_TESTING_cmd_merchant_delete_template ("get-templates-empty",
   1977                                                 merchant_url,
   1978                                                 "t1",
   1979                                                 MHD_HTTP_NOT_FOUND),
   1980     TALER_TESTING_cmd_merchant_delete_template ("get-templates-empty",
   1981                                                 merchant_url,
   1982                                                 "template-1",
   1983                                                 MHD_HTTP_NO_CONTENT),
   1984     TALER_TESTING_cmd_merchant_post_using_templates (
   1985       "post-templates-t1-deleted",
   1986       "post-templates-t1",
   1987       NULL,
   1988       merchant_url,
   1989       "0",
   1990       "summary-1",
   1991       "EUR:5",
   1992       GNUNET_TIME_UNIT_ZERO_TS,
   1993       GNUNET_TIME_UNIT_FOREVER_TS,
   1994       MHD_HTTP_NOT_FOUND),
   1995     TALER_TESTING_cmd_merchant_post_otp_devices (
   1996       "post-otp-device",
   1997       merchant_url,
   1998       "otp-dev-2",
   1999       "my OTP device",
   2000       "secret",
   2001       TALER_MCA_WITH_PRICE,
   2002       0,
   2003       MHD_HTTP_NO_CONTENT),
   2004     TALER_TESTING_cmd_merchant_post_templates2 (
   2005       "post-templates-with-pos-key",
   2006       merchant_url,
   2007       "template-key",
   2008       "a different template with POS KEY",
   2009       "otp-dev-2",
   2010       GNUNET_JSON_PACK (
   2011         GNUNET_JSON_pack_uint64 ("minimum_age", 0),
   2012         GNUNET_JSON_pack_time_rel ("pay_duration",
   2013                                    GNUNET_TIME_UNIT_MINUTES)),
   2014       MHD_HTTP_NO_CONTENT),
   2015 
   2016     TALER_TESTING_cmd_merchant_post_using_templates (
   2017       "using-templates-pos-key",
   2018       "post-templates-with-pos-key",
   2019       "post-otp-device",
   2020       merchant_url,
   2021       "1",
   2022       "summary-1-pos",
   2023       "EUR:9.98",
   2024       GNUNET_TIME_UNIT_ZERO_TS,
   2025       GNUNET_TIME_UNIT_FOREVER_TS,
   2026       MHD_HTTP_OK),
   2027     TALER_TESTING_cmd_merchant_pay_order ("pay-with-pos",
   2028                                           merchant_url,
   2029                                           MHD_HTTP_OK,
   2030                                           "using-templates-pos-key",
   2031                                           "withdraw-coin-xc;withdraw-coin-xd",
   2032                                           "EUR:4.99",
   2033                                           "EUR:4.99",
   2034                                           NULL),
   2035     cmd_transfer_to_exchange ("create-reserve-20y",
   2036                               "EUR:10.02"),
   2037     cmd_exec_wirewatch ("wirewatch-20y"),
   2038     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-20y",
   2039                                                  "EUR:10.02",
   2040                                                  payer_payto,
   2041                                                  exchange_payto,
   2042                                                  "create-reserve-20y"),
   2043     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-yk",
   2044                                        "create-reserve-20y",
   2045                                        "EUR:5",
   2046                                        0,
   2047                                        MHD_HTTP_OK),
   2048     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-ykb",
   2049                                        "create-reserve-20y",
   2050                                        "EUR:5",
   2051                                        0,
   2052                                        MHD_HTTP_OK),
   2053     TALER_TESTING_cmd_status ("withdraw-status-20y",
   2054                               "create-reserve-20y",
   2055                               "EUR:0",
   2056                               MHD_HTTP_OK),
   2057     TALER_TESTING_cmd_merchant_post_products_with_unit_prices (
   2058       "post-products-inv-1",
   2059       merchant_url,
   2060       "inv-product-1",
   2061       "Inventory Product One",
   2062       "test-unit",
   2063       (const char *[]) { "EUR:1", "KUDOS:1" },
   2064       2,
   2065       MHD_HTTP_NO_CONTENT),
   2066     TALER_TESTING_cmd_merchant_post_products_with_unit_prices (
   2067       "post-products-inv-2",
   2068       merchant_url,
   2069       "inv-product-2",
   2070       "Inventory Product Two",
   2071       "test-unit",
   2072       (const char *[]) { "EUR:2", "KUDOS:2" },
   2073       2,
   2074       MHD_HTTP_NO_CONTENT),
   2075     TALER_TESTING_cmd_merchant_post_templates2 (
   2076       "post-templates-inv-one",
   2077       merchant_url,
   2078       "template-inv-one",
   2079       "inventory template one",
   2080       NULL,
   2081       GNUNET_JSON_PACK (
   2082         GNUNET_JSON_pack_string ("template_type",
   2083                                  "inventory-cart"),
   2084         GNUNET_JSON_pack_string ("summary",
   2085                                  "inventory template"),
   2086         GNUNET_JSON_pack_time_rel ("pay_duration",
   2087                                    GNUNET_TIME_UNIT_MINUTES),
   2088         GNUNET_JSON_pack_array_steal (
   2089           "selected_products",
   2090           make_selected_products ("inv-product-1",
   2091                                   "inv-product-2")),
   2092         GNUNET_JSON_pack_bool ("choose_one",
   2093                                true)),
   2094       MHD_HTTP_NO_CONTENT),
   2095     TALER_TESTING_cmd_merchant_wallet_get_template (
   2096       "wallet-get-template-inv-one",
   2097       merchant_url,
   2098       "template-inv-one",
   2099       0,
   2100       NULL,
   2101       NULL,
   2102       false,
   2103       0,
   2104       NULL,
   2105       NULL,
   2106       NULL,
   2107       0,
   2108       0,
   2109       MHD_HTTP_OK),
   2110     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2111       "using-templates-inv-one",
   2112       "post-templates-inv-one",
   2113       NULL,
   2114       merchant_url,
   2115       "inv-1",
   2116       GNUNET_JSON_PACK (
   2117         GNUNET_JSON_pack_string ("amount",
   2118                                  "EUR:1"),
   2119         GNUNET_JSON_pack_string ("template_type",
   2120                                  "inventory-cart"),
   2121         GNUNET_JSON_pack_array_steal (
   2122           "inventory_selection",
   2123           make_inventory_selection ("inv-product-1",
   2124                                     "1.0",
   2125                                     NULL,
   2126                                     NULL))),
   2127       MHD_HTTP_OK),
   2128     TALER_TESTING_cmd_merchant_post_templates2 (
   2129       "post-templates-inv-multi",
   2130       merchant_url,
   2131       "template-inv-multi",
   2132       "inventory template multi",
   2133       NULL,
   2134       GNUNET_JSON_PACK (
   2135         GNUNET_JSON_pack_string ("template_type",
   2136                                  "inventory-cart"),
   2137         GNUNET_JSON_pack_string ("summary",
   2138                                  "inventory template multi"),
   2139         GNUNET_JSON_pack_time_rel ("pay_duration",
   2140                                    GNUNET_TIME_UNIT_MINUTES),
   2141         GNUNET_JSON_pack_array_steal (
   2142           "selected_products",
   2143           make_selected_products ("inv-product-1",
   2144                                   "inv-product-2"))),
   2145       MHD_HTTP_NO_CONTENT),
   2146     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2147       "using-templates-inv-multi",
   2148       "post-templates-inv-multi",
   2149       NULL,
   2150       merchant_url,
   2151       "inv-2",
   2152       GNUNET_JSON_PACK (
   2153         GNUNET_JSON_pack_string ("amount",
   2154                                  "EUR:3"),
   2155         GNUNET_JSON_pack_string ("template_type",
   2156                                  "inventory-cart"),
   2157         GNUNET_JSON_pack_array_steal (
   2158           "inventory_selection",
   2159           make_inventory_selection ("inv-product-1",
   2160                                     "1.0",
   2161                                     "inv-product-2",
   2162                                     "1.0"))),
   2163       MHD_HTTP_OK),
   2164     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2165       "using-templates-inv-one-empty",
   2166       "post-templates-inv-one",
   2167       NULL,
   2168       merchant_url,
   2169       "inv-1-empty",
   2170       GNUNET_JSON_PACK (
   2171         GNUNET_JSON_pack_string ("amount",
   2172                                  "EUR:1"),
   2173         GNUNET_JSON_pack_string ("template_type",
   2174                                  "inventory-cart"),
   2175         GNUNET_JSON_pack_array_steal (
   2176           "inventory_selection",
   2177           json_array ())),
   2178       MHD_HTTP_CONFLICT),
   2179     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2180       "using-templates-inv-one-two",
   2181       "post-templates-inv-one",
   2182       NULL,
   2183       merchant_url,
   2184       "inv-1-two",
   2185       GNUNET_JSON_PACK (
   2186         GNUNET_JSON_pack_string ("amount",
   2187                                  "EUR:3"),
   2188         GNUNET_JSON_pack_string ("template_type",
   2189                                  "inventory-cart"),
   2190         GNUNET_JSON_pack_array_steal (
   2191           "inventory_selection",
   2192           make_inventory_selection ("inv-product-1",
   2193                                     "1.0",
   2194                                     "inv-product-2",
   2195                                     "1.0"))),
   2196       MHD_HTTP_CONFLICT),
   2197     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2198       "using-templates-inv-one-tip",
   2199       "post-templates-inv-one",
   2200       NULL,
   2201       merchant_url,
   2202       "inv-1-tip",
   2203       GNUNET_JSON_PACK (
   2204         GNUNET_JSON_pack_string ("amount",
   2205                                  "EUR:1"),
   2206         GNUNET_JSON_pack_string ("tip",
   2207                                  "EUR:1"),
   2208         GNUNET_JSON_pack_string ("template_type",
   2209                                  "inventory-cart"),
   2210         GNUNET_JSON_pack_array_steal (
   2211           "inventory_selection",
   2212           make_inventory_selection ("inv-product-1",
   2213                                     "1.0",
   2214                                     NULL,
   2215                                     NULL))),
   2216       MHD_HTTP_CONFLICT),
   2217     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2218       "using-templates-inv-one-tip-ok",
   2219       "post-templates-inv-one",
   2220       NULL,
   2221       merchant_url,
   2222       "inv-1-tip-ok",
   2223       GNUNET_JSON_PACK (
   2224         GNUNET_JSON_pack_string ("amount",
   2225                                  "EUR:2"),
   2226         GNUNET_JSON_pack_string ("tip",
   2227                                  "EUR:1"),
   2228         GNUNET_JSON_pack_string ("template_type",
   2229                                  "inventory-cart"),
   2230         GNUNET_JSON_pack_array_steal (
   2231           "inventory_selection",
   2232           make_inventory_selection ("inv-product-1",
   2233                                     "1.0",
   2234                                     NULL,
   2235                                     NULL))),
   2236       MHD_HTTP_OK),
   2237     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2238       "using-templates-inv-one-unknown",
   2239       "post-templates-inv-one",
   2240       NULL,
   2241       merchant_url,
   2242       "inv-1-unknown",
   2243       GNUNET_JSON_PACK (
   2244         GNUNET_JSON_pack_string ("amount",
   2245                                  "EUR:1"),
   2246         GNUNET_JSON_pack_string ("template_type",
   2247                                  "inventory-cart"),
   2248         GNUNET_JSON_pack_array_steal (
   2249           "inventory_selection",
   2250           make_inventory_selection ("inv-product-404",
   2251                                     "1.0",
   2252                                     NULL,
   2253                                     NULL))),
   2254       MHD_HTTP_NOT_FOUND),
   2255     TALER_TESTING_cmd_merchant_post_templates2 (
   2256       "post-templates-inv-only",
   2257       merchant_url,
   2258       "template-inv-only",
   2259       "inventory template only",
   2260       NULL,
   2261       GNUNET_JSON_PACK (
   2262         GNUNET_JSON_pack_string ("template_type",
   2263                                  "inventory-cart"),
   2264         GNUNET_JSON_pack_string ("summary",
   2265                                  "inventory template only"),
   2266         GNUNET_JSON_pack_time_rel ("pay_duration",
   2267                                    GNUNET_TIME_UNIT_MINUTES),
   2268         GNUNET_JSON_pack_array_steal (
   2269           "selected_products",
   2270           make_selected_products ("inv-product-1",
   2271                                   NULL))),
   2272       MHD_HTTP_NO_CONTENT),
   2273     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2274       "using-templates-inv-only-wrong",
   2275       "post-templates-inv-only",
   2276       NULL,
   2277       merchant_url,
   2278       "inv-only-wrong",
   2279       GNUNET_JSON_PACK (
   2280         GNUNET_JSON_pack_string ("amount",
   2281                                  "EUR:2"),
   2282         GNUNET_JSON_pack_string ("template_type",
   2283                                  "inventory-cart"),
   2284         GNUNET_JSON_pack_array_steal (
   2285           "inventory_selection",
   2286           make_inventory_selection ("inv-product-2",
   2287                                     "1.0",
   2288                                     NULL,
   2289                                     NULL))),
   2290       MHD_HTTP_CONFLICT),
   2291     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2292       "using-templates-inv-multi-amount-mismatch",
   2293       "post-templates-inv-multi",
   2294       NULL,
   2295       merchant_url,
   2296       "inv-2-mismatch",
   2297       GNUNET_JSON_PACK (
   2298         GNUNET_JSON_pack_string ("amount",
   2299                                  "EUR:4"),
   2300         GNUNET_JSON_pack_string ("template_type",
   2301                                  "inventory-cart"),
   2302         GNUNET_JSON_pack_array_steal (
   2303           "inventory_selection",
   2304           make_inventory_selection ("inv-product-1",
   2305                                     "1.0",
   2306                                     "inv-product-2",
   2307                                     "1.0"))),
   2308       MHD_HTTP_CONFLICT),
   2309     TALER_TESTING_cmd_merchant_post_units ("post-unit-special",
   2310                                            merchant_url,
   2311                                            "special-unit",
   2312                                            "Special Unit",
   2313                                            "sunit",
   2314                                            true,
   2315                                            1,
   2316                                            true,
   2317                                            json_pack ("{s:s}",
   2318                                                       "en",
   2319                                                       "Special Unit"),
   2320                                            json_pack ("{s:s}",
   2321                                                       "en",
   2322                                                       "sunit"),
   2323                                            MHD_HTTP_NO_CONTENT),
   2324     TALER_TESTING_cmd_merchant_post_categories ("post-category-special",
   2325                                                 merchant_url,
   2326                                                 "Category Special",
   2327                                                 json_pack ("{s:s}",
   2328                                                            "en",
   2329                                                            "Category Special"),
   2330                                                 1,
   2331                                                 MHD_HTTP_OK),
   2332     TALER_TESTING_cmd_merchant_post_categories ("post-category-special-2",
   2333                                                 merchant_url,
   2334                                                 "Category Special Two",
   2335                                                 json_pack ("{s:s}",
   2336                                                            "en",
   2337                                                            "Category Special Two"),
   2338                                                 2,
   2339                                                 MHD_HTTP_OK),
   2340     TALER_TESTING_cmd_merchant_post_products_with_categories (
   2341       "post-products-inv-unit-1",
   2342       merchant_url,
   2343       "inv-unit-product-1",
   2344       "Inventory Unit Product One",
   2345       "special-unit",
   2346       "EUR:5",
   2347       1,
   2348       (const uint64_t[]) { 1 },
   2349       true,
   2350       1,
   2351       MHD_HTTP_NO_CONTENT),
   2352     TALER_TESTING_cmd_merchant_post_products2 (
   2353       "post-products-inv-unit-2",
   2354       merchant_url,
   2355       "inv-unit-product-2",
   2356       "Inventory Unit Product Two",
   2357       json_pack ("{s:s}", "en", "Inventory Unit Product Two"),
   2358       "test-unit",
   2359       "EUR:1.2",
   2360       "",
   2361       json_array (),
   2362       -1, /* total stock: infinite */
   2363       0,  /* minimum age */
   2364       json_pack ("{s:s}", "street", "my street"),
   2365       GNUNET_TIME_UNIT_ZERO_TS,
   2366       MHD_HTTP_NO_CONTENT),
   2367     TALER_TESTING_cmd_merchant_post_products_with_categories (
   2368       "post-products-inv-unit-3",
   2369       merchant_url,
   2370       "inv-unit-product-3",
   2371       "Inventory Unit Product Three",
   2372       "test-unit",
   2373       "EUR:9",
   2374       1,
   2375       (const uint64_t[]) { 2 },
   2376       false,
   2377       0,
   2378       MHD_HTTP_NO_CONTENT),
   2379     TALER_TESTING_cmd_merchant_post_templates2 (
   2380       "post-templates-inv-cat-prod-unit",
   2381       merchant_url,
   2382       "template-inv-cat-prod-unit",
   2383       "inventory template category+product unit",
   2384       NULL,
   2385       GNUNET_JSON_PACK (
   2386         GNUNET_JSON_pack_string ("template_type",
   2387                                  "inventory-cart"),
   2388         GNUNET_JSON_pack_string ("summary",
   2389                                  "inventory template category+product unit"),
   2390         GNUNET_JSON_pack_time_rel ("pay_duration",
   2391                                    GNUNET_TIME_UNIT_MINUTES),
   2392         GNUNET_JSON_pack_array_steal (
   2393           "selected_categories",
   2394           make_selected_categories (1,
   2395                                     0)),
   2396         GNUNET_JSON_pack_array_steal (
   2397           "selected_products",
   2398           make_selected_products ("inv-unit-product-2",
   2399                                   "inv-unit-product-3"))),
   2400       MHD_HTTP_NO_CONTENT),
   2401     TALER_TESTING_cmd_merchant_wallet_get_template (
   2402       "wallet-get-template-inv-cat-prod-unit",
   2403       merchant_url,
   2404       "template-inv-cat-prod-unit",
   2405       3,
   2406       "inv-unit-product-1",
   2407       "special-unit",
   2408       true,
   2409       1,
   2410       json_pack ("{s:s}",
   2411                  "en",
   2412                  "sunit"),
   2413       "inv-unit-product-2",
   2414       "inv-unit-product-3",
   2415       1,
   2416       2,
   2417       MHD_HTTP_OK),
   2418     TALER_TESTING_cmd_merchant_post_using_templates2 (
   2419       "using-templates-inv-cat-prod-unit",
   2420       "post-templates-inv-cat-prod-unit",
   2421       NULL,
   2422       merchant_url,
   2423       "inv-cat-prod-unit",
   2424       GNUNET_JSON_PACK (
   2425         GNUNET_JSON_pack_string ("amount",
   2426                                  "EUR:3.2"),
   2427         GNUNET_JSON_pack_string ("template_type",
   2428                                  "inventory-cart"),
   2429         GNUNET_JSON_pack_array_steal (
   2430           "inventory_selection",
   2431           make_inventory_selection ("inv-unit-product-1",
   2432                                     "0.4",
   2433                                     "inv-unit-product-2",
   2434                                     "1"))),
   2435       MHD_HTTP_OK),
   2436     TALER_TESTING_cmd_merchant_pay_order_choices (
   2437       "pay-inv-cat-prod-unit",
   2438       merchant_url,
   2439       MHD_HTTP_OK,
   2440       "using-templates-inv-cat-prod-unit",
   2441       "withdraw-coin-yk",
   2442       "EUR:3.2",
   2443       "EUR:3.2",
   2444       NULL,
   2445       0,
   2446       NULL),
   2447 
   2448 
   2449     TALER_TESTING_cmd_end ()
   2450   };
   2451 
   2452   struct TALER_TESTING_Command webhooks[] = {
   2453     TALER_TESTING_cmd_merchant_get_webhooks ("get-webhooks-empty",
   2454                                              merchant_url,
   2455                                              MHD_HTTP_OK,
   2456                                              NULL),
   2457     TALER_TESTING_cmd_merchant_post_webhooks ("post-webhooks-w1",
   2458                                               merchant_url,
   2459                                               "webhook-1",
   2460                                               "Paid",
   2461                                               MHD_HTTP_NO_CONTENT),
   2462     TALER_TESTING_cmd_merchant_post_webhooks ("post-webhooks-w1-idem",
   2463                                               merchant_url,
   2464                                               "webhook-1",
   2465                                               "Paid",
   2466                                               MHD_HTTP_NO_CONTENT),
   2467     TALER_TESTING_cmd_merchant_post_webhooks ("post-webhooks-w1-non-idem",
   2468                                               merchant_url,
   2469                                               "webhook-1",
   2470                                               "Refund",
   2471                                               MHD_HTTP_CONFLICT),
   2472     TALER_TESTING_cmd_merchant_get_webhooks ("get-webhooks-w1",
   2473                                              merchant_url,
   2474                                              MHD_HTTP_OK,
   2475                                              "post-webhooks-w1",
   2476                                              NULL),
   2477     TALER_TESTING_cmd_merchant_get_webhook ("get-webhook-w1",
   2478                                             merchant_url,
   2479                                             "webhook-1",
   2480                                             MHD_HTTP_OK,
   2481                                             "post-webhooks-w1"),
   2482     TALER_TESTING_cmd_merchant_post_webhooks ("post-webhooks-w2",
   2483                                               merchant_url,
   2484                                               "webhook-2",
   2485                                               "Paid",
   2486                                               MHD_HTTP_NO_CONTENT),
   2487     TALER_TESTING_cmd_merchant_patch_webhook ("patch-webhooks-w2",
   2488                                               merchant_url,
   2489                                               "webhook-2",
   2490                                               "Refund2",
   2491                                               "http://localhost:38188/",
   2492                                               "POST",
   2493                                               "Authorization:WHWOXZXPLL",
   2494                                               "Amount",
   2495                                               MHD_HTTP_NO_CONTENT),
   2496     TALER_TESTING_cmd_merchant_get_webhook ("get-webhook-w2",
   2497                                             merchant_url,
   2498                                             "webhook-2",
   2499                                             MHD_HTTP_OK,
   2500                                             "patch-webhooks-w2"),
   2501     TALER_TESTING_cmd_merchant_get_webhook ("get-webhook-nx",
   2502                                             merchant_url,
   2503                                             "webhook-nx",
   2504                                             MHD_HTTP_NOT_FOUND,
   2505                                             NULL),
   2506     TALER_TESTING_cmd_merchant_patch_webhook ("patch-webhooks-w3-nx",
   2507                                               merchant_url,
   2508                                               "webhook-3",
   2509                                               "Paid2",
   2510                                               "https://example.com",
   2511                                               "POST",
   2512                                               "Authorization:WHWOXZXPLL",
   2513                                               "Amount",
   2514                                               MHD_HTTP_NOT_FOUND),
   2515     TALER_TESTING_cmd_merchant_delete_webhook ("get-webhooks-empty",
   2516                                                merchant_url,
   2517                                                "w1",
   2518                                                MHD_HTTP_NOT_FOUND),
   2519     TALER_TESTING_cmd_merchant_delete_webhook ("get-webhooks-empty",
   2520                                                merchant_url,
   2521                                                "webhook-1",
   2522                                                MHD_HTTP_NO_CONTENT),
   2523     TALER_TESTING_cmd_end ()
   2524   };
   2525   struct TALER_TESTING_Command inventory_webhooks[] = {
   2526     TALER_TESTING_cmd_testserver (
   2527       "launch-http-server-for-inventory-webhooks",
   2528       12346),
   2529     TALER_TESTING_cmd_merchant_post_webhooks2 (
   2530       "post-webhooks-inventory-added",
   2531       merchant_url,
   2532       "webhook-inventory-added",
   2533       "inventory_added",
   2534       "http://localhost:12346/",
   2535       "POST",
   2536       "Taler-test-header: inventory",
   2537       "inventory-added",
   2538       MHD_HTTP_NO_CONTENT),
   2539     TALER_TESTING_cmd_merchant_post_webhooks2 (
   2540       "post-webhooks-inventory-updated",
   2541       merchant_url,
   2542       "webhook-inventory-updated",
   2543       "inventory_updated",
   2544       "http://localhost:12346/",
   2545       "POST",
   2546       "Taler-test-header: inventory",
   2547       "inventory-updated",
   2548       MHD_HTTP_NO_CONTENT),
   2549     TALER_TESTING_cmd_merchant_post_webhooks2 (
   2550       "post-webhooks-inventory-deleted",
   2551       merchant_url,
   2552       "webhook-inventory-deleted",
   2553       "inventory_deleted",
   2554       "http://localhost:12346/",
   2555       "POST",
   2556       "Taler-test-header: inventory",
   2557       "inventory-deleted",
   2558       MHD_HTTP_NO_CONTENT),
   2559     TALER_TESTING_cmd_merchant_post_products (
   2560       "post-product-inventory-hook",
   2561       merchant_url,
   2562       "product-inventory-hook",
   2563       "webhook inventory product",
   2564       "EUR:1",
   2565       MHD_HTTP_NO_CONTENT),
   2566     cmd_webhook ("pending-webhooks-inventory-added"),
   2567     TALER_TESTING_cmd_checkserver2 (
   2568       "check-inventory-webhook-added",
   2569       "launch-http-server-for-inventory-webhooks",
   2570       0,
   2571       "/",
   2572       "POST",
   2573       NULL,
   2574       "inventory-added"),
   2575     TALER_TESTING_cmd_merchant_patch_product (
   2576       "patch-product-inventory-hook",
   2577       merchant_url,
   2578       "product-inventory-hook",
   2579       "webhook inventory product patched",
   2580       json_object (),
   2581       "unit",
   2582       "EUR:2",
   2583       "",
   2584       json_array (),
   2585       5,
   2586       0,
   2587       json_object (),
   2588       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES),
   2589       MHD_HTTP_NO_CONTENT),
   2590     cmd_webhook ("pending-webhooks-inventory-updated"),
   2591     TALER_TESTING_cmd_checkserver2 (
   2592       "check-inventory-webhook-updated",
   2593       "launch-http-server-for-inventory-webhooks",
   2594       1,
   2595       "/",
   2596       "POST",
   2597       NULL,
   2598       "inventory-updated"),
   2599     TALER_TESTING_cmd_merchant_delete_product (
   2600       "delete-product-inventory-hook",
   2601       merchant_url,
   2602       "product-inventory-hook",
   2603       MHD_HTTP_NO_CONTENT),
   2604     cmd_webhook ("pending-webhooks-inventory-deleted"),
   2605     TALER_TESTING_cmd_checkserver2 (
   2606       "check-inventory-webhook-deleted",
   2607       "launch-http-server-for-inventory-webhooks",
   2608       2,
   2609       "/",
   2610       "POST",
   2611       NULL,
   2612       "inventory-deleted"),
   2613     TALER_TESTING_cmd_end ()
   2614   };
   2615   struct TALER_TESTING_Command repurchase[] = {
   2616     cmd_transfer_to_exchange (
   2617       "create-reserve-30x",
   2618       "EUR:30.06"),
   2619     cmd_exec_wirewatch (
   2620       "wirewatch-30x"),
   2621     TALER_TESTING_cmd_check_bank_admin_transfer (
   2622       "check_bank_transfer-30x",
   2623       "EUR:30.06",
   2624       payer_payto,
   2625       exchange_payto,
   2626       "create-reserve-30x"),
   2627     TALER_TESTING_cmd_withdraw_amount (
   2628       "withdraw-coin-rep",
   2629       "create-reserve-30x",
   2630       "EUR:5",
   2631       0,
   2632       MHD_HTTP_OK),
   2633     TALER_TESTING_cmd_merchant_post_orders3 (
   2634       "post-order-repurchase-original",
   2635       cred.cfg,
   2636       merchant_url,
   2637       MHD_HTTP_OK,
   2638       "repurchase-original",
   2639       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_HOURS),
   2640       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES),
   2641       "https://fulfillment.example.com/",
   2642       "EUR:1.0"),
   2643     TALER_TESTING_cmd_merchant_pay_order (
   2644       "repurchase-pay-first",
   2645       merchant_url,
   2646       MHD_HTTP_OK,
   2647       "post-order-repurchase-original",
   2648       "withdraw-coin-rep",
   2649       "EUR:1.00",
   2650       "EUR:0.99",
   2651       "repurchase-session"),
   2652     TALER_TESTING_cmd_wallet_get_order (
   2653       "repurchase-wallet-check-primary-order",
   2654       merchant_url,
   2655       "post-order-repurchase-original",
   2656       true,
   2657       false,
   2658       false,
   2659       MHD_HTTP_OK),
   2660     TALER_TESTING_cmd_merchant_get_order3 (
   2661       "repurchase-check-primary-payment",
   2662       merchant_url,
   2663       "post-order-repurchase-original",
   2664       TALER_MERCHANT_OSC_PAID,
   2665       "repurchase-session",
   2666       NULL,
   2667       MHD_HTTP_OK),
   2668     TALER_TESTING_cmd_merchant_get_order3 (
   2669       "repurchase-check-primary-payment-bad-binding",
   2670       merchant_url,
   2671       "post-order-repurchase-original",
   2672       TALER_MERCHANT_OSC_CLAIMED, /* someone else has it! */
   2673       "wrong-session",
   2674       NULL,
   2675       MHD_HTTP_OK),
   2676     TALER_TESTING_cmd_merchant_post_orders3 (
   2677       "post-order-repurchase-secondary",
   2678       cred.cfg,
   2679       merchant_url,
   2680       MHD_HTTP_OK,
   2681       "repurchase-secondary",
   2682       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_HOURS),
   2683       GNUNET_TIME_relative_to_timestamp (GNUNET_TIME_UNIT_MINUTES),
   2684       "https://fulfillment.example.com/",
   2685       "EUR:1.0"),
   2686     TALER_TESTING_cmd_merchant_get_order3 (
   2687       "repurchase-check-secondary-payment",
   2688       merchant_url,
   2689       "post-order-repurchase-secondary",
   2690       TALER_MERCHANT_OSC_UNPAID,
   2691       "repurchase-session",
   2692       NULL,
   2693       MHD_HTTP_OK),
   2694     TALER_TESTING_cmd_merchant_get_order3 (
   2695       "repurchase-check-secondary-payment",
   2696       merchant_url,
   2697       "post-order-repurchase-secondary",
   2698       TALER_MERCHANT_OSC_UNPAID,
   2699       "repurchase-session",
   2700       "post-order-repurchase-original",
   2701       MHD_HTTP_OK),
   2702     TALER_TESTING_cmd_wallet_get_order2 (
   2703       "repurchase-wallet-check-order-secondary",
   2704       merchant_url,
   2705       "post-order-repurchase-secondary",
   2706       "repurchase-session",
   2707       false,
   2708       false,
   2709       false,
   2710       "post-order-repurchase-original",
   2711       MHD_HTTP_PAYMENT_REQUIRED),
   2712     TALER_TESTING_cmd_wallet_get_order2 (
   2713       "repurchase-wallet-check-order-secondary-bad-session",
   2714       merchant_url,
   2715       "post-order-repurchase-secondary",
   2716       "wrong-session",
   2717       false,
   2718       false,
   2719       false,
   2720       NULL,
   2721       MHD_HTTP_PAYMENT_REQUIRED),
   2722     TALER_TESTING_cmd_merchant_order_refund (
   2723       "refund-repurchased",
   2724       merchant_url,
   2725       "refund repurchase",
   2726       "repurchase-original",
   2727       "EUR:1.0",
   2728       MHD_HTTP_OK),
   2729     TALER_TESTING_cmd_wallet_get_order2 (
   2730       "repurchase-wallet-check-primary-order-refunded-no-session",
   2731       merchant_url,
   2732       "post-order-repurchase-original",
   2733       NULL,
   2734       true,
   2735       true,
   2736       true,
   2737       "post-order-repurchase-original",
   2738       MHD_HTTP_OK),
   2739     TALER_TESTING_cmd_wallet_get_order2 (
   2740       "repurchase-wallet-check-primary-order-refunded",
   2741       merchant_url,
   2742       "post-order-repurchase-original",
   2743       "repurchase-session",
   2744       true,
   2745       true,
   2746       true,
   2747       "post-order-repurchase-original",
   2748       MHD_HTTP_OK),
   2749     TALER_TESTING_cmd_merchant_get_order3 (
   2750       "repurchase-check-refunded",
   2751       merchant_url,
   2752       "post-order-repurchase-secondary",
   2753       TALER_MERCHANT_OSC_CLAIMED,
   2754       "repurchase-session",
   2755       NULL,
   2756       MHD_HTTP_OK),
   2757 
   2758     TALER_TESTING_cmd_end ()
   2759   };
   2760 
   2761   struct TALER_TESTING_Command tokens[] = {
   2762     /**
   2763      * Move money to the exchange's bank account.
   2764      */
   2765     cmd_transfer_to_exchange ("create-reserve-tokens",
   2766                               "EUR:20.03"),
   2767     /**
   2768      * Make a reserve exist, according to the previous transfer.
   2769      */
   2770     cmd_exec_wirewatch ("wirewatch-1"),
   2771     TALER_TESTING_cmd_check_bank_admin_transfer ("check_bank_transfer-tokens",
   2772                                                  "EUR:20.03",
   2773                                                  payer_payto,
   2774                                                  exchange_payto,
   2775                                                  "create-reserve-tokens"),
   2776     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-1",
   2777                                        "create-reserve-tokens",
   2778                                        "EUR:5",
   2779                                        0,
   2780                                        MHD_HTTP_OK),
   2781     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-2",
   2782                                        "create-reserve-tokens",
   2783                                        "EUR:5",
   2784                                        0,
   2785                                        MHD_HTTP_OK),
   2786     TALER_TESTING_cmd_withdraw_amount ("withdraw-coin-3",
   2787                                        "create-reserve-tokens",
   2788                                        "EUR:5",
   2789                                        0,
   2790                                        MHD_HTTP_OK),
   2791     TALER_TESTING_cmd_merchant_post_tokenfamilies (
   2792       "create-upcoming-tokenfamily",
   2793       merchant_url,
   2794       MHD_HTTP_NO_CONTENT,
   2795       "subscription-upcoming",
   2796       "Upcoming Subscription",
   2797       "An upcoming subscription that is not valid yet.",
   2798       NULL,
   2799       /* In one day */
   2800       GNUNET_TIME_absolute_to_timestamp (
   2801         GNUNET_TIME_absolute_add (
   2802           GNUNET_TIME_timestamp_get ().abs_time,
   2803           GNUNET_TIME_UNIT_DAYS)),
   2804       /* In a year */
   2805       GNUNET_TIME_absolute_to_timestamp (
   2806         GNUNET_TIME_absolute_add (
   2807           GNUNET_TIME_timestamp_get ().abs_time,
   2808           GNUNET_TIME_UNIT_YEARS)),
   2809       GNUNET_TIME_UNIT_MONTHS,
   2810       GNUNET_TIME_UNIT_MONTHS,
   2811       "subscription"),
   2812     TALER_TESTING_cmd_merchant_post_orders_choices (
   2813       "create-order-with-upcoming-output",
   2814       cred.cfg,
   2815       merchant_url,
   2816       MHD_HTTP_OK,
   2817       "subscription-upcoming",
   2818       "A choice in the contract",
   2819       NULL,
   2820       0,
   2821       1,
   2822       "5-upcoming-output",
   2823       GNUNET_TIME_UNIT_ZERO_TS,
   2824       GNUNET_TIME_UNIT_FOREVER_TS,
   2825       "EUR:5.0"),
   2826     TALER_TESTING_cmd_merchant_post_tokenfamilies (
   2827       "create-tokenfamily",
   2828       merchant_url,
   2829       MHD_HTTP_NO_CONTENT,
   2830       "subscription-1",
   2831       "Subscription",
   2832       "A subscription.",
   2833       NULL,
   2834       GNUNET_TIME_UNIT_ZERO_TS,
   2835       GNUNET_TIME_relative_to_timestamp (
   2836         GNUNET_TIME_UNIT_YEARS),
   2837       GNUNET_TIME_UNIT_MONTHS,
   2838       GNUNET_TIME_UNIT_MONTHS,
   2839       "subscription"),
   2840     TALER_TESTING_cmd_merchant_post_orders_choices (
   2841       "create-order-with-output",
   2842       cred.cfg,
   2843       merchant_url,
   2844       MHD_HTTP_OK,
   2845       "subscription-1",
   2846       "A choice in the contract",
   2847       NULL,
   2848       0,
   2849       1,
   2850       "5-output",
   2851       GNUNET_TIME_UNIT_ZERO_TS,
   2852       GNUNET_TIME_UNIT_FOREVER_TS,
   2853       "EUR:5.0"),
   2854     TALER_TESTING_cmd_merchant_pay_order_choices (
   2855       "pay-order-with-output",
   2856       merchant_url,
   2857       MHD_HTTP_OK,
   2858       "create-order-with-output",
   2859       "withdraw-coin-1",
   2860       "EUR:5",
   2861       "EUR:4.99",
   2862       NULL,
   2863       0,
   2864       NULL),
   2865     TALER_TESTING_cmd_merchant_post_orders_choices (
   2866       "create-order-with-input-and-output",
   2867       cred.cfg,
   2868       merchant_url,
   2869       MHD_HTTP_OK,
   2870       "subscription-1",
   2871       "A choice in the contract",
   2872       NULL,
   2873       1,
   2874       1,
   2875       "5-input-output",
   2876       GNUNET_TIME_UNIT_ZERO_TS,
   2877       GNUNET_TIME_UNIT_FOREVER_TS,
   2878       "EUR:0.0"),
   2879     TALER_TESTING_cmd_merchant_pay_order_choices (
   2880       "pay-order-with-input-and-output",
   2881       merchant_url,
   2882       MHD_HTTP_OK,
   2883       "create-order-with-input-and-output",
   2884       "",
   2885       "EUR:0",
   2886       "EUR:0",
   2887       NULL,
   2888       0,
   2889       "pay-order-with-output"),
   2890     // TALER_TESTING_cmd_merchant_pay_order_choices ("idempotent-pay-order-with-input-and-output",
   2891     //                                               merchant_url,
   2892     //                                               MHD_HTTP_OK,
   2893     //                                               "create-order-with-input-and-output",
   2894     //                                               "",
   2895     //                                               "EUR:0",
   2896     //                                               "EUR:0",
   2897     //                                               NULL,
   2898     //                                               0,
   2899     //                                               "pay-order-with-output"),
   2900     TALER_TESTING_cmd_merchant_post_orders_choices (
   2901       "create-another-order-with-input-and-output",
   2902       cred.cfg,
   2903       merchant_url,
   2904       MHD_HTTP_OK,
   2905       "subscription-1",
   2906       "A choice in the contract",
   2907       NULL,
   2908       1,
   2909       1,
   2910       "5-input-output-2",
   2911       GNUNET_TIME_UNIT_ZERO_TS,
   2912       GNUNET_TIME_UNIT_FOREVER_TS,
   2913       "EUR:0.0"),
   2914     TALER_TESTING_cmd_merchant_pay_order_choices ("double-spend-token",
   2915                                                   merchant_url,
   2916                                                   MHD_HTTP_CONFLICT,
   2917                                                   "create-another-order-with-input-and-output",
   2918                                                   "",
   2919                                                   "EUR:0",
   2920                                                   "EUR:0",
   2921                                                   NULL,
   2922                                                   0,
   2923                                                   "pay-order-with-output"),
   2924     TALER_TESTING_cmd_end ()
   2925   };
   2926 
   2927   const struct DONAU_BearerToken bearer = {
   2928     .token = NULL
   2929   };
   2930 
   2931   struct TALER_TESTING_Command donau[] = {
   2932     TALER_TESTING_cmd_set_var (
   2933       "donau",
   2934       TALER_TESTING_cmd_get_donau ("get-donau",
   2935                                    cred.cfg,
   2936                                    true /* wait for response */)),
   2937     TALER_TESTING_cmd_charity_post_merchant ("post-charity",
   2938                                              "example",
   2939                                              "https://example.com/",
   2940                                              "EUR:50", // max_per_year
   2941                                              &bearer,
   2942                                              "create-another-order-with-input-and-output",
   2943                                              // reusing the merchant_reference for merchant_pub
   2944                                              MHD_HTTP_CREATED),
   2945     TALER_TESTING_cmd_charity_post_merchant ("post-charity-idempotent",
   2946                                              "example",
   2947                                              "https://example.com/",
   2948                                              "EUR:50", // max_per_year
   2949                                              &bearer,
   2950                                              "create-another-order-with-input-and-output",
   2951                                              // reusing the merchant_reference for merchant_pub
   2952                                              MHD_HTTP_CREATED),
   2953     TALER_TESTING_cmd_merchant_post_donau_instance (
   2954       "post-donau-instance",
   2955       merchant_url,
   2956       "create-another-order-with-input-and-output",
   2957       MHD_HTTP_NO_CONTENT),
   2958     TALER_TESTING_cmd_merchant_post_donau_instance (
   2959       "post-donau-instance-idempotent",
   2960       merchant_url,
   2961       "create-another-order-with-input-and-output",
   2962       MHD_HTTP_NO_CONTENT),
   2963     TALER_TESTING_cmd_merchant_get_donau_instances (
   2964       "get-donau-instances-after-insert",
   2965       merchant_url,
   2966       1,
   2967       MHD_HTTP_OK),
   2968     TALER_TESTING_cmd_exec_donaukeyupdate ("run-merchant-donaukeyupdate",
   2969                                            config_file),
   2970     TALER_TESTING_cmd_merchant_get_donau_instances (
   2971       "get-donau-instance",
   2972       merchant_url,
   2973       1,
   2974       MHD_HTTP_OK),
   2975     TALER_TESTING_cmd_merchant_post_orders_donau (
   2976       "create-donau-order",
   2977       cred.cfg,
   2978       merchant_url,
   2979       MHD_HTTP_OK,
   2980       "donau",
   2981       GNUNET_TIME_UNIT_ZERO_TS,
   2982       GNUNET_TIME_UNIT_FOREVER_TS,
   2983       "EUR:1"),
   2984     TALER_TESTING_cmd_merchant_pay_order_donau (
   2985       "pay-donau-order",
   2986       merchant_url,
   2987       MHD_HTTP_OK,
   2988       "create-donau-order",
   2989       "withdraw-coin-3",
   2990       "EUR:1", /* full amount */
   2991       "EUR:0.99", /* amount without fees */
   2992       "EUR:1", /* donation amount */
   2993       NULL,
   2994       0,
   2995       "post-charity",
   2996       GNUNET_TIME_get_current_year (),
   2997       "7560001010000",
   2998       "1234"
   2999       ),
   3000     TALER_TESTING_cmd_merchant_delete_donau_instance (
   3001       "delete-donau-instance",
   3002       merchant_url,
   3003       1,
   3004       MHD_HTTP_NO_CONTENT),
   3005     TALER_TESTING_cmd_merchant_get_donau_instances (
   3006       "get-donau-instances-after-delete",
   3007       merchant_url,
   3008       0,
   3009       MHD_HTTP_OK),
   3010     TALER_TESTING_cmd_end ()
   3011   };
   3012 
   3013   /* Products with categories.  Runs last, as it adds a category and
   3014      products which would otherwise show up in the category- and
   3015      product-based expectations of the 'templates' batch. */
   3016   struct TALER_TESTING_Command product_categories[] = {
   3017     /* 3rd category: the 'templates' batch already created two. */
   3018     TALER_TESTING_cmd_merchant_post_categories ("post-category-pc",
   3019                                                 merchant_url,
   3020                                                 "Category Products",
   3021                                                 json_pack ("{s:s}",
   3022                                                            "en",
   3023                                                            "Category Products"),
   3024                                                 3,
   3025                                                 MHD_HTTP_OK),
   3026     /* Unknown category must yield 404, not a DB failure (500). */
   3027     TALER_TESTING_cmd_merchant_post_products_with_categories (
   3028       "post-products-pc-cat-nx",
   3029       merchant_url,
   3030       "pc-product-nx",
   3031       "product with unknown category",
   3032       "test-unit",
   3033       "EUR:3",
   3034       1,
   3035       (const uint64_t[]) { 424242 },
   3036       false,
   3037       0,
   3038       MHD_HTTP_NOT_FOUND),
   3039     /* Category serials are positive; 0 is malformed. */
   3040     TALER_TESTING_cmd_merchant_post_products_with_categories (
   3041       "post-products-pc-cat-zero",
   3042       merchant_url,
   3043       "pc-product-zero",
   3044       "product with zero category",
   3045       "test-unit",
   3046       "EUR:3",
   3047       1,
   3048       (const uint64_t[]) { 0 },
   3049       false,
   3050       0,
   3051       MHD_HTTP_BAD_REQUEST),
   3052     TALER_TESTING_cmd_merchant_get_product (
   3053       "get-product-pc-nx",
   3054       merchant_url,
   3055       "pc-product-nx",
   3056       MHD_HTTP_NOT_FOUND,
   3057       NULL),
   3058     TALER_TESTING_cmd_merchant_post_products_with_categories (
   3059       "post-products-pc",
   3060       merchant_url,
   3061       "pc-product",
   3062       "product with category",
   3063       "test-unit",
   3064       "EUR:3",
   3065       1,
   3066       (const uint64_t[]) { 3 },
   3067       false,
   3068       0,
   3069       MHD_HTTP_NO_CONTENT),
   3070     /* Same for PATCH: unknown category must yield 404, not 500.  The
   3071        rejected update must not have been applied either, hence the
   3072        deviating description and the GET checking against the POST. */
   3073     TALER_TESTING_cmd_merchant_patch_product_with_categories (
   3074       "patch-products-pc-cat-nx",
   3075       merchant_url,
   3076       "pc-product",
   3077       "product with unapplied update",
   3078       "test-unit",
   3079       "EUR:3",
   3080       1,
   3081       (const uint64_t[]) { 424242 },
   3082       MHD_HTTP_NOT_FOUND),
   3083     TALER_TESTING_cmd_merchant_get_product (
   3084       "get-product-pc-unchanged",
   3085       merchant_url,
   3086       "pc-product",
   3087       MHD_HTTP_OK,
   3088       "post-products-pc"),
   3089     TALER_TESTING_cmd_merchant_patch_product_with_categories (
   3090       "patch-products-pc-cat-zero",
   3091       merchant_url,
   3092       "pc-product",
   3093       "product with unapplied update",
   3094       "test-unit",
   3095       "EUR:3",
   3096       1,
   3097       (const uint64_t[]) { 0 },
   3098       MHD_HTTP_BAD_REQUEST),
   3099     TALER_TESTING_cmd_merchant_get_product (
   3100       "get-product-pc-unchanged-2",
   3101       merchant_url,
   3102       "pc-product",
   3103       MHD_HTTP_OK,
   3104       "post-products-pc"),
   3105     /* Duplicate categories are de-duplicated, not rejected. */
   3106     TALER_TESTING_cmd_merchant_patch_product_with_categories (
   3107       "patch-products-pc-cat-dup",
   3108       merchant_url,
   3109       "pc-product",
   3110       "product with category",
   3111       "test-unit",
   3112       "EUR:3",
   3113       2,
   3114       (const uint64_t[]) { 3, 3 },
   3115       MHD_HTTP_NO_CONTENT),
   3116     TALER_TESTING_cmd_merchant_patch_product_with_categories (
   3117       "patch-products-pc-cat-ok",
   3118       merchant_url,
   3119       "pc-product",
   3120       "product with category",
   3121       "test-unit",
   3122       "EUR:3",
   3123       1,
   3124       (const uint64_t[]) { 3 },
   3125       MHD_HTTP_NO_CONTENT),
   3126     TALER_TESTING_cmd_merchant_get_product (
   3127       "get-product-pc",
   3128       merchant_url,
   3129       "pc-product",
   3130       MHD_HTTP_OK,
   3131       "patch-products-pc-cat-ok"),
   3132     TALER_TESTING_cmd_end ()
   3133   };
   3134 
   3135   struct TALER_TESTING_Command commands[] = {
   3136     /* general setup */
   3137     TALER_TESTING_cmd_run_fakebank (
   3138       "run-fakebank",
   3139       cred.cfg,
   3140       "exchange-account-exchange"),
   3141     TALER_TESTING_cmd_system_start (
   3142       "start-taler",
   3143       config_file,
   3144       "-emaD",
   3145       "-u", "exchange-account-exchange",
   3146       "-r", "merchant-exchange-test",
   3147       NULL),
   3148     TALER_TESTING_cmd_get_exchange (
   3149       "get-exchange",
   3150       cred.cfg,
   3151       NULL,
   3152       true,
   3153       true),
   3154     TALER_TESTING_cmd_batch (
   3155       "orders-id",
   3156       get_private_order_id),
   3157     TALER_TESTING_cmd_config (
   3158       "config",
   3159       merchant_url,
   3160       MHD_HTTP_OK),
   3161     TALER_TESTING_cmd_merchant_get_instances (
   3162       "instances-empty",
   3163       merchant_url,
   3164       MHD_HTTP_OK,
   3165       NULL),
   3166     TALER_TESTING_cmd_merchant_post_instances (
   3167       "instance-create-default-setup",
   3168       merchant_url,
   3169       "admin",
   3170       MHD_HTTP_NO_CONTENT),
   3171     TALER_TESTING_cmd_merchant_post_account (
   3172       "instance-create-default-account",
   3173       merchant_url,
   3174       merchant_payto,
   3175       NULL, NULL,
   3176       MHD_HTTP_OK),
   3177     TALER_TESTING_cmd_merchant_post_instances (
   3178       "instance-create-i1",
   3179       merchant_url,
   3180       "i1",
   3181       MHD_HTTP_NO_CONTENT),
   3182     TALER_TESTING_cmd_merchant_get_instances (
   3183       "instances-get-i1",
   3184       merchant_url,
   3185       MHD_HTTP_OK,
   3186       "instance-create-i1",
   3187       "instance-create-default-setup",
   3188       NULL),
   3189     TALER_TESTING_cmd_merchant_get_instance (
   3190       "instances-get-i1",
   3191       merchant_url,
   3192       "i1",
   3193       MHD_HTTP_OK,
   3194       "instance-create-i1"),
   3195     TALER_TESTING_cmd_merchant_patch_instance (
   3196       "instance-patch-i1",
   3197       merchant_url,
   3198       "i1",
   3199       "bob-the-merchant",
   3200       json_pack ("{s:s}",
   3201                  "street",
   3202                  "bobstreet"),
   3203       json_pack ("{s:s}",
   3204                  "street",
   3205                  "bobjuryst"),
   3206       true,
   3207       GNUNET_TIME_UNIT_ZERO, /* wire transfer */
   3208       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
   3209                                      2), /* small pay delay */
   3210       MHD_HTTP_NO_CONTENT),
   3211     TALER_TESTING_cmd_merchant_get_instance (
   3212       "instances-get-i1-2",
   3213       merchant_url,
   3214       "i1",
   3215       MHD_HTTP_OK,
   3216       "instance-patch-i1"),
   3217     TALER_TESTING_cmd_merchant_get_instance (
   3218       "instances-get-i2-nx",
   3219       merchant_url,
   3220       "i2",
   3221       MHD_HTTP_NOT_FOUND,
   3222       NULL),
   3223     TALER_TESTING_cmd_merchant_post_instances2 (
   3224       "instance-create-ACL",
   3225       merchant_url,
   3226       "i-acl",
   3227       "controlled instance",
   3228       json_pack ("{s:s}", "city",
   3229                  "shopcity"),
   3230       json_pack ("{s:s}", "city",
   3231                  "lawyercity"),
   3232       true,
   3233       GNUNET_TIME_UNIT_ZERO, /* wire transfer */
   3234       GNUNET_TIME_UNIT_SECONDS, /* pay delay */
   3235       // FIXME: change this back once
   3236       // we have a update auth test CMD
   3237       // RFC_8959_PREFIX "EXAMPLE",
   3238       NULL,
   3239       MHD_HTTP_NO_CONTENT),
   3240     TALER_TESTING_cmd_merchant_patch_instance (
   3241       "instance-patch-ACL",
   3242       merchant_url,
   3243       "i-acl",
   3244       "controlled instance",
   3245       json_pack ("{s:s}",
   3246                  "street",
   3247                  "bobstreet"),
   3248       json_pack ("{s:s}",
   3249                  "street",
   3250                  "bobjuryst"),
   3251       true,
   3252       GNUNET_TIME_UNIT_ZERO, /* wire transfer */
   3253       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
   3254                                      2), /* small pay delay */
   3255       MHD_HTTP_NO_CONTENT),
   3256     TALER_TESTING_cmd_merchant_post_instances (
   3257       "instance-create-i2",
   3258       merchant_url,
   3259       "i2",
   3260       MHD_HTTP_NO_CONTENT),
   3261     TALER_TESTING_cmd_merchant_post_instances (
   3262       "instance-create-i2-idem",
   3263       merchant_url,
   3264       "i2",
   3265       MHD_HTTP_NO_CONTENT),
   3266     TALER_TESTING_cmd_merchant_delete_instance (
   3267       "instance-delete-i2",
   3268       merchant_url,
   3269       "i2",
   3270       MHD_HTTP_NO_CONTENT),
   3271     TALER_TESTING_cmd_merchant_get_instance (
   3272       "instances-get-i2-post-deletion",
   3273       merchant_url,
   3274       "i2",
   3275       MHD_HTTP_NOT_FOUND,
   3276       NULL),
   3277     TALER_TESTING_cmd_merchant_purge_instance (
   3278       "instance-delete-then-purge-i2",
   3279       merchant_url,
   3280       "i2",
   3281       MHD_HTTP_NO_CONTENT),
   3282     TALER_TESTING_cmd_merchant_purge_instance (
   3283       "instance-purge-i1",
   3284       merchant_url,
   3285       "i1",
   3286       MHD_HTTP_NO_CONTENT),
   3287     TALER_TESTING_cmd_merchant_delete_instance (
   3288       "instance-purge-then-delete-i1",
   3289       merchant_url,
   3290       "i1",
   3291       MHD_HTTP_NOT_FOUND),
   3292     TALER_TESTING_cmd_merchant_purge_instance (
   3293       "instance-purge-i-acl-middle",
   3294       merchant_url,
   3295       "i-acl",
   3296       MHD_HTTP_NO_CONTENT),
   3297     TALER_TESTING_cmd_merchant_purge_instance (
   3298       "instance-purge-default-middle",
   3299       merchant_url,
   3300       "admin",
   3301       MHD_HTTP_NO_CONTENT),
   3302     TALER_TESTING_cmd_merchant_post_instances (
   3303       "instance-create-default-after-purge",
   3304       merchant_url,
   3305       "admin",
   3306       MHD_HTTP_NO_CONTENT),
   3307     TALER_TESTING_cmd_merchant_post_account (
   3308       "instance-create-default-account-after-purge",
   3309       merchant_url,
   3310       merchant_payto,
   3311       NULL, NULL,
   3312       MHD_HTTP_OK),
   3313     TALER_TESTING_cmd_merchant_get_products (
   3314       "get-products-empty",
   3315       merchant_url,
   3316       MHD_HTTP_OK,
   3317       NULL),
   3318     TALER_TESTING_cmd_merchant_post_products (
   3319       "post-products-p1",
   3320       merchant_url,
   3321       "product-1",
   3322       "a product",
   3323       "EUR:1",
   3324       MHD_HTTP_NO_CONTENT),
   3325     TALER_TESTING_cmd_merchant_post_products (
   3326       "post-products-p1-idem",
   3327       merchant_url,
   3328       "product-1",
   3329       "a product",
   3330       "EUR:1",
   3331       MHD_HTTP_NO_CONTENT),
   3332     TALER_TESTING_cmd_merchant_post_products (
   3333       "post-products-p1-non-idem",
   3334       merchant_url,
   3335       "product-1",
   3336       "a different product",
   3337       "EUR:1",
   3338       MHD_HTTP_CONFLICT),
   3339     TALER_TESTING_cmd_merchant_get_products (
   3340       "get-products-p1",
   3341       merchant_url,
   3342       MHD_HTTP_OK,
   3343       "post-products-p1",
   3344       NULL),
   3345     TALER_TESTING_cmd_merchant_get_product (
   3346       "get-product-p1",
   3347       merchant_url,
   3348       "product-1",
   3349       MHD_HTTP_OK,
   3350       "post-products-p1"),
   3351     TALER_TESTING_cmd_merchant_post_products2 (
   3352       "post-products-img",
   3353       merchant_url,
   3354       "product-img",
   3355       "product with image",
   3356       json_pack ("{s:s}", "en", "product with image"),
   3357       "test-unit",
   3358       "EUR:1",
   3359       "data:image/jpeg;base64,RAWDATA",
   3360       json_array (),
   3361       4,
   3362       0,
   3363       json_pack ("{s:s}", "street", "my street"),
   3364       GNUNET_TIME_UNIT_ZERO_TS,
   3365       MHD_HTTP_NO_CONTENT),
   3366     TALER_TESTING_cmd_get_product_image (
   3367       "get-product-image-img",
   3368       merchant_url,
   3369       "post-products-img",
   3370       "5831ca012639a29df949c3b1e5cd436bac0a5b26a5340ccd95df394b7a8742d6",
   3371       MHD_HTTP_OK),
   3372     TALER_TESTING_cmd_get_product_image (
   3373       "get-product-image-invalid",
   3374       merchant_url,
   3375       NULL,
   3376       "not-a-valid-hash",
   3377       MHD_HTTP_BAD_REQUEST),
   3378     TALER_TESTING_cmd_get_product_image (
   3379       "get-product-image-empty",
   3380       merchant_url,
   3381       NULL,
   3382       "",
   3383       MHD_HTTP_BAD_REQUEST),
   3384     TALER_TESTING_cmd_get_product_image (
   3385       "get-product-image-not-found",
   3386       merchant_url,
   3387       NULL,
   3388       "5831ca012639a29df949c3b1e5cd436bac0a5b26a5340ccd95df394b7a8742d7",
   3389       MHD_HTTP_NOT_FOUND),
   3390     TALER_TESTING_cmd_merchant_post_products (
   3391       "post-products-p2",
   3392       merchant_url,
   3393       "product-2",
   3394       "a product",
   3395       "EUR:1",
   3396       MHD_HTTP_NO_CONTENT),
   3397     TALER_TESTING_cmd_merchant_patch_product (
   3398       "patch-products-p2",
   3399       merchant_url,
   3400       "product-2",
   3401       "another product",
   3402       json_pack ("{s:s}", "en", "text"),
   3403       "kg",
   3404       "EUR:1",
   3405       "data:image/jpeg;base64,RAWDATA",
   3406       json_array (),
   3407       40,
   3408       0,
   3409       json_pack ("{s:s}",
   3410                  "street",
   3411                  "pstreet"),
   3412       GNUNET_TIME_relative_to_timestamp (
   3413         GNUNET_TIME_UNIT_MINUTES),
   3414       MHD_HTTP_NO_CONTENT),
   3415     TALER_TESTING_cmd_merchant_get_product (
   3416       "get-product-p2",
   3417       merchant_url,
   3418       "product-2",
   3419       MHD_HTTP_OK,
   3420       "patch-products-p2"),
   3421     TALER_TESTING_cmd_merchant_get_product (
   3422       "get-product-nx",
   3423       merchant_url,
   3424       "product-nx",
   3425       MHD_HTTP_NOT_FOUND,
   3426       NULL),
   3427     TALER_TESTING_cmd_merchant_patch_product (
   3428       "patch-products-p3-nx",
   3429       merchant_url,
   3430       "product-3",
   3431       "nx updated product",
   3432       json_pack ("{s:s}", "en", "text"),
   3433       "kg",
   3434       "EUR:1",
   3435       "data:image/jpeg;base64,RAWDATA",
   3436       json_array (),
   3437       40,
   3438       0,
   3439       json_pack ("{s:s}",
   3440                  "street",
   3441                  "pstreet"),
   3442       GNUNET_TIME_relative_to_timestamp (
   3443         GNUNET_TIME_UNIT_MINUTES),
   3444       MHD_HTTP_NOT_FOUND),
   3445     TALER_TESTING_cmd_merchant_delete_product (
   3446       "get-products-empty",
   3447       merchant_url,
   3448       "p1",
   3449       MHD_HTTP_NOT_FOUND),
   3450     TALER_TESTING_cmd_merchant_delete_product (
   3451       "get-products-empty",
   3452       merchant_url,
   3453       "product-1",
   3454       MHD_HTTP_NO_CONTENT),
   3455     TALER_TESTING_cmd_merchant_lock_product (
   3456       "lock-product-p2",
   3457       merchant_url,
   3458       "product-2",
   3459       GNUNET_TIME_UNIT_MINUTES,
   3460       2,
   3461       MHD_HTTP_NO_CONTENT),
   3462     TALER_TESTING_cmd_merchant_lock_product (
   3463       "lock-product-nx",
   3464       merchant_url,
   3465       "product-nx",
   3466       GNUNET_TIME_UNIT_MINUTES,
   3467       2,
   3468       MHD_HTTP_NOT_FOUND),
   3469     TALER_TESTING_cmd_merchant_lock_product (
   3470       "lock-product-too-much",
   3471       merchant_url,
   3472       "product-2",
   3473       GNUNET_TIME_UNIT_MINUTES,
   3474       39,
   3475       MHD_HTTP_GONE),
   3476     TALER_TESTING_cmd_merchant_delete_product (
   3477       "delete-product-locked",
   3478       merchant_url,
   3479       "product-2",
   3480       MHD_HTTP_CONFLICT),
   3481     TALER_TESTING_cmd_batch ("pay",
   3482                              pay),
   3483     TALER_TESTING_cmd_batch ("double-spending",
   3484                              double_spending),
   3485     TALER_TESTING_cmd_batch ("pay-again",
   3486                              pay_again),
   3487     TALER_TESTING_cmd_batch ("pay-abort",
   3488                              pay_abort),
   3489     TALER_TESTING_cmd_batch ("refund",
   3490                              refund),
   3491     TALER_TESTING_cmd_batch ("templates",
   3492                              templates),
   3493     TALER_TESTING_cmd_batch ("webhooks",
   3494                              webhooks),
   3495     TALER_TESTING_cmd_batch ("inventory-webhooks",
   3496                              inventory_webhooks),
   3497     TALER_TESTING_cmd_batch ("auth",
   3498                              auth),
   3499     TALER_TESTING_cmd_batch ("repurchase",
   3500                              repurchase),
   3501     TALER_TESTING_cmd_batch ("tokens",
   3502                              tokens),
   3503     TALER_TESTING_cmd_batch ("donau",
   3504                              donau),
   3505     TALER_TESTING_cmd_batch ("product-categories",
   3506                              product_categories),
   3507     TALER_TESTING_cmd_merchant_get_statisticsamount ("stats-refund",
   3508                                                      merchant_url,
   3509                                                      "refunds-granted",
   3510                                                      6,
   3511                                                      0,
   3512                                                      MHD_HTTP_OK),
   3513     TALER_TESTING_cmd_merchant_get_statisticscounter ("stats-tokens-issued",
   3514                                                       merchant_url,
   3515                                                       "tokens-issued",
   3516                                                       6,
   3517                                                       1,
   3518                                                       MHD_HTTP_OK),
   3519     TALER_TESTING_cmd_merchant_get_statisticscounter ("stats-tokens-used",
   3520                                                       merchant_url,
   3521                                                       "tokens-used",
   3522                                                       6,
   3523                                                       1,
   3524                                                       MHD_HTTP_OK),
   3525 
   3526     /**
   3527      * End the suite.
   3528      */
   3529     TALER_TESTING_cmd_end ()
   3530   };
   3531 
   3532   TALER_TESTING_run (is,
   3533                      commands);
   3534 }
   3535 
   3536 
   3537 int
   3538 main (int argc,
   3539       char *const *argv)
   3540 {
   3541   {
   3542     char *cipher;
   3543 
   3544     cipher = GNUNET_STRINGS_get_suffix_from_binary_name (argv[0]);
   3545     GNUNET_assert (NULL != cipher);
   3546     GNUNET_asprintf (&config_file,
   3547                      "test_merchant_api-%s.conf",
   3548                      cipher);
   3549     GNUNET_free (cipher);
   3550   }
   3551   payer_payto.full_payto =
   3552     (char *) "payto://x-taler-bank/localhost/" USER_ACCOUNT_NAME
   3553     "?receiver-name=" USER_ACCOUNT_NAME;
   3554   exchange_payto.full_payto =
   3555     (char *) "payto://x-taler-bank/localhost/" EXCHANGE_ACCOUNT_NAME
   3556     "?receiver-name="
   3557     EXCHANGE_ACCOUNT_NAME;
   3558   merchant_payto.full_payto =
   3559     (char *) "payto://x-taler-bank/localhost/" MERCHANT_ACCOUNT_NAME
   3560     "?receiver-name=" MERCHANT_ACCOUNT_NAME;
   3561   merchant_url = "http://localhost:8080/";
   3562   GNUNET_asprintf (&merchant_url_i1a,
   3563                    "%sinstances/i1a/",
   3564                    merchant_url);
   3565   return TALER_TESTING_main (argv,
   3566                              "INFO",
   3567                              config_file,
   3568                              "exchange-account-exchange",
   3569                              TALER_TESTING_BS_FAKEBANK,
   3570                              &cred,
   3571                              &run,
   3572                              NULL);
   3573 }
   3574 
   3575 
   3576 /* end of test_merchant_api.c */