merchant

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

test_merchant_transfer_tracking.sh (26240B)


      1 #!/usr/bin/env bash
      2 # This file is part of TALER
      3 # Copyright (C) 2014-2026 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 # Testcase for #6912 and #8061
     20 
     21 set -eu
     22 
     23 . setup.sh
     24 
     25 # Replace with 0 for nexus...
     26 USE_FAKEBANK=1
     27 if [ 1 = "$USE_FAKEBANK" ]
     28 then
     29     ACCOUNT="exchange-account-2"
     30     WIRE_METHOD="x-taler-bank"
     31     BANK_FLAGS="-f -d $WIRE_METHOD -u $ACCOUNT"
     32     BANK_URL="http://localhost:8082/"
     33 else
     34     echo -n "Testing for libeufin-bank"
     35     libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING"
     36     echo " FOUND"
     37     ACCOUNT="exchange-account-1"
     38     WIRE_METHOD="iban"
     39     BANK_FLAGS="-ns -d $WIRE_METHOD -u $ACCOUNT"
     40     BANK_URL="http://localhost:18082/"
     41 fi
     42 
     43 
     44 echo -n "Testing for taler-harness"
     45 taler-harness --help >/dev/null </dev/null || exit_skip " MISSING"
     46 echo " FOUND"
     47 
     48 # Launch system.
     49 setup -c "test_template.conf" \
     50       -r "merchant-exchange-default" \
     51       -em \
     52       $BANK_FLAGS
     53 LAST_RESPONSE=$(mktemp -p "${TMPDIR:-/tmp}" test_response.conf-XXXXXX)
     54 WALLET_DB=$(mktemp -p "${TMPDIR:-/tmp}" test_wallet.json-XXXXXX)
     55 CONF="test_template.conf.edited"
     56 EXCHANGE_URL="http://localhost:8081/"
     57 
     58 echo -n "First prepare wallet with coins..."
     59 rm -f "$WALLET_DB"
     60 taler-wallet-cli \
     61     --no-throttle \
     62     --wallet-db="$WALLET_DB" \
     63     api \
     64     --expect-success 'withdrawTestBalance' \
     65   "$(jq -n '
     66     {
     67         amount: "TESTKUDOS:99",
     68         corebankApiBaseUrl: $BANK_URL,
     69         exchangeBaseUrl: $EXCHANGE_URL
     70     }' \
     71     --arg BANK_URL "${BANK_URL}" \
     72     --arg EXCHANGE_URL "$EXCHANGE_URL"
     73   )" 2>wallet-withdraw-1.err >wallet-withdraw-1.out
     74 echo -n "."
     75 if [ 1 = "$USE_FAKEBANK" ]
     76 then
     77     # Fakebank is instant...
     78     sleep 0
     79 else
     80     sleep 10
     81     # NOTE: once libeufin can do long-polling, we should
     82     # be able to reduce the delay here and run wirewatch
     83     # always in the background via setup
     84 fi
     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     -L "INFO" \
     91     -c "$CONF" \
     92     -t &> taler-exchange-wirewatch0.out
     93 echo -n "."
     94 
     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 #
    103 # CREATE INSTANCE FOR TESTING
    104 #
    105 
    106 echo -n "Configuring merchant admin instance ..."
    107 if [ 1 = "$USE_FAKEBANK" ]
    108 then
    109     TOR_PAYTO="payto://x-taler-bank/localhost/tor?receiver-name=tor"
    110     GNUNET_PAYTO="payto://x-taler-bank/localhost/gnunet?receiver-name=gnunet"
    111     SURVEY_PAYTO="payto://x-taler-bank/localhost/survey?receiver-name=survey"
    112     TUTORIAL_PAYTO="payto://x-taler-bank/localhost/tutorial?receiver-name=tutorial"
    113 else
    114     TOR_PAYTO=$(get_payto_uri tor x)
    115     GNUNET_PAYTO=$(get_payto_uri gnunet x)
    116     SURVEY_PAYTO=$(get_payto_uri survey x)
    117     TUTORIAL_PAYTO=$(get_payto_uri tutorial x)
    118 fi
    119 # create with 2 address
    120 
    121 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    122     -H 'Authorization: Bearer secret-token:super_secret' \
    123     http://localhost:9966/management/instances \
    124     -d '{"auth":{"method":"external"},"id":"admin","name":"default","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \
    125     -w "%{http_code}" -s -o /dev/null)
    126 
    127 if [ "$STATUS" != "204" ]
    128 then
    129     exit_fail "Expected 204, instance created. got: $STATUS"
    130 fi
    131 
    132 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    133     -H 'Authorization: Bearer secret-token:super_secret' \
    134     http://localhost:9966/private/accounts \
    135     -d '{"payto_uri":"'"$TOR_PAYTO"'"}' \
    136     -w "%{http_code}" -s -o /dev/null)
    137 
    138 if [ "$STATUS" != "200" ]
    139 then
    140     exit_fail "Expected 200 OK. Got: $STATUS"
    141 fi
    142 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    143     -H 'Authorization: Bearer secret-token:super_secret' \
    144     http://localhost:9966/private/accounts \
    145     -d '{"payto_uri":"'"$GNUNET_PAYTO"'"}' \
    146     -w "%{http_code}" -s -o /dev/null)
    147 
    148 if [ "$STATUS" != "200" ]
    149 then
    150     exit_fail "Expected 200 OK. Got: $STATUS"
    151 fi
    152 
    153 echo "OK"
    154 
    155 echo -n "Configuring merchant test instance ..."
    156 # create with 2 address
    157 
    158 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    159     -H 'Authorization: Bearer secret-token:super_secret' \
    160     http://localhost:9966/management/instances \
    161     -d '{"auth":{"method":"external"},"id":"test","name":"test","user_type":"business","address":{},"jurisdiction":{},"use_stefan":true,"default_wire_transfer_delay":{"d_us" : 50000000},"default_pay_delay":{"d_us": 60000000}}' \
    162     -w "%{http_code}" -s -o /dev/null)
    163 
    164 if [ "$STATUS" != "204" ]
    165 then
    166     exit_fail "Expected 204, instance created. got: $STATUS"
    167 fi
    168 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    169     -H 'Authorization: Bearer secret-token:super_secret' \
    170     http://localhost:9966/instances/test/private/accounts \
    171     -d '{"payto_uri":"'"$SURVEY_PAYTO"'","credit_facade_url":"http://localhost:8082/accounts/survey/taler-revenue/","credit_facade_credentials":{"type":"basic","username":"survey","password":"x"}}' \
    172     -w "%{http_code}" -s -o /dev/null)
    173 
    174 if [ "$STATUS" != "200" ]
    175 then
    176     exit_fail "Expected 200 OK. Got: $STATUS"
    177 fi
    178 
    179 # CREATE ORDER AND SELL IT
    180 echo -n "Creating order to be paid..."
    181 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    182     -d '{"refund_delay":{"d_us":0}, "order":{"amount":"TESTKUDOS:1","summary":"payme"}}' \
    183     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    184 
    185 if [ "$STATUS" != "200" ]
    186 then
    187     cat "$LAST_RESPONSE"
    188     exit_fail "Expected 200 ok, order created. got: $STATUS"
    189 fi
    190 
    191 echo " OK"
    192 
    193 ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE")
    194 #TOKEN=$(jq -e -r .token < "$LAST_RESPONSE")
    195 
    196 # Lists orders with the given extra query arguments and checks whether the
    197 # order created above is included ($2 is "some") or filtered out ($2 is
    198 # "none").  The age filters only apply to an ascending listing, hence the
    199 # hard-coded positive "limit".
    200 check_order_listing() {
    201     local args="$1"
    202     local expect="$2"
    203     local status
    204     local num
    205 
    206     status=$(curl "http://localhost:9966/instances/test/private/orders?limit=20&$args" \
    207               -w "%{http_code}" \
    208               -s \
    209               -o "$LAST_RESPONSE")
    210     if [ "$status" != "200" ]
    211     then
    212         cat "$LAST_RESPONSE"
    213         exit_fail "Expected 200 ok listing orders with '$args'. got: $status"
    214     fi
    215     num=$(jq -e -r '.orders | length' < "$LAST_RESPONSE")
    216     if [ "none" = "$expect" ] && [ "0" != "$num" ]
    217     then
    218         exit_fail "Expected no orders listed with '$args', got $num"
    219     fi
    220     if [ "some" = "$expect" ] && [ "0" = "$num" ]
    221     then
    222         exit_fail "Expected orders to be listed with '$args', got none"
    223     fi
    224 }
    225 
    226 echo -n "Checking order listing with max_age_s..."
    227 check_order_listing 'max_age_s=3600' some
    228 check_order_listing 'max_age_s=0' none
    229 echo " OK"
    230 
    231 # "max_age" was deprecated in protocol v33, but MUST still work.
    232 echo -n "Checking order listing with deprecated max_age..."
    233 check_order_listing 'max_age=3600000' some
    234 check_order_listing 'max_age=0' none
    235 echo " OK"
    236 
    237 # If both are given, "max_age_s" wins (and the backend logs a warning).
    238 echo -n "Checking that max_age_s takes precedence over max_age..."
    239 check_order_listing 'max_age=0&max_age_s=3600' some
    240 check_order_listing 'max_age=3600000&max_age_s=0' none
    241 echo " OK"
    242 
    243 echo -n "Checking for Typst ..."
    244 if typst --version 2> /dev/null > /dev/null 
    245 then
    246     echo " OK"
    247 
    248 
    249     # Check max-age argument
    250     echo -n "Checking order list generation with max-age..."
    251     STATUS=$(curl 'http://localhost:9966/instances/test/private/orders?max_age=3600000' \
    252               -H 'Accept: application/pdf' \
    253               -w "%{http_code}" \
    254               -s \
    255               -o "$LAST_RESPONSE")
    256 
    257     if [ "$STATUS" != "200" ]
    258     then
    259         cat "$LAST_RESPONSE"
    260         exit_fail "Expected 200 ok, order created. got: $STATUS"
    261     fi
    262     # If we want to see the order list...
    263     # cat $LAST_RESPONSE > order-list.pdf
    264     echo " OK"
    265 else
    266     echo " Not found, skipping test"
    267 fi
    268 
    269 echo -n "Checking order status before claiming it..."
    270 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    271     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    272 
    273 if [ "$STATUS" != "200" ]
    274 then
    275     cat "$LAST_RESPONSE"
    276     exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS"
    277 fi
    278 PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE")
    279 echo "OK"
    280 
    281 NOW=$(date +%s)
    282 echo -n "Pay first order ..."
    283 taler-wallet-cli \
    284     --no-throttle \
    285     --wallet-db="$WALLET_DB" \
    286     handle-uri "${PAY_URL}" \
    287     -y \
    288     2> wallet-pay1.err > wallet-pay1.log
    289 NOW2=$(date +%s)
    290 echo " OK (took $(( NOW2 - NOW )) secs)"
    291 
    292 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    293     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    294 
    295 if [ "$STATUS" != "200" ]
    296 then
    297     cat "$LAST_RESPONSE"
    298     exit_fail "Expected 200 ok, after pay. got: $STATUS"
    299 fi
    300 
    301 ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE")
    302 
    303 if [ "$ORDER_STATUS" != "paid" ]
    304 then
    305     cat "$LAST_RESPONSE"
    306     exit_fail "Expected 'paid'. got: $ORDER_STATUS"
    307 fi
    308 
    309 #
    310 # WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND
    311 #
    312 
    313 #PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE")
    314 WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE")
    315 
    316 NOW=$(date +%s)
    317 
    318 TO_SLEEP=$((3600 + WIRE_DEADLINE - NOW ))
    319 echo "waiting $TO_SLEEP secs for wire transfer"
    320 
    321 echo -n "Perform wire transfers ..."
    322 taler-exchange-aggregator -y -c $CONF -T ${TO_SLEEP}000000 -t -L INFO &> aggregator.log
    323 taler-exchange-transfer -c $CONF -t -L INFO &> transfer.log
    324 echo " DONE"
    325 
    326 echo -n "Obtaining wire transfer details from bank..."
    327 
    328 BANKDATA="$(curl 'http://localhost:8082/accounts/exchange/taler-wire-gateway/history/outgoing?delta=1' -s)"
    329 WTID=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].wtid)
    330 WURL=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].exchange_base_url)
    331 CREDIT_AMOUNT=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].amount)
    332 TARGET_PAYTO=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].credit_account)
    333 TARGET=$(echo "$TARGET_PAYTO" | awk -F = '{print $2}')
    334 
    335 # Figure out which account got paid, in order to
    336 # resort the right (and complete: including the receiver-name)
    337 # TARGET_PAYTO
    338 if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then
    339   TARGET_PAYTO="$SURVEY_PAYTO";
    340 fi
    341 if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then
    342   TARGET_PAYTO="$SURVEY_PAYTO";
    343 fi
    344 if [ "$EXCHANGE_URL" != "$WURL" ]
    345 then
    346     exit_fail "Wrong exchange URL in subject '$SUBJECT', expected $EXCHANGE_URL"
    347 fi
    348 echo " OK"
    349 
    350 set +e
    351 
    352 echo -n "Notifying merchant of correct wire transfer, but on wrong instance..."
    353 
    354 #issue 6912
    355 #here we are notifying the transfer into a wrong instance (admin) and the payto_uri of the admin instance
    356 STATUS=$(curl 'http://localhost:9966/private/transfers' \
    357     -d "{\"credit_amount\":\"$CREDIT_AMOUNT\",\"wtid\":\"$WTID\",\"payto_uri\":\"$TOR_PAYTO\",\"exchange_url\":\"$WURL\"}" \
    358     -m 3 \
    359     -w "%{http_code}" \
    360     -s \
    361     -o "$LAST_RESPONSE")
    362 
    363 if [ "$STATUS" != "204" ]
    364 then
    365     jq . < "$LAST_RESPONSE"
    366     exit_fail "Expected response 204 no content, after providing transfer data. Got: $STATUS"
    367 fi
    368 echo " OK"
    369 
    370 
    371 echo -n "Fetching wire transfers of ADMIN instance ..."
    372 
    373 STATUS=$(curl 'http://localhost:9966/private/transfers' \
    374               -w "%{http_code}" \
    375               -s \
    376               -o "$LAST_RESPONSE")
    377 
    378 if [ "$STATUS" != "200" ]
    379 then
    380     jq . < "$LAST_RESPONSE"
    381     exit_fail "Expected response 200 Ok. got: $STATUS"
    382 fi
    383 
    384 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    385 
    386 if [ "$TRANSFERS_LIST_SIZE" != "1" ]
    387 then
    388     jq . < "$LAST_RESPONSE"
    389     exit_fail "Expected one transfer. got: $TRANSFERS_LIST_SIZE"
    390 fi
    391 
    392 echo "OK"
    393 
    394 echo -n "Fetching running taler-merchant-reconciliation on bogus transfer ..."
    395 taler-merchant-reconciliation \
    396     -c "$CONF" \
    397     -L INFO \
    398     -t &> taler-merchant-reconciliation0.log
    399 echo "OK"
    400 
    401 echo -n "Fetching wire transfers of 'test' instance ..."
    402 
    403 STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \
    404               -w "%{http_code}" \
    405               -s \
    406               -o "$LAST_RESPONSE")
    407 
    408 if [ "$STATUS" != "200" ]
    409 then
    410     jq . < "$LAST_RESPONSE"
    411     exit_fail "Expected response 200 Ok. got: $STATUS"
    412 fi
    413 
    414 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    415 
    416 if [ "$TRANSFERS_LIST_SIZE" != "0" ]
    417 then
    418     jq . < "$LAST_RESPONSE"
    419     exit_fail "Expected non-empty transfer list size. got: $TRANSFERS_LIST_SIZE"
    420 fi
    421 
    422 echo "OK"
    423 
    424 echo -n "Checking order status ..."
    425 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}?transfer=YES" \
    426     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    427 
    428 if [ "$STATUS" != "200" ]
    429 then
    430     jq . < "$LAST_RESPONSE"
    431     exit_fail "Expected 200 ok, after order inquiry. got: $STATUS"
    432 fi
    433 
    434 WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE")
    435 
    436 if [ "$WAS_WIRED" == "true" ]
    437 then
    438     jq . < "$LAST_RESPONSE"
    439     exit_fail ".wired is true, expected false"
    440 fi
    441 
    442 echo " OK"
    443 
    444 echo -n "Notifying merchant of correct wire transfer in the correct instance..."
    445 #this time in the correct instance so the order will be marked as wired...
    446 
    447 echo -n "Running taler-merchant-wirewatch to check transfer ..."
    448 taler-merchant-wirewatch \
    449     -c $CONF \
    450     -t \
    451     -L INFO &> taler-merchant-wirewatch1.log
    452 echo " DONE"
    453 
    454 echo -n "Post-check for exchange deposit ..."
    455 taler-merchant-depositcheck \
    456     -c $CONF \
    457     -t \
    458     -e "http://localhost:8081/" \
    459     -T ${TO_SLEEP}000000 \
    460     -L INFO &> depositcheck1a.log
    461 echo " DONE"
    462 
    463 echo -n "Fetching running taler-merchant-reconciliation on good transfer ..."
    464 taler-merchant-reconciliation \
    465     -c $CONF \
    466     -L INFO \
    467     -T ${TO_SLEEP}000000 \
    468     -t &> taler-merchant-reconciliation1.log
    469 echo "OK"
    470 
    471 echo -n "Fetching wire transfers of TEST instance ..."
    472 
    473 STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \
    474               -w "%{http_code}" \
    475               -s \
    476               -o "$LAST_RESPONSE")
    477 
    478 if [ "$STATUS" != "200" ]
    479 then
    480     jq . < "$LAST_RESPONSE"
    481     exit_fail "Expected response 200 Ok. got: $STATUS"
    482 fi
    483 
    484 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    485 
    486 if [ "$TRANSFERS_LIST_SIZE" != "1" ]
    487 then
    488     jq . < "$LAST_RESPONSE"
    489     exit_fail "Expected one transfer. got: $TRANSFERS_LIST_SIZE"
    490 fi
    491 
    492 echo "OK"
    493 
    494 echo -n "Checking order status ..."
    495 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    496     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    497 
    498 if [ "$STATUS" != "200" ]
    499 then
    500     jq . < "$LAST_RESPONSE"
    501     exit_fail "Expected 200 ok, after order inquiry. got: $STATUS"
    502 fi
    503 
    504 WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE")
    505 
    506 if [ "$WAS_WIRED" != "true" ]
    507 then
    508     jq . < "$LAST_RESPONSE"
    509     exit_fail ".wired false, expected true"
    510 fi
    511 
    512 echo " OK"
    513 
    514 
    515 echo "================== 2nd order ====================== "
    516 
    517 
    518 
    519 # CREATE ORDER AND SELL IT
    520 echo -n "Creating 2nd order to be paid..."
    521 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    522     -d '{"refund_delay":{"d_us":0}, "order":{"amount":"TESTKUDOS:2","summary":"payme"}}' \
    523     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    524 
    525 if [ "$STATUS" != "200" ]
    526 then
    527     cat "$LAST_RESPONSE"
    528     exit_fail "Expected 200 ok, order created. got: $STATUS"
    529 fi
    530 
    531 ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE")
    532 #TOKEN=$(jq -e -r .token < "$LAST_RESPONSE")
    533 
    534 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    535     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    536 
    537 if [ "$STATUS" != "200" ]
    538 then
    539     cat "$LAST_RESPONSE"
    540     exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS"
    541 fi
    542 PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE")
    543 echo "OK"
    544 
    545 NOW=$(date +%s)
    546 echo -n "Pay second order ..."
    547 taler-wallet-cli \
    548     --no-throttle \
    549     --wallet-db="$WALLET_DB" \
    550     handle-uri "${PAY_URL}" \
    551     -y \
    552     2> wallet-pay2.err > wallet-pay2.log
    553 NOW2=$(date +%s)
    554 echo " OK (took $(( NOW2 - NOW )) secs)"
    555 
    556 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    557     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    558 
    559 if [ "$STATUS" != "200" ]
    560 then
    561     cat "$LAST_RESPONSE"
    562     exit_fail "Expected 200 ok, after pay. got: $STATUS"
    563 fi
    564 
    565 ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE")
    566 
    567 if [ "$ORDER_STATUS" != "paid" ]
    568 then
    569     cat "$LAST_RESPONSE"
    570     exit_fail "Expected 'paid'. got: $ORDER_STATUS"
    571 fi
    572 
    573 #
    574 # WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND
    575 #
    576 
    577 #PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE")
    578 WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE")
    579 
    580 NOW=$(date +%s)
    581 
    582 TO_SLEEP=$((3600 + WIRE_DEADLINE - NOW ))
    583 echo "waiting $TO_SLEEP secs for wire transfer"
    584 
    585 echo -n "Pre-check for exchange deposit ..."
    586 taler-merchant-depositcheck \
    587     -c $CONF \
    588     -t \
    589     -e "http://localhost:8081/" \
    590     -L INFO &> depositcheck1b.log
    591 echo " DONE"
    592 
    593 echo -n "Perform wire transfers ..."
    594 taler-exchange-aggregator \
    595     -y \
    596     -c $CONF \
    597     -T ${TO_SLEEP}000000 \
    598     -t \
    599     -L INFO &> aggregator2.log
    600 taler-exchange-transfer \
    601     -c $CONF \
    602     -t \
    603     -L INFO &> transfer2.log
    604 echo " DONE"
    605 
    606 echo -n "Post-check for exchange deposit ..."
    607 taler-merchant-depositcheck \
    608     -c $CONF \
    609     -t \
    610     -e "http://localhost:8081/" \
    611     -T ${TO_SLEEP}000000 \
    612     -L INFO &> depositcheck1c.log
    613 echo " DONE"
    614 
    615 
    616 echo -n "Obtaining wire transfer details from bank..."
    617 
    618 BANKDATA="$(curl 'http://localhost:8082/accounts/exchange/taler-wire-gateway/history/outgoing?delta=2' -s)"
    619 
    620 WTID=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].wtid)
    621 WURL=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].exchange_base_url)
    622 CREDIT_AMOUNT=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].amount)
    623 TARGET_PAYTO=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].credit_account)
    624 TARGET=$(echo "$TARGET_PAYTO" | awk -F = '{print $2}')
    625 
    626 # Figure out which account got paid, in order to
    627 # resort the right (and complete: including the receiver-name)
    628 # TARGET_PAYTO
    629 if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then
    630   TARGET_PAYTO="$SURVEY_PAYTO";
    631 fi
    632 if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then
    633   TARGET_PAYTO="$SURVEY_PAYTO";
    634 fi
    635 if [ "$EXCHANGE_URL" != "$WURL" ]
    636 then
    637     exit_fail "Wrong exchange URL in subject '$SUBJECT', expected $EXCHANGE_URL"
    638 fi
    639 echo " OK"
    640 
    641 echo -n "Running taler-merchant-wirewatch to check transfer ..."
    642 taler-merchant-wirewatch \
    643     -c $CONF \
    644     -t \
    645     -L INFO &> taler-merchant-wirewatch2.log
    646 echo " DONE"
    647 
    648 echo -n "Fetching running taler-merchant-reconciliation on good transfer ..."
    649 taler-merchant-reconciliation \
    650     -c $CONF \
    651     -L INFO \
    652     -T ${TO_SLEEP}000000 \
    653     -t &> taler-merchant-reconciliation2.log
    654 echo "OK"
    655 
    656 echo -n "Fetching wire transfers of TEST instance ..."
    657 
    658 STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \
    659               -w "%{http_code}" \
    660               -s \
    661               -o "$LAST_RESPONSE")
    662 
    663 if [ "$STATUS" != "200" ]
    664 then
    665     jq . < "$LAST_RESPONSE"
    666     exit_fail "Expected response 200 Ok. got: $STATUS"
    667 fi
    668 
    669 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    670 
    671 if [ "$TRANSFERS_LIST_SIZE" != "2" ]
    672 then
    673     jq . < "$LAST_RESPONSE"
    674     exit_fail "Expected two transfers. got: $TRANSFERS_LIST_SIZE"
    675 fi
    676 
    677 echo "OK"
    678 
    679 echo -n "Checking order status ..."
    680 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    681     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    682 
    683 if [ "$STATUS" != "200" ]
    684 then
    685     jq . < "$LAST_RESPONSE"
    686     exit_fail "Expected 200 ok, after order inquiry. got: $STATUS"
    687 fi
    688 
    689 WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE")
    690 
    691 if [ "$WAS_WIRED" != "true" ]
    692 then
    693     jq . < "$LAST_RESPONSE"
    694     exit_fail ".wired false, expected true"
    695 fi
    696 
    697 echo " OK"
    698 
    699 echo "================== 3rd order ====================== "
    700 
    701 # CREATE ORDER AND SELL IT
    702 echo -n "Creating 3rd order to be paid..."
    703 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    704     -d '{"refund_delay":{"d_us":0}, "order":{"amount":"TESTKUDOS:3","summary":"payme"}}' \
    705     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    706 
    707 if [ "$STATUS" != "200" ]
    708 then
    709     cat "$LAST_RESPONSE"
    710     exit_fail "Expected 200 ok, order created. got: $STATUS"
    711 fi
    712 
    713 ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE")
    714 #TOKEN=$(jq -e -r .token < "$LAST_RESPONSE")
    715 
    716 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    717     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    718 
    719 if [ "$STATUS" != "200" ]
    720 then
    721     cat "$LAST_RESPONSE"
    722     exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS"
    723 fi
    724 PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE")
    725 echo "OK"
    726 
    727 NOW=$(date +%s)
    728 echo -n "Pay third order ..."
    729 taler-wallet-cli \
    730     --no-throttle \
    731     --wallet-db="$WALLET_DB" \
    732     handle-uri "${PAY_URL}" \
    733     -y \
    734     2> wallet-pay2.err > wallet-pay2.log
    735 NOW2=$(date +%s)
    736 echo " OK (took $(( NOW2 - NOW )) secs)"
    737 
    738 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    739     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    740 
    741 if [ "$STATUS" != "200" ]
    742 then
    743     cat "$LAST_RESPONSE"
    744     exit_fail "Expected 200 ok, after pay. got: $STATUS"
    745 fi
    746 
    747 ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE")
    748 
    749 if [ "$ORDER_STATUS" != "paid" ]
    750 then
    751     cat "$LAST_RESPONSE"
    752     exit_fail "Expected 'paid'. got: $ORDER_STATUS"
    753 fi
    754 
    755 #
    756 # WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND
    757 #
    758 
    759 #PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE")
    760 WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE")
    761 
    762 NOW=$(date +%s)
    763 
    764 TO_SLEEP=$((1200 + WIRE_DEADLINE - NOW ))
    765 echo "waiting $TO_SLEEP secs for wire transfer"
    766 
    767 echo -n "Perform wire transfers for 3rd order..."
    768 taler-exchange-aggregator \
    769     -y \
    770     -c $CONF \
    771     -T ${TO_SLEEP}000000 \
    772     -t \
    773     -L INFO &> aggregator3.log
    774 taler-exchange-transfer \
    775     -c $CONF \
    776     -t \
    777     -L INFO &> transfer3.log
    778 echo " DONE"
    779 
    780 echo -n "Running taler-merchant-wirewatch to check transfer ..."
    781 taler-merchant-wirewatch \
    782     -c $CONF \
    783     -t \
    784     -L INFO &> taler-merchant-wirewatch3.log
    785 echo " DONE"
    786 
    787 echo -n "Post-wirewatch check for exchange deposit ..."
    788 taler-merchant-depositcheck \
    789     -c $CONF \
    790     -t \
    791     -e "http://localhost:8081/" \
    792     -T ${TO_SLEEP}000000 \
    793     -L INFO &> depositcheck1d.log
    794 echo " DONE"
    795 
    796 echo -n "Fetching wire transfers of TEST instance ..."
    797 
    798 STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \
    799               -w "%{http_code}" \
    800               -s \
    801               -o "$LAST_RESPONSE")
    802 
    803 if [ "$STATUS" != "200" ]
    804 then
    805     jq . < "$LAST_RESPONSE"
    806     exit_fail "Expected response 200 Ok. got: $STATUS"
    807 fi
    808 
    809 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    810 
    811 if [ "$TRANSFERS_LIST_SIZE" != "3" ]
    812 then
    813     jq . < "$LAST_RESPONSE"
    814     exit_fail "Expected three transfers. got: $TRANSFERS_LIST_SIZE"
    815 fi
    816 
    817 echo "OK"
    818 
    819 echo -n "Fetching running taler-merchant-reconciliation on good transfer ..."
    820 taler-merchant-reconciliation \
    821     -c $CONF \
    822     -L INFO \
    823     -T ${TO_SLEEP}000000 \
    824     -t &> taler-merchant-reconciliation3.log
    825 echo "OK"
    826 
    827 echo -n "Checking order status ..."
    828 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    829     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    830 
    831 if [ "$STATUS" != "200" ]
    832 then
    833     jq . < "$LAST_RESPONSE"
    834     exit_fail "Expected 200 ok, after order inquiry. got: $STATUS"
    835 fi
    836 
    837 WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE")
    838 
    839 if [ "$WAS_WIRED" != "true" ]
    840 then
    841     jq . < "$LAST_RESPONSE"
    842     exit_fail ".wired false, expected true"
    843 fi
    844 
    845 EXPECTED_TRANSFER_SERIAL=$(jq -r .wire_details[0].expected_transfer_serial_id < "$LAST_RESPONSE")
    846 
    847 echo " OK"
    848 
    849 echo -n "Checking reconciliation details ..."
    850 STATUS=$(curl "http://localhost:9966/instances/test/private/incoming/${EXPECTED_TRANSFER_SERIAL}" \
    851     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    852 
    853 if [ "$STATUS" != "200" ]
    854 then
    855     jq . < "$LAST_RESPONSE"
    856     exit_fail "Expected 200 ok. got: $STATUS"
    857 fi
    858 
    859 SETTLED_ORDER_ID=$(jq -r .reconciliation_details[0].order_id < "$LAST_RESPONSE")
    860 
    861 if [ "$SETTLED_ORDER_ID" != "$ORDER_ID" ]
    862 then
    863     jq . < "$LAST_RESPONSE"
    864     exit_fail ".order_id false, expected $ORDER_ID, got $SETTLED_ORDER_ID"
    865 fi
    866 
    867 echo " OK"
    868 
    869 echo -n "Checking for Typst ..."
    870 if typst --version 2> /dev/null > /dev/null 
    871 then
    872     echo " OK"
    873 
    874     echo -n "Fetch order list as PDF..."
    875     STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    876               -H "Accept: application/pdf" \
    877               -w "%{http_code}" \
    878               -s \
    879               -o "$LAST_RESPONSE")
    880 
    881     if [ "$STATUS" != "200" ]
    882     then
    883         cat "$LAST_RESPONSE" >&2
    884         exit_fail "Expected 200, PDF created. got: $STATUS"
    885     fi
    886     # To keep PDF
    887     # mv $LAST_RESPONSE test.pdf
    888     echo "OK"
    889 else
    890     echo " Not found, skipping test"
    891 fi
    892 
    893 echo -n "Fetch order list as CSV..."
    894 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    895               -H "Accept: text/csv" \
    896               -w "%{http_code}" \
    897               -s \
    898               -o "$LAST_RESPONSE")
    899 
    900 if [ "$STATUS" != "200" ]
    901 then
    902     cat "$LAST_RESPONSE" >&2
    903     exit_fail "Expected 200, CSV created. got: $STATUS"
    904 fi
    905 # To keep CSV
    906 # mv $LAST_RESPONSE test.csv
    907 echo "OK"
    908 
    909 echo -n "Fetch order list as XLS..."
    910 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    911               -H "Accept: application/vnd.ms-excel" \
    912               -w "%{http_code}" \
    913               -s \
    914               -o "$LAST_RESPONSE")
    915 
    916 if [ "$STATUS" != "200" ]
    917 then
    918     cat "$LAST_RESPONSE" >&2
    919     exit_fail "Expected 200, XLS created. got: $STATUS"
    920 fi
    921 # To keep XLS
    922 # mv $LAST_RESPONSE test.xls
    923 echo "OK"
    924 
    925 
    926 echo "TEST PASSED"
    927 exit 0