merchant

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

test_merchant_order_creation.sh (22444B)


      1 #!/bin/bash
      2 # This file is in the public domain.
      3 
      4 set -eu
      5 
      6 function clean_wallet() {
      7     rm -f "${WALLET_DB}"
      8     exit_cleanup
      9 }
     10 
     11 
     12 # Replace with 0 for nexus...
     13 USE_FAKEBANK=1
     14 if [ 1 = "$USE_FAKEBANK" ]
     15 then
     16     ACCOUNT="exchange-account-2"
     17     BANK_FLAGS="-f -d x-taler-bank -u $ACCOUNT"
     18     BANK_URL="http://localhost:8082/"
     19 else
     20     ACCOUNT="exchange-account-1"
     21     BANK_FLAGS="-ns -d iban -u $ACCOUNT"
     22     BANK_URL="http://localhost:8082/"
     23     echo -n "Testing for libeufin-bank"
     24     libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING"
     25     echo " FOUND"
     26 
     27 fi
     28 
     29 . setup.sh
     30 
     31 echo -n "Testing for taler-harness"
     32 taler-harness --help >/dev/null </dev/null || exit_skip " MISSING"
     33 echo " FOUND"
     34 
     35 # Launch exchange, merchant and bank.
     36 setup -c "test_template.conf" \
     37       -r "merchant-exchange-default" \
     38       -em \
     39       $BANK_FLAGS
     40 LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX)
     41 CONF="test_template.conf.edited"
     42 WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_wallet.json-XXXXXX)
     43 EXCHANGE_URL="http://localhost:8081/"
     44 
     45 # Install cleanup handler (except for kill -9)
     46 trap clean_wallet EXIT
     47 
     48 echo -n "First prepare wallet with coins ..."
     49 rm -f "$WALLET_DB"
     50 taler-wallet-cli \
     51     --no-throttle \
     52     --wallet-db="$WALLET_DB" \
     53     api \
     54     --expect-success 'withdrawTestBalance' \
     55   "$(jq -n '
     56     {
     57         amount: "TESTKUDOS:99",
     58         corebankApiBaseUrl: $BANK_URL,
     59         exchangeBaseUrl: $EXCHANGE_URL
     60     }' \
     61     --arg BANK_URL "${BANK_URL}" \
     62     --arg EXCHANGE_URL "$EXCHANGE_URL"
     63   )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out
     64 echo -n "."
     65 # FIXME-MS: add logic to have nexus check immediately here.
     66 # sleep 10
     67 echo -n "."
     68 # NOTE: once libeufin can do long-polling, we should
     69 # be able to reduce the delay here and run wirewatch
     70 # always in the background via setup
     71 taler-exchange-wirewatch \
     72     -a "$ACCOUNT" \
     73     -L "INFO" \
     74     -c "$CONF" \
     75     -t &> taler-exchange-wirewatch.out
     76 echo -n "."
     77 timeout 60 taler-wallet-cli \
     78     --wallet-db="$WALLET_DB" \
     79     run-until-done \
     80     2>wallet-withdraw-finish-1.err \
     81     >wallet-withdraw-finish-1.out
     82 echo " OK"
     83 
     84 CURRENCY_COUNT=$(taler-wallet-cli --wallet-db="$WALLET_DB" balance | jq '.balances|length')
     85 if [ "$CURRENCY_COUNT" = "0" ]
     86 then
     87     exit_fail "Expected least one currency, withdrawal failed. check log."
     88 fi
     89 
     90 #
     91 # CREATE INSTANCE FOR TESTING
     92 #
     93 
     94 
     95 echo -n "Configuring merchant instance ..."
     96 
     97 STATUS=$(curl -H "Content-Type: application/json" -X POST \
     98     -H 'Authorization: Bearer secret-token:super_secret' \
     99     http://localhost:9966/management/instances \
    100     -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000000},"default_pay_delay":{"d_us": 60000000000}}' \
    101     -w "%{http_code}" -s -o /dev/null)
    102 
    103 if [ "$STATUS" != "204" ]
    104 then
    105     exit_fail "Expected '204 No content' response. Got instead $STATUS"
    106 fi
    107 echo "Ok"
    108 
    109 echo -n "Configuring merchant account ..."
    110 
    111 if [ 1 = "$USE_FAKEBANK" ]
    112 then
    113     FORTYTHREE="payto://x-taler-bank/localhost/fortythree?receiver-name=fortythree"
    114 else
    115     FORTYTHREE=$(get_payto_uri fortythree x)
    116 fi
    117 # create with 2 bank account addresses
    118 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    119     -H 'Authorization: Bearer secret-token:super_secret' \
    120     http://localhost:9966/private/accounts \
    121     -d '{"payto_uri":"'"$FORTYTHREE"'"}' \
    122     -w "%{http_code}" -s -o /dev/null)
    123 
    124 if [ "$STATUS" != "200" ]
    125 then
    126     exit_fail "Expected '200 OK' response. Got instead $STATUS"
    127 fi
    128 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    129     -H 'Authorization: Bearer secret-token:super_secret' \
    130     http://localhost:9966/private/accounts \
    131     -d '{"payto_uri":"payto://iban/SANDBOXX/DE270744?receiver-name=Forty+Four"}' \
    132     -w "%{http_code}" -s -o /dev/null)
    133 
    134 if [ "$STATUS" != "200" ]
    135 then
    136     exit_fail "Expected '200 OK' response. Got instead $STATUS"
    137 fi
    138 
    139 echo "Ok"
    140 
    141 
    142 echo -n "Get accounts..."
    143 STATUS=$(curl http://localhost:9966/private/accounts \
    144     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    145 PAY_URI=$(jq -r .accounts[1].payto_uri < "$LAST_RESPONSE")
    146 H_WIRE=$(jq -r .accounts[1].h_wire < "$LAST_RESPONSE")
    147 if [ "$PAY_URI" != "payto://iban/SANDBOXX/DE270744?receiver-name=Forty+Four" ]
    148 then
    149     cat "$LAST_RESPONSE" >&2
    150     exit_fail "Expected second payto URI. Got $PAY_URI"
    151 fi
    152 echo "OK"
    153 
    154 # remove one account address
    155 echo -n "Deleting one account ..."
    156 STATUS=$(curl -H "Content-Type: application/json" -X PATCH \
    157     -H 'Authorization: Bearer secret-token:super_secret' \
    158     "http://localhost:9966/private/accounts/${H_WIRE}" \
    159     -X DELETE \
    160     -w "%{http_code}" -s -o /dev/null)
    161 
    162 if [ "$STATUS" != "204" ]
    163 then
    164     exit_fail "Expected '204 No content' for deletion of ${H_WIRE}. Got instead: $STATUS"
    165 fi
    166 echo "OK"
    167 
    168 RANDOM_IMG='data:image/png;base64,abcdefg'
    169 
    170 #
    171 # CREATE AN ORDER WITHOUT TOKEN
    172 #
    173 
    174 echo -n "Creating order without TOKEN..."
    175 STATUS=$(curl 'http://localhost:9966/private/orders' \
    176     -d '{"create_token":false,"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \
    177     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    178 
    179 if [ "$STATUS" != "200" ]
    180 then
    181     cat "$LAST_RESPONSE" >&2
    182     exit_fail "Expected 200, order created. got: $STATUS"
    183 fi
    184 
    185 ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE")
    186 TOKEN=$(jq -r .token < "$LAST_RESPONSE")
    187 
    188 if [ "$TOKEN" != "null" ]
    189 then
    190     exit_fail "token should be null, got: $TOKEN"
    191 fi
    192 
    193 echo "OK"
    194 
    195 echo -n "Checking created order without TOKEN..."
    196 STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID" \
    197               -w "%{http_code}" -s -o "$LAST_RESPONSE")
    198 PAY_URI=$(jq -r .taler_pay_uri < "$LAST_RESPONSE")
    199 if [ "$PAY_URI" == "null" ]
    200 then
    201     cat "$LAST_RESPONSE" >&2
    202     exit_fail "Expected non-NULL payuri. got $PAY_URI"
    203 fi
    204 echo "OK"
    205 
    206 #
    207 # CREATE AN ORDER WITHOUT TOKEN WITH FULLFILMENT URL
    208 #
    209 
    210 echo -n "Creating order without TOKEN and fullfilment URL..."
    211 STATUS=$(curl 'http://localhost:9966/private/orders' \
    212     -d '{"create_token":false,"refund_delay":{"d_us":0},"order":{"fulfillment_url":"go_here_please", "amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \
    213     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    214 
    215 if [ "$STATUS" != "200" ]
    216 then
    217     cat "$LAST_RESPONSE" >&2
    218     exit_fail "Expected 200, order created. got: $STATUS"
    219 fi
    220 
    221 ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE")
    222 TOKEN=$(jq -r .token < "$LAST_RESPONSE")
    223 
    224 if [ "$TOKEN" != "null" ]
    225 then
    226     exit_fail "Token should be null, got: $TOKEN"
    227 fi
    228 
    229 STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID" \
    230     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    231 
    232 PAY_URI=$(jq -r .taler_pay_uri < "$LAST_RESPONSE")
    233 FULLFILMENT_URL=$(jq -r .fulfillment_url < "$LAST_RESPONSE")
    234 
    235 if [ "$FULLFILMENT_URL" != "go_here_please" ]
    236 then
    237     cat "$LAST_RESPONSE" >&2
    238     exit_fail "Expected a pay URI. got: $PAY_URI"
    239 fi
    240 
    241 if [ "$PAY_URI" == "null" ]
    242 then
    243     cat "$LAST_RESPONSE" >&2
    244     exit_fail "Expected non-NULL pay URI. Got: $PAY_URI"
    245 fi
    246 echo "OK"
    247 
    248 #
    249 # CREATE A DISCOUNT TOKEN FAMILY
    250 #
    251 echo -n "Creating discount token family..."
    252 VALID_AFTER="{\"t_s\": $(date +%s)}" # now
    253 VALID_BEFORE="{\"t_s\": $(date +%s -d "+30 days")}" # 30 days from now
    254 DURATION="{\"d_us\": $(expr 30 \* 24 \* 60 \* 60 \* 1000000)}" # 30 days
    255 STATUS=$(curl 'http://localhost:9966/private/tokenfamilies' \
    256               -d "{\"kind\": \"discount\", \"slug\":\"test-discount\", \"name\": \"Test discount\", \"description\": \"Less money $$\", \"description_i18n\": {\"en\": \"Less money $$\", \"es\": \"Menos dinero $$\"}, \"valid_after\": $VALID_AFTER, \"valid_before\": $VALID_BEFORE, \"duration\": $DURATION, \"validity_granularity\": $DURATION}" \
    257               -w "%{http_code}" -s -o "$LAST_RESPONSE")
    258 if [ "$STATUS" != "204" ]
    259 then
    260     cat "$LAST_RESPONSE" >&2
    261     exit_fail "Expected '204 OK' response. Got instead $STATUS"
    262 fi
    263 echo "Ok"
    264 
    265 #
    266 # CREATE A SUBSCRIPTION TOKEN FAMILY
    267 #
    268 echo -n "Creating subscription token family..."
    269 VALID_AFTER="{\"t_s\": $(date +%s)}" # now
    270 VALID_BEFORE="{\"t_s\": $(date +%s -d "+30 days")}" # 30 days from now
    271 DURATION="{\"d_us\": $(expr 30 \* 24 \* 60 \* 60 \* 1000000)}" # 30 days
    272 STATUS=$(curl 'http://localhost:9966/private/tokenfamilies' \
    273               -d "{\"kind\": \"subscription\", \"slug\":\"test-subscription\", \"name\": \"Test subscription\", \"description\": \"Money per month\", \"description_i18n\": {\"en\": \"Money $$$ per month\", \"es\": \"Dinero $$$ al mes\"}, \"valid_after\": $VALID_AFTER, \"valid_before\": $VALID_BEFORE, \"duration\": $DURATION, \"validity_granularity\": $DURATION}" \
    274               -w "%{http_code}" -s -o "$LAST_RESPONSE")
    275 if [ "$STATUS" != "204" ]
    276 then
    277    cat "$LAST_RESPONSE" >&2
    278    exit_fail "Expected '204 OK' response. Got instead $STATUS"
    279 fi
    280 echo "Ok"
    281 
    282 #
    283 # CREATE AN DISCOUNTABLE ORDER WITHOUT TOKEN
    284 #
    285 RANDOM_IMG='data:image/png;base64,abcdefg'
    286 
    287 echo -n "Creating discountable order..."
    288 STATUS=$(curl 'http://localhost:9966/private/orders' \
    289     -d '{"create_token":true,"refund_delay":{"d_us":0},"order":{"version":1,"summary":"Expensive purchase","products":[{"description":"Expensive steak","quantity":2,"unit":"pieces","price":"TESTKUDOS:100"}],"choices":[{"amount":"TESTKUDOS:100"},{"amount":"TESTKUDOS:10","inputs":[{"type":"token","token_family_slug":"test-discount","count":1}],"outputs":[]}]}}' \
    290     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    291 
    292 if [ "$STATUS" != "200" ]
    293 then
    294     cat "$LAST_RESPONSE" >&2
    295     exit_fail "Expected 200, order created. got: $STATUS"
    296 fi
    297 echo "OK"
    298 
    299 ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE")
    300 TOKEN=$(jq -r .token < "$LAST_RESPONSE")
    301 
    302 echo -n "Checking created order..."
    303 STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID?token=$TOKEN" \
    304               -w "%{http_code}" -s -o "$LAST_RESPONSE")
    305 PAY_URI=$(jq -r .taler_pay_uri < "$LAST_RESPONSE")
    306 if [ "$PAY_URI" == "null" ]
    307 then
    308     cat "$LAST_RESPONSE" >&2
    309     exit_fail "Expected non-NULL payuri. got $PAY_URI"
    310 fi
    311 echo "OK"
    312 
    313 echo -n "Claming order with token family ..."
    314 STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID"/claim \
    315     -d '{"nonce":"0FTTZ475NBECCZN97VFTN6DEKWVKJ8AQY9PWR6VS36JZQFS66YG0","token":"'"$TOKEN"'"}' \
    316     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    317 
    318 if [ "$STATUS" != "200" ]
    319 then
    320     cat "$LAST_RESPONSE" >&2
    321     exit_fail "Expected 200, order claimed. got: $STATUS"
    322 fi
    323 
    324 echo " OK"
    325 
    326 # echo -n "Fetching pay URL for order ..."
    327 # STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \
    328 #     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    329 
    330 # if [ "$STATUS" != "200" ]
    331 # then
    332 #     jq . < "$LAST_RESPONSE"
    333 #     exit_fail "Expected 200, getting order info before claming it. got: $STATUS"
    334 # fi
    335 
    336 # PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE")
    337 
    338 # echo " OK"
    339 
    340 # NOW=$(date +%s)
    341 
    342 # echo -n "Pay for order ${PAY_URL} ..."
    343 # taler-wallet-cli --no-throttle --wallet-db="$WALLET_DB" handle-uri "${PAY_URL}" -y 2> wallet-pay1.err > wallet-pay1.log
    344 # taler-wallet-cli --no-throttle --wallet-db="$WALLET_DB" run-until-done 2> wallet-finish-pay1.err > wallet-finish-pay1.log
    345 # NOW2=$(date +%s)
    346 # echo " OK (took $(( NOW2 - NOW )) secs )"
    347 
    348 #
    349 # CREATE ORDER WITH NON-INVENTORY AND CHECK
    350 #
    351 
    352 echo -n "Creating order with non-inventory products..."
    353 STATUS=$(curl 'http://localhost:9966/private/orders' \
    354     -d '{"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:7","summary":"3","products":[{"description":"desct","image":"'"$RANDOM_IMG"'","price":"TESTKUDOS:1","taxes":[],"unit":"u","quantity":1}]}}' \
    355     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    356 
    357 if [ "$STATUS" != "200" ]
    358 then
    359     cat "$LAST_RESPONSE" >&2
    360     exit_fail "Expected 200, order created. got: $STATUS"
    361 fi
    362 
    363 ORDER_ID=$(jq -r .order_id < "$LAST_RESPONSE")
    364 TOKEN=$(jq -r .token < "$LAST_RESPONSE")
    365 
    366 STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID"/claim \
    367     -d '{"nonce":"0FTTZ475NBECCZN97VFTN6DEKWVKJ8AQY9PWR6VS36JZQFS66YG0","token":"'"$TOKEN"'"}' \
    368     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    369 
    370 if [ "$STATUS" != "200" ]
    371 then
    372     cat "$LAST_RESPONSE" >&2
    373     exit_fail "Expected 200, order claimed. got: $STATUS"
    374 fi
    375 
    376 QUANTITY=$(jq -r .contract_terms.products[0].quantity < "$LAST_RESPONSE")
    377 if [ "$QUANTITY" != "1" ]
    378 then
    379     cat < "$LAST_RESPONSE" >&2
    380     exit_fail "Expected quantity 1. got: $QUANTITY"
    381 fi
    382 
    383 IMAGE=$(jq -r .contract_terms.products[0].image < "$LAST_RESPONSE")
    384 if [ "$IMAGE" != "$RANDOM_IMG" ]
    385 then
    386     cat "$LAST_RESPONSE" >&2
    387     exit_fail "Expected $RANDOM_IMG but got something else: $IMAGE"
    388 fi
    389 echo "OK"
    390 
    391 
    392 #
    393 # CREATE INVENTORY PRODUCT AND CLAIM IT
    394 #
    395 
    396 echo -n "Creating product..."
    397 STATUS=$(curl 'http://localhost:9966/private/products' \
    398     -d '{"product_id":"2","description":"product with id 2 and price :15","unit_price":["TESTKUDOS:15"],"unit_total_stock":"2","description_i18n":{},"unit":"","image":"'$RANDOM_IMG'","taxes":[],"address":{},"next_restock":{"t_s":"never"}}' \
    399     -w "%{http_code}" -s -o /dev/null)
    400 
    401 if [ "$STATUS" != "204" ]
    402 then
    403     exit_fail "Expected 204, product created. got: $STATUS"
    404 fi
    405 echo "OK"
    406 
    407 echo -n "Creating order with inventory products..."
    408 STATUS=$(curl 'http://localhost:9966/private/orders' \
    409     -d '{"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:7","summary":"3"},"inventory_products":[{"product_id":"2","unit_quantity":"1"}]}' \
    410     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    411 
    412 
    413 if [ "$STATUS" != "200" ]
    414 then
    415     jq . < "$LAST_RESPONSE"
    416     exit_fail "Expected 200 OK, order created response. Got: $STATUS"
    417 fi
    418 
    419 ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE")
    420 TOKEN=$(jq -e -r .token < "$LAST_RESPONSE")
    421 
    422 STATUS=$(curl http://localhost:9966/orders/"$ORDER_ID"/claim \
    423     -d '{"nonce":"1ZRJCEAGM5N98P6ATH0NSR9SP3RKQJQQ05MQJAJA57T8YNPCPWEG","token":"'"$TOKEN"'"}' \
    424     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    425 
    426 if [ "$STATUS" != "200" ]
    427 then
    428     jq . < "$LAST_RESPONSE"
    429     exit_fail "Expected 200, order claimed. got: $STATUS"
    430 fi
    431 
    432 QUANTITY=$(jq -r .contract_terms.products[0].quantity < "$LAST_RESPONSE")
    433 
    434 if [ "$QUANTITY" != "1" ]
    435 then
    436     exit_fail "Expected quantity 1. got: $QUANTITY"
    437 fi
    438 
    439 echo "OK"
    440 
    441 #
    442 # Create product in another currency
    443 #
    444 
    445 
    446 STATUS=$(curl 'http://localhost:9966/private/products' \
    447     -d '{"product_id":"1","description":"product with id 1 and price :15","unit_price":["USD:15"],"unit_total_stock":"1","description_i18n":{},"unit":"","image":"","taxes":[],"address":{},"next_restock":{"t_s":"never"}}' \
    448     -w "%{http_code}" -s -o /dev/null)
    449 
    450 if [ "$STATUS" != "204" ]
    451 then
    452     exit_fail "Expected 204 no content. got: $STATUS"
    453 fi
    454 
    455 #
    456 # CREATE ORDER AND SELL IT
    457 #
    458 
    459 echo -n "Creating order to be paid..."
    460 STATUS=$(curl 'http://localhost:9966/private/orders' \
    461     -d '{"refund_delay":{"d_us":0},"order":{"amount":"TESTKUDOS:1","summary":"payme"},"inventory_products":[{"product_id":"2","unit_quantity":"1"}]}' \
    462     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    463 
    464 if [ "$STATUS" != "200" ]
    465 then
    466     jq . < "$LAST_RESPONSE"
    467     exit_fail "Expected 200, order created. got: $STATUS"
    468 fi
    469 
    470 ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE")
    471 TOKEN=$(jq -e -r .token < "$LAST_RESPONSE")
    472 
    473 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \
    474     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    475 
    476 if [ "$STATUS" != "200" ]
    477 then
    478     jq . < "$LAST_RESPONSE"
    479     exit_fail "Expected 200, getting order info. got: $STATUS"
    480 fi
    481 
    482 PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE")
    483 
    484 echo "OK"
    485 
    486 NOW=$(date +%s)
    487 
    488 echo -n "Pay first order ${PAY_URL} ..."
    489 taler-wallet-cli \
    490     --no-throttle \
    491     --wallet-db="$WALLET_DB" \
    492     handle-uri "${PAY_URL}" \
    493     -y 2> wallet-pay1.err > wallet-pay1.log
    494 timeout 60 taler-wallet-cli \
    495     --no-throttle \
    496     --wallet-db="$WALLET_DB" \
    497     run-until-done 2> wallet-finish-pay1.err > wallet-finish-pay1.log
    498 NOW2=$(date +%s)
    499 echo " OK (took $(( NOW2 - NOW )) secs )"
    500 
    501 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \
    502     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    503 
    504 if [ "$STATUS" != "200" ]
    505 then
    506     jq . < "$LAST_RESPONSE"
    507     exit_fail "Expected 200, after pay. got: $STATUS"
    508 fi
    509 
    510 ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE")
    511 
    512 if [ "$ORDER_STATUS" != "paid" ]
    513 then
    514     jq . < "$LAST_RESPONSE"
    515     exit_fail "Order status should be 'paid'. got: $ORDER_STATUS"
    516 fi
    517 
    518 #
    519 # WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND
    520 #
    521 
    522 # PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE")
    523 WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE")
    524 
    525 NOW=$(date +%s)
    526 
    527 TO_SLEEP=$((1200 + WIRE_DEADLINE - NOW ))
    528 echo "Waiting $TO_SLEEP secs for wire transfer"
    529 
    530 echo -n "Call taler-exchange-aggregator ..."
    531 taler-exchange-aggregator \
    532     -y \
    533     -c "$CONF" \
    534     -T "${TO_SLEEP}"000000 \
    535     -t \
    536     -L INFO &> aggregator.log
    537 echo " DONE"
    538 echo -n "Call taler-exchange-transfer ..."
    539 taler-exchange-transfer \
    540     -c "$CONF" \
    541     -t \
    542     -L INFO &> transfer.log
    543 echo " DONE"
    544 echo -n "Give time to Nexus to route the payment to Sandbox..."
    545 # FIXME: trigger immediate update at nexus
    546 # NOTE: once libeufin can do long-polling, we should
    547 # be able to reduce the delay here and run aggregator/transfer
    548 # always in the background via setup
    549 sleep 3
    550 echo " DONE"
    551 
    552 echo -n "Obtaining wire transfer details from bank ($USE_FAKEBANK)..."
    553 
    554 BANKDATA="$(curl 'http://localhost:8082/accounts/exchange/taler-wire-gateway/history/outgoing?delta=1' -s)"
    555 WTID=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].wtid)
    556 WURL=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].exchange_base_url)
    557 CREDIT_AMOUNT=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].amount)
    558 TARGET_PAYTO=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].credit_account)
    559 
    560 if [ "$EXCHANGE_URL" != "$WURL" ]
    561 then
    562     exit_fail "Wrong exchange URL in '$BANKDATA' response, expected '$EXCHANGE_URL'"
    563 fi
    564 
    565 echo " OK"
    566 
    567 set +e
    568 
    569 echo -n "Notifying merchant of bogus wire transfer ..."
    570 
    571 STATUS=$(curl 'http://localhost:9966/private/transfers' \
    572     -d '{"credit_amount":"'"$CREDIT_AMOUNT"'1","wtid":"'"$WTID"'","payto_uri":"'"$TARGET_PAYTO"'","exchange_url":"'"$WURL"'"}' \
    573     -m 3 \
    574     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    575 
    576 if [ "$STATUS" != "204" ]
    577 then
    578     jq . < "$LAST_RESPONSE"
    579     exit_fail "Expected to fail since the amount is not valid. got: $STATUS"
    580 fi
    581 
    582 echo "OK"
    583 
    584 echo -n "Deleting bogus wire transfer ..."
    585 
    586 TID=$(curl -s http://localhost:9966/private/transfers | jq -r .transfers[0].transfer_serial_id)
    587 STATUS=$(curl -H "Content-Type: application/json" -X DELETE \
    588     "http://localhost:9966/private/transfers/$TID" \
    589     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    590 
    591 if [ "$STATUS" != "204" ]
    592 then
    593     jq . < "$LAST_RESPONSE"
    594     exit_fail "Expected response 204 No Content, after deleting valid TID. got: $STATUS"
    595 fi
    596 
    597 STATUS=$(curl -H "Content-Type: application/json" -X DELETE \
    598     "http://localhost:9966/private/transfers/$TID" \
    599     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    600 if [ "$STATUS" != "404" ]
    601 then
    602     jq . < "$LAST_RESPONSE"
    603     exit_fail "Expected response 404 Not found, after deleting TID again. got: $STATUS"
    604 fi
    605 
    606 echo " OK"
    607 
    608 echo -n "Notifying merchant of correct wire transfer..."
    609 
    610 STATUS=$(curl 'http://localhost:9966/private/transfers' \
    611     -d '{"credit_amount":"'"$CREDIT_AMOUNT"'","wtid":"'"$WTID"'","payto_uri":"'"$TARGET_PAYTO"'","exchange_url":"'"$WURL"'"}' \
    612     -m 3 \
    613     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    614 
    615 if [ "$STATUS" != "204" ]
    616 then
    617     jq . < "$LAST_RESPONSE"
    618     exit_fail "Expected response 204 No content, after providing transfer data. got: $STATUS"
    619 fi
    620 
    621 echo " OK"
    622 
    623 echo -n "Running taler-merchant-depositcheck ..."
    624 set -e
    625 taler-merchant-depositcheck \
    626     -L INFO \
    627     -c "$CONF" \
    628     -T "${TO_SLEEP}"000000 \
    629     -t &> taler-merchant-depositcheck.log
    630 echo " OK"
    631 
    632 echo -n "Running taler-merchant-reconciliation ..."
    633 set -e
    634 taler-merchant-reconciliation \
    635     -L INFO \
    636     -c "$CONF" \
    637     -T "${TO_SLEEP}"000000 \
    638     -t &> taler-merchant-reconciliation.log
    639 echo " OK"
    640 
    641 
    642 echo -n "Fetching wire transfers ..."
    643 
    644 STATUS=$(curl 'http://localhost:9966/private/transfers' \
    645     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    646 
    647 if [ "$STATUS" != "200" ]
    648 then
    649     jq . < "$LAST_RESPONSE"
    650     exit_fail "Expected response 200 Ok. got: $STATUS"
    651 fi
    652 
    653 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    654 
    655 if [ "$TRANSFERS_LIST_SIZE" != "1" ]
    656 then
    657     jq . < "$LAST_RESPONSE"
    658     exit_fail "Expected 1 entry in transfer list. Got: $TRANSFERS_LIST_SIZE"
    659 fi
    660 
    661 echo "OK"
    662 
    663 echo -n "Checking order status ..."
    664 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}?transfer=YES" \
    665     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    666 if [ "$STATUS" != "200" ]
    667 then
    668     jq . < "$LAST_RESPONSE"
    669     exit_fail "Expected 200, after order inquiry. got: $STATUS"
    670 fi
    671 DEPOSIT_TOTAL=$(jq -r .deposit_total < "$LAST_RESPONSE")
    672 if [ "$DEPOSIT_TOTAL" == "TESTKUDOS:0" ]
    673 then
    674     jq . < "$LAST_RESPONSE"
    675     exit_fail "Expected non-zero deposit total. got: $DEPOSIT_TOTAL"
    676 fi
    677 echo " OK"
    678 
    679 echo -n "Checking bank account status ..."
    680 if [ 1 = "$USE_FAKEBANK" ]
    681 then
    682     STATUS=$(curl "http://localhost:8082/accounts/fortythree" \
    683                   -w "%{http_code}" \
    684                   -s \
    685                   -o "$LAST_RESPONSE")
    686     if [ "$STATUS" != "200" ]
    687     then
    688         jq . < "$LAST_RESPONSE"
    689         exit_fail "Expected response 200 Ok, getting account status. Got: $STATUS"
    690     fi
    691     BALANCE=$(jq -r .balance.amount < "$LAST_RESPONSE")
    692     if [ "$BALANCE" == "TESTKUDOS:0" ]
    693     then
    694         jq . < "$LAST_RESPONSE"
    695         exit_fail "Wire transfer did not happen. Got: $BALANCE"
    696     fi
    697 else
    698     ACCOUNT_PASSWORD="fortythree:x"
    699     BANK_HOST="localhost:18082"
    700     STATUS=$(curl "http://$ACCOUNT_PASSWORD@$BANK_HOST/accounts/fortythree" \
    701                   -w "%{http_code}" -s -o "$LAST_RESPONSE")
    702     if [ "$STATUS" != "200" ]
    703     then
    704         jq . < "$LAST_RESPONSE"
    705         exit_fail "Expected response 200 Ok, getting account status. Got: $STATUS"
    706     fi
    707     BALANCE=$(jq -r .balance.amount < "$LAST_RESPONSE")
    708     if [ "$BALANCE" == "TESTKUDOS:0" ]
    709     then
    710         jq . < "$LAST_RESPONSE"
    711         exit_fail "Wire transfer did not happen. Got: $BALANCE"
    712     fi
    713 fi
    714 echo " OK"
    715 
    716 echo -n "Getting information about kyc ..."
    717 STATUS=$(curl -H "Content-Type: application/json" -X GET \
    718     http://localhost:9966/private/kyc \
    719     -w "%{http_code}" -s -o /dev/null)
    720 if [ "$STATUS" != "200" ]
    721 then
    722     exit_fail "Expected 200. Got: $STATUS"
    723 fi
    724 echo " OK"
    725 
    726 exit 0