merchant

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

test_merchant_order_creation.sh (26007B)


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