merchant

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

test_merchant_api.c (140850B)


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