merchant

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

test_merchant_transfer_tracking.sh (27411B)


      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 echo -n "Checking unwired value in order listing..."
    232 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders?limit=20' \
    233     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    234 if [ "$STATUS" != "200" ]
    235 then
    236     cat "$LAST_RESPONSE"
    237     exit_fail "Expected 200 ok listing unwired order. got: $STATUS"
    238 fi
    239 LIST_WIRED=$(jq -r --arg order_id "$ORDER_ID" \
    240     '.orders[] | select(.order_id == $order_id) | .wired' < "$LAST_RESPONSE")
    241 if [ "$LIST_WIRED" != "false" ]
    242 then
    243     jq . < "$LAST_RESPONSE"
    244     exit_fail "Order list .wired was not false before settlement"
    245 fi
    246 echo " OK"
    247 
    248 # "max_age" was deprecated in protocol v33, but MUST still work.
    249 echo -n "Checking order listing with deprecated max_age..."
    250 check_order_listing 'max_age=3600000' some
    251 check_order_listing 'max_age=0' none
    252 echo " OK"
    253 
    254 # If both are given, "max_age_s" wins (and the backend logs a warning).
    255 echo -n "Checking that max_age_s takes precedence over max_age..."
    256 check_order_listing 'max_age=0&max_age_s=3600' some
    257 check_order_listing 'max_age=3600000&max_age_s=0' none
    258 echo " OK"
    259 
    260 echo -n "Checking for Typst ..."
    261 if typst --version 2> /dev/null > /dev/null 
    262 then
    263     echo " OK"
    264 
    265 
    266     # Check max-age argument
    267     echo -n "Checking order list generation with max-age..."
    268     STATUS=$(curl 'http://localhost:9966/instances/test/private/orders?max_age=3600000' \
    269               -H 'Accept: application/pdf' \
    270               -w "%{http_code}" \
    271               -s \
    272               -o "$LAST_RESPONSE")
    273 
    274     if [ "$STATUS" != "200" ]
    275     then
    276         cat "$LAST_RESPONSE"
    277         exit_fail "Expected 200 ok, order created. got: $STATUS"
    278     fi
    279     # If we want to see the order list...
    280     # cat $LAST_RESPONSE > order-list.pdf
    281     echo " OK"
    282 else
    283     echo " Not found, skipping test"
    284 fi
    285 
    286 echo -n "Checking order status before claiming it..."
    287 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    288     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    289 
    290 if [ "$STATUS" != "200" ]
    291 then
    292     cat "$LAST_RESPONSE"
    293     exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS"
    294 fi
    295 PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE")
    296 echo "OK"
    297 
    298 NOW=$(date +%s)
    299 echo -n "Pay first order ..."
    300 taler-wallet-cli \
    301     --no-throttle \
    302     --wallet-db="$WALLET_DB" \
    303     handle-uri "${PAY_URL}" \
    304     -y \
    305     2> wallet-pay1.err > wallet-pay1.log
    306 NOW2=$(date +%s)
    307 echo " OK (took $(( NOW2 - NOW )) secs)"
    308 
    309 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    310     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    311 
    312 if [ "$STATUS" != "200" ]
    313 then
    314     cat "$LAST_RESPONSE"
    315     exit_fail "Expected 200 ok, after pay. got: $STATUS"
    316 fi
    317 
    318 ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE")
    319 
    320 if [ "$ORDER_STATUS" != "paid" ]
    321 then
    322     cat "$LAST_RESPONSE"
    323     exit_fail "Expected 'paid'. got: $ORDER_STATUS"
    324 fi
    325 
    326 #
    327 # WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND
    328 #
    329 
    330 #PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE")
    331 WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE")
    332 
    333 NOW=$(date +%s)
    334 
    335 TO_SLEEP=$((3600 + WIRE_DEADLINE - NOW ))
    336 echo "waiting $TO_SLEEP secs for wire transfer"
    337 
    338 echo -n "Perform wire transfers ..."
    339 taler-exchange-aggregator -y -c $CONF -T ${TO_SLEEP}000000 -t -L INFO &> aggregator.log
    340 taler-exchange-transfer -c $CONF -t -L INFO &> transfer.log
    341 echo " DONE"
    342 
    343 echo -n "Obtaining wire transfer details from bank..."
    344 
    345 BANKDATA="$(curl 'http://localhost:8082/accounts/exchange/taler-wire-gateway/history/outgoing?delta=1' -s)"
    346 WTID=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].wtid)
    347 WURL=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].exchange_base_url)
    348 CREDIT_AMOUNT=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].amount)
    349 TARGET_PAYTO=$(echo "$BANKDATA" | jq -r .outgoing_transactions[0].credit_account)
    350 TARGET=$(echo "$TARGET_PAYTO" | awk -F = '{print $2}')
    351 
    352 # Figure out which account got paid, in order to
    353 # resort the right (and complete: including the receiver-name)
    354 # TARGET_PAYTO
    355 if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then
    356   TARGET_PAYTO="$SURVEY_PAYTO";
    357 fi
    358 if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then
    359   TARGET_PAYTO="$SURVEY_PAYTO";
    360 fi
    361 if [ "$EXCHANGE_URL" != "$WURL" ]
    362 then
    363     exit_fail "Wrong exchange URL in subject '$SUBJECT', expected $EXCHANGE_URL"
    364 fi
    365 echo " OK"
    366 
    367 set +e
    368 
    369 echo -n "Notifying merchant of correct wire transfer, but on wrong instance..."
    370 
    371 #issue 6912
    372 #here we are notifying the transfer into a wrong instance (admin) and the payto_uri of the admin instance
    373 STATUS=$(curl 'http://localhost:9966/private/transfers' \
    374     -d "{\"credit_amount\":\"$CREDIT_AMOUNT\",\"wtid\":\"$WTID\",\"payto_uri\":\"$TOR_PAYTO\",\"exchange_url\":\"$WURL\"}" \
    375     -m 3 \
    376     -w "%{http_code}" \
    377     -s \
    378     -o "$LAST_RESPONSE")
    379 
    380 if [ "$STATUS" != "204" ]
    381 then
    382     jq . < "$LAST_RESPONSE"
    383     exit_fail "Expected response 204 no content, after providing transfer data. Got: $STATUS"
    384 fi
    385 echo " OK"
    386 
    387 
    388 echo -n "Fetching wire transfers of ADMIN instance ..."
    389 
    390 STATUS=$(curl 'http://localhost:9966/private/transfers' \
    391               -w "%{http_code}" \
    392               -s \
    393               -o "$LAST_RESPONSE")
    394 
    395 if [ "$STATUS" != "200" ]
    396 then
    397     jq . < "$LAST_RESPONSE"
    398     exit_fail "Expected response 200 Ok. got: $STATUS"
    399 fi
    400 
    401 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    402 
    403 if [ "$TRANSFERS_LIST_SIZE" != "1" ]
    404 then
    405     jq . < "$LAST_RESPONSE"
    406     exit_fail "Expected one transfer. got: $TRANSFERS_LIST_SIZE"
    407 fi
    408 
    409 echo "OK"
    410 
    411 echo -n "Fetching running taler-merchant-reconciliation on bogus transfer ..."
    412 taler-merchant-reconciliation \
    413     -c "$CONF" \
    414     -L INFO \
    415     -t &> taler-merchant-reconciliation0.log
    416 echo "OK"
    417 
    418 echo -n "Fetching wire transfers of 'test' instance ..."
    419 
    420 STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \
    421               -w "%{http_code}" \
    422               -s \
    423               -o "$LAST_RESPONSE")
    424 
    425 if [ "$STATUS" != "200" ]
    426 then
    427     jq . < "$LAST_RESPONSE"
    428     exit_fail "Expected response 200 Ok. got: $STATUS"
    429 fi
    430 
    431 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    432 
    433 if [ "$TRANSFERS_LIST_SIZE" != "0" ]
    434 then
    435     jq . < "$LAST_RESPONSE"
    436     exit_fail "Expected non-empty transfer list size. got: $TRANSFERS_LIST_SIZE"
    437 fi
    438 
    439 echo "OK"
    440 
    441 echo -n "Checking order status ..."
    442 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}?transfer=YES" \
    443     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    444 
    445 if [ "$STATUS" != "200" ]
    446 then
    447     jq . < "$LAST_RESPONSE"
    448     exit_fail "Expected 200 ok, after order inquiry. got: $STATUS"
    449 fi
    450 
    451 WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE")
    452 
    453 if [ "$WAS_WIRED" == "true" ]
    454 then
    455     jq . < "$LAST_RESPONSE"
    456     exit_fail ".wired is true, expected false"
    457 fi
    458 
    459 echo " OK"
    460 
    461 echo -n "Notifying merchant of correct wire transfer in the correct instance..."
    462 #this time in the correct instance so the order will be marked as wired...
    463 
    464 echo -n "Running taler-merchant-wirewatch to check transfer ..."
    465 taler-merchant-wirewatch \
    466     -c $CONF \
    467     -t \
    468     -L INFO &> taler-merchant-wirewatch1.log
    469 echo " DONE"
    470 
    471 echo -n "Post-check for exchange deposit ..."
    472 taler-merchant-depositcheck \
    473     -c $CONF \
    474     -t \
    475     -e "http://localhost:8081/" \
    476     -T ${TO_SLEEP}000000 \
    477     -L INFO &> depositcheck1a.log
    478 echo " DONE"
    479 
    480 echo -n "Fetching running taler-merchant-reconciliation on good transfer ..."
    481 taler-merchant-reconciliation \
    482     -c $CONF \
    483     -L INFO \
    484     -T ${TO_SLEEP}000000 \
    485     -t &> taler-merchant-reconciliation1.log
    486 echo "OK"
    487 
    488 echo -n "Fetching wire transfers of TEST instance ..."
    489 
    490 STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \
    491               -w "%{http_code}" \
    492               -s \
    493               -o "$LAST_RESPONSE")
    494 
    495 if [ "$STATUS" != "200" ]
    496 then
    497     jq . < "$LAST_RESPONSE"
    498     exit_fail "Expected response 200 Ok. got: $STATUS"
    499 fi
    500 
    501 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    502 
    503 if [ "$TRANSFERS_LIST_SIZE" != "1" ]
    504 then
    505     jq . < "$LAST_RESPONSE"
    506     exit_fail "Expected one transfer. got: $TRANSFERS_LIST_SIZE"
    507 fi
    508 
    509 echo "OK"
    510 
    511 echo -n "Checking order status ..."
    512 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    513     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    514 
    515 if [ "$STATUS" != "200" ]
    516 then
    517     jq . < "$LAST_RESPONSE"
    518     exit_fail "Expected 200 ok, after order inquiry. got: $STATUS"
    519 fi
    520 
    521 WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE")
    522 
    523 if [ "$WAS_WIRED" != "true" ]
    524 then
    525     jq . < "$LAST_RESPONSE"
    526     exit_fail ".wired false, expected true"
    527 fi
    528 
    529 echo " OK"
    530 
    531 echo -n "Checking wired value and filter in order listing..."
    532 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders?limit=20&wired=YES' \
    533     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    534 if [ "$STATUS" != "200" ]
    535 then
    536     cat "$LAST_RESPONSE"
    537     exit_fail "Expected 200 ok listing wired order. got: $STATUS"
    538 fi
    539 LIST_WIRED=$(jq -e -r --arg order_id "$ORDER_ID" \
    540     '.orders[] | select(.order_id == $order_id) | .wired' < "$LAST_RESPONSE")
    541 if [ "$LIST_WIRED" != "true" ]
    542 then
    543     jq . < "$LAST_RESPONSE"
    544     exit_fail "Order list .wired was not true after settlement"
    545 fi
    546 echo " OK"
    547 
    548 
    549 echo "================== 2nd order ====================== "
    550 
    551 
    552 
    553 # CREATE ORDER AND SELL IT
    554 echo -n "Creating 2nd order to be paid..."
    555 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    556     -d '{"refund_delay":{"d_us":0}, "order":{"amount":"TESTKUDOS:2","summary":"payme"}}' \
    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, order created. got: $STATUS"
    563 fi
    564 
    565 ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE")
    566 #TOKEN=$(jq -e -r .token < "$LAST_RESPONSE")
    567 
    568 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    569     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    570 
    571 if [ "$STATUS" != "200" ]
    572 then
    573     cat "$LAST_RESPONSE"
    574     exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS"
    575 fi
    576 PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE")
    577 echo "OK"
    578 
    579 NOW=$(date +%s)
    580 echo -n "Pay second order ..."
    581 taler-wallet-cli \
    582     --no-throttle \
    583     --wallet-db="$WALLET_DB" \
    584     handle-uri "${PAY_URL}" \
    585     -y \
    586     2> wallet-pay2.err > wallet-pay2.log
    587 NOW2=$(date +%s)
    588 echo " OK (took $(( NOW2 - NOW )) secs)"
    589 
    590 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    591     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    592 
    593 if [ "$STATUS" != "200" ]
    594 then
    595     cat "$LAST_RESPONSE"
    596     exit_fail "Expected 200 ok, after pay. got: $STATUS"
    597 fi
    598 
    599 ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE")
    600 
    601 if [ "$ORDER_STATUS" != "paid" ]
    602 then
    603     cat "$LAST_RESPONSE"
    604     exit_fail "Expected 'paid'. got: $ORDER_STATUS"
    605 fi
    606 
    607 #
    608 # WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND
    609 #
    610 
    611 #PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE")
    612 WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE")
    613 
    614 NOW=$(date +%s)
    615 
    616 TO_SLEEP=$((3600 + WIRE_DEADLINE - NOW ))
    617 echo "waiting $TO_SLEEP secs for wire transfer"
    618 
    619 echo -n "Pre-check for exchange deposit ..."
    620 taler-merchant-depositcheck \
    621     -c $CONF \
    622     -t \
    623     -e "http://localhost:8081/" \
    624     -L INFO &> depositcheck1b.log
    625 echo " DONE"
    626 
    627 echo -n "Perform wire transfers ..."
    628 taler-exchange-aggregator \
    629     -y \
    630     -c $CONF \
    631     -T ${TO_SLEEP}000000 \
    632     -t \
    633     -L INFO &> aggregator2.log
    634 taler-exchange-transfer \
    635     -c $CONF \
    636     -t \
    637     -L INFO &> transfer2.log
    638 echo " DONE"
    639 
    640 echo -n "Post-check for exchange deposit ..."
    641 taler-merchant-depositcheck \
    642     -c $CONF \
    643     -t \
    644     -e "http://localhost:8081/" \
    645     -T ${TO_SLEEP}000000 \
    646     -L INFO &> depositcheck1c.log
    647 echo " DONE"
    648 
    649 
    650 echo -n "Obtaining wire transfer details from bank..."
    651 
    652 BANKDATA="$(curl 'http://localhost:8082/accounts/exchange/taler-wire-gateway/history/outgoing?delta=2' -s)"
    653 
    654 WTID=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].wtid)
    655 WURL=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].exchange_base_url)
    656 CREDIT_AMOUNT=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].amount)
    657 TARGET_PAYTO=$(echo "$BANKDATA" | jq -r .outgoing_transactions[1].credit_account)
    658 TARGET=$(echo "$TARGET_PAYTO" | awk -F = '{print $2}')
    659 
    660 # Figure out which account got paid, in order to
    661 # resort the right (and complete: including the receiver-name)
    662 # TARGET_PAYTO
    663 if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then
    664   TARGET_PAYTO="$SURVEY_PAYTO";
    665 fi
    666 if echo "$SURVEY_PAYTO" | grep -q "$TARGET" > /dev/null; then
    667   TARGET_PAYTO="$SURVEY_PAYTO";
    668 fi
    669 if [ "$EXCHANGE_URL" != "$WURL" ]
    670 then
    671     exit_fail "Wrong exchange URL in subject '$SUBJECT', expected $EXCHANGE_URL"
    672 fi
    673 echo " OK"
    674 
    675 echo -n "Running taler-merchant-wirewatch to check transfer ..."
    676 taler-merchant-wirewatch \
    677     -c $CONF \
    678     -t \
    679     -L INFO &> taler-merchant-wirewatch2.log
    680 echo " DONE"
    681 
    682 echo -n "Fetching running taler-merchant-reconciliation on good transfer ..."
    683 taler-merchant-reconciliation \
    684     -c $CONF \
    685     -L INFO \
    686     -T ${TO_SLEEP}000000 \
    687     -t &> taler-merchant-reconciliation2.log
    688 echo "OK"
    689 
    690 echo -n "Fetching wire transfers of TEST instance ..."
    691 
    692 STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \
    693               -w "%{http_code}" \
    694               -s \
    695               -o "$LAST_RESPONSE")
    696 
    697 if [ "$STATUS" != "200" ]
    698 then
    699     jq . < "$LAST_RESPONSE"
    700     exit_fail "Expected response 200 Ok. got: $STATUS"
    701 fi
    702 
    703 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    704 
    705 if [ "$TRANSFERS_LIST_SIZE" != "2" ]
    706 then
    707     jq . < "$LAST_RESPONSE"
    708     exit_fail "Expected two transfers. got: $TRANSFERS_LIST_SIZE"
    709 fi
    710 
    711 echo "OK"
    712 
    713 echo -n "Checking order status ..."
    714 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    715     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    716 
    717 if [ "$STATUS" != "200" ]
    718 then
    719     jq . < "$LAST_RESPONSE"
    720     exit_fail "Expected 200 ok, after order inquiry. got: $STATUS"
    721 fi
    722 
    723 WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE")
    724 
    725 if [ "$WAS_WIRED" != "true" ]
    726 then
    727     jq . < "$LAST_RESPONSE"
    728     exit_fail ".wired false, expected true"
    729 fi
    730 
    731 echo " OK"
    732 
    733 echo "================== 3rd order ====================== "
    734 
    735 # CREATE ORDER AND SELL IT
    736 echo -n "Creating 3rd order to be paid..."
    737 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    738     -d '{"refund_delay":{"d_us":0}, "order":{"amount":"TESTKUDOS:3","summary":"payme"}}' \
    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, order created. got: $STATUS"
    745 fi
    746 
    747 ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE")
    748 #TOKEN=$(jq -e -r .token < "$LAST_RESPONSE")
    749 
    750 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    751     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    752 
    753 if [ "$STATUS" != "200" ]
    754 then
    755     cat "$LAST_RESPONSE"
    756     exit_fail "Expected 200 ok, getting order info before claming it. got: $STATUS"
    757 fi
    758 PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE")
    759 echo "OK"
    760 
    761 NOW=$(date +%s)
    762 echo -n "Pay third order ..."
    763 taler-wallet-cli \
    764     --no-throttle \
    765     --wallet-db="$WALLET_DB" \
    766     handle-uri "${PAY_URL}" \
    767     -y \
    768     2> wallet-pay2.err > wallet-pay2.log
    769 NOW2=$(date +%s)
    770 echo " OK (took $(( NOW2 - NOW )) secs)"
    771 
    772 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    773     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    774 
    775 if [ "$STATUS" != "200" ]
    776 then
    777     cat "$LAST_RESPONSE"
    778     exit_fail "Expected 200 ok, after pay. got: $STATUS"
    779 fi
    780 
    781 ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE")
    782 
    783 if [ "$ORDER_STATUS" != "paid" ]
    784 then
    785     cat "$LAST_RESPONSE"
    786     exit_fail "Expected 'paid'. got: $ORDER_STATUS"
    787 fi
    788 
    789 #
    790 # WIRE TRANSFER TO MERCHANT AND NOTIFY BACKEND
    791 #
    792 
    793 #PAY_DEADLINE=$(jq -r .contract_terms.pay_deadline.t_s < "$LAST_RESPONSE")
    794 WIRE_DEADLINE=$(jq -r .contract_terms.wire_transfer_deadline.t_s < "$LAST_RESPONSE")
    795 
    796 NOW=$(date +%s)
    797 
    798 TO_SLEEP=$((1200 + WIRE_DEADLINE - NOW ))
    799 echo "waiting $TO_SLEEP secs for wire transfer"
    800 
    801 echo -n "Perform wire transfers for 3rd order..."
    802 taler-exchange-aggregator \
    803     -y \
    804     -c $CONF \
    805     -T ${TO_SLEEP}000000 \
    806     -t \
    807     -L INFO &> aggregator3.log
    808 taler-exchange-transfer \
    809     -c $CONF \
    810     -t \
    811     -L INFO &> transfer3.log
    812 echo " DONE"
    813 
    814 echo -n "Running taler-merchant-wirewatch to check transfer ..."
    815 taler-merchant-wirewatch \
    816     -c $CONF \
    817     -t \
    818     -L INFO &> taler-merchant-wirewatch3.log
    819 echo " DONE"
    820 
    821 echo -n "Post-wirewatch check for exchange deposit ..."
    822 taler-merchant-depositcheck \
    823     -c $CONF \
    824     -t \
    825     -e "http://localhost:8081/" \
    826     -T ${TO_SLEEP}000000 \
    827     -L INFO &> depositcheck1d.log
    828 echo " DONE"
    829 
    830 echo -n "Fetching wire transfers of TEST instance ..."
    831 
    832 STATUS=$(curl 'http://localhost:9966/instances/test/private/transfers' \
    833               -w "%{http_code}" \
    834               -s \
    835               -o "$LAST_RESPONSE")
    836 
    837 if [ "$STATUS" != "200" ]
    838 then
    839     jq . < "$LAST_RESPONSE"
    840     exit_fail "Expected response 200 Ok. got: $STATUS"
    841 fi
    842 
    843 TRANSFERS_LIST_SIZE=$(jq -r '.transfers | length' < "$LAST_RESPONSE")
    844 
    845 if [ "$TRANSFERS_LIST_SIZE" != "3" ]
    846 then
    847     jq . < "$LAST_RESPONSE"
    848     exit_fail "Expected three transfers. got: $TRANSFERS_LIST_SIZE"
    849 fi
    850 
    851 echo "OK"
    852 
    853 echo -n "Fetching running taler-merchant-reconciliation on good transfer ..."
    854 taler-merchant-reconciliation \
    855     -c $CONF \
    856     -L INFO \
    857     -T ${TO_SLEEP}000000 \
    858     -t &> taler-merchant-reconciliation3.log
    859 echo "OK"
    860 
    861 echo -n "Checking order status ..."
    862 STATUS=$(curl "http://localhost:9966/instances/test/private/orders/${ORDER_ID}" \
    863     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    864 
    865 if [ "$STATUS" != "200" ]
    866 then
    867     jq . < "$LAST_RESPONSE"
    868     exit_fail "Expected 200 ok, after order inquiry. got: $STATUS"
    869 fi
    870 
    871 WAS_WIRED=$(jq -r .wired < "$LAST_RESPONSE")
    872 
    873 if [ "$WAS_WIRED" != "true" ]
    874 then
    875     jq . < "$LAST_RESPONSE"
    876     exit_fail ".wired false, expected true"
    877 fi
    878 
    879 EXPECTED_TRANSFER_SERIAL=$(jq -r .wire_details[0].expected_transfer_serial_id < "$LAST_RESPONSE")
    880 
    881 echo " OK"
    882 
    883 echo -n "Checking reconciliation details ..."
    884 STATUS=$(curl "http://localhost:9966/instances/test/private/incoming/${EXPECTED_TRANSFER_SERIAL}" \
    885     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    886 
    887 if [ "$STATUS" != "200" ]
    888 then
    889     jq . < "$LAST_RESPONSE"
    890     exit_fail "Expected 200 ok. got: $STATUS"
    891 fi
    892 
    893 SETTLED_ORDER_ID=$(jq -r .reconciliation_details[0].order_id < "$LAST_RESPONSE")
    894 
    895 if [ "$SETTLED_ORDER_ID" != "$ORDER_ID" ]
    896 then
    897     jq . < "$LAST_RESPONSE"
    898     exit_fail ".order_id false, expected $ORDER_ID, got $SETTLED_ORDER_ID"
    899 fi
    900 
    901 echo " OK"
    902 
    903 echo -n "Checking for Typst ..."
    904 if typst --version 2> /dev/null > /dev/null 
    905 then
    906     echo " OK"
    907 
    908     echo -n "Fetch order list as PDF..."
    909     STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    910               -H "Accept: application/pdf" \
    911               -w "%{http_code}" \
    912               -s \
    913               -o "$LAST_RESPONSE")
    914 
    915     if [ "$STATUS" != "200" ]
    916     then
    917         cat "$LAST_RESPONSE" >&2
    918         exit_fail "Expected 200, PDF created. got: $STATUS"
    919     fi
    920     # To keep PDF
    921     # mv $LAST_RESPONSE test.pdf
    922     echo "OK"
    923 else
    924     echo " Not found, skipping test"
    925 fi
    926 
    927 echo -n "Fetch order list as CSV..."
    928 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    929               -H "Accept: text/csv" \
    930               -w "%{http_code}" \
    931               -s \
    932               -o "$LAST_RESPONSE")
    933 
    934 if [ "$STATUS" != "200" ]
    935 then
    936     cat "$LAST_RESPONSE" >&2
    937     exit_fail "Expected 200, CSV created. got: $STATUS"
    938 fi
    939 # To keep CSV
    940 # mv $LAST_RESPONSE test.csv
    941 echo "OK"
    942 
    943 echo -n "Fetch order list as XLS..."
    944 STATUS=$(curl 'http://localhost:9966/instances/test/private/orders' \
    945               -H "Accept: application/vnd.ms-excel" \
    946               -w "%{http_code}" \
    947               -s \
    948               -o "$LAST_RESPONSE")
    949 
    950 if [ "$STATUS" != "200" ]
    951 then
    952     cat "$LAST_RESPONSE" >&2
    953     exit_fail "Expected 200, XLS created. got: $STATUS"
    954 fi
    955 # To keep XLS
    956 # mv $LAST_RESPONSE test.xls
    957 echo "OK"
    958 
    959 
    960 echo "TEST PASSED"
    961 exit 0