merchant

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

test_merchant_order_refund.sh (8762B)


      1 #!/usr/bin/env bash
      2 # This file is in the public domain.
      3 
      4 set -eu
      5 
      6 function clean_wallet() {
      7     echo 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:18082/"
     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       -em \
     55       -r "merchant-exchange-default" \
     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 echo -n "Configuring merchant instance ..."
    113 
    114 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    115     http://localhost:9966/management/instances \
    116     -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}}' \
    117     -w "%{http_code}" -s -o /dev/null)
    118 
    119 if [ "$STATUS" != "204" ]
    120 then
    121     exit_fail "Expected '204 No content' response. Got instead $STATUS"
    122 fi
    123 ADMIN_TOKEN=$(merchant_login admin super_secret)
    124 echo "Ok"
    125 
    126 echo -n "Configuring merchant account ..."
    127 
    128 if [ 1 = "$USE_FAKEBANK" ]
    129 then
    130     FORTYTHREE="payto://x-taler-bank/localhost/fortythree?receiver-name=fortythree"
    131 else
    132     FORTYTHREE=$(get_payto_uri fortythree x)
    133 fi
    134 # create with 2 bank account addresses
    135 STATUS=$(curl -H "Content-Type: application/json" -X POST \
    136     -H "Authorization: Bearer $ADMIN_TOKEN" \
    137     http://localhost:9966/private/accounts \
    138     -d '{"payto_uri":"'"$FORTYTHREE"'"}' \
    139     -w "%{http_code}" -s -o /dev/null)
    140 
    141 if [ "$STATUS" != "200" ]
    142 then
    143     exit_fail "Expected '200 OK' response. Got instead $STATUS"
    144 fi
    145 
    146 echo "Ok"
    147 
    148 
    149 #
    150 # CREATE ORDER AND SELL IT
    151 #
    152 
    153 echo -n "Creating order to be paid..."
    154 STATUS=$(curl 'http://localhost:9966/private/orders' \
    155     -H "Authorization: Bearer $ADMIN_TOKEN" \
    156     -d '{"order":{"amount":"TESTKUDOS:5","summary":"payme","auto_refund":{"d_us":180000000}}}' \
    157     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    158 
    159 if [ "$STATUS" != "200" ]
    160 then
    161     jq . < "$LAST_RESPONSE"
    162     exit_fail "Expected 200, order created. got: $STATUS"
    163 fi
    164 
    165 ORDER_ID=$(jq -e -r .order_id < "$LAST_RESPONSE")
    166 TOKEN=$(jq -e -r .token < "$LAST_RESPONSE")
    167 
    168 RESPONSE_HEADERS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \
    169                         -H "Authorization: Bearer $ADMIN_TOKEN" \
    170                         -w "%{header_json}" \
    171                         -s \
    172                         -o "$LAST_RESPONSE")
    173 
    174 ETAG=$(echo "$RESPONSE_HEADERS" | jq -r .etag[0])
    175 ETAG_NQ=$(echo "$ETAG" | tr -d '"')
    176 PAY_URL=$(jq -e -r .taler_pay_uri < "$LAST_RESPONSE")
    177 
    178 echo "OK"
    179 
    180 LP_START=$(date +%s)
    181 
    182 echo -n "Long-polling for order status change paid..."
    183 
    184 curl "http://localhost:9966/private/orders/${ORDER_ID}?timeout_ms=30000&lp_not_etag=${ETAG_NQ}" \
    185      -H "Authorization: Bearer $ADMIN_TOKEN" \
    186      -H "If-none-match: $ETAG" \
    187      -w "%{header_json}" \
    188      -s \
    189      -o "${LAST_RESPONSE}-long-poll" &
    190 LP_PID="$!"
    191 
    192 #
    193 # PAY THE ORDER
    194 #
    195 
    196 # FIXME: use claim-only first:
    197 # $ taler-wallet-cli api 'preparePayForUri' '{"talerPayUri":"taler://pay/backend.demo.taler.net/instances/blog/2026.035-0184YVPMMWKKE/b4f09f9c-f863-4805-9caf-4f849e5eb34b?c=0P603WJ9T6TYTC7Z6QRDFXEJQ0"}'
    198 
    199 
    200 # set -x
    201 PAYMENT_START=$(date +%s)
    202 echo "Pay first order ${PAY_URL} ..."
    203 taler-wallet-cli \
    204     --no-throttle \
    205     -V \
    206     --wallet-db="$WALLET_DB" \
    207     handle-uri "${PAY_URL}" \
    208     -y \
    209     2> wallet-pay1.err \
    210     > wallet-pay1.log
    211 PAYMENT_END=$(date +%s)
    212 echo " OK (payment took $(( PAYMENT_END - PAYMENT_START )) secs )"
    213 
    214 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}" \
    215     -H "Authorization: Bearer $ADMIN_TOKEN" \
    216     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    217 
    218 if [ "$STATUS" != "200" ]
    219 then
    220     jq . < "$LAST_RESPONSE"
    221     exit_fail "Expected 200, after pay. got: $STATUS"
    222 fi
    223 
    224 ORDER_STATUS=$(jq -r .order_status < "$LAST_RESPONSE")
    225 
    226 if [ "$ORDER_STATUS" != "paid" ]
    227 then
    228     jq . < "$LAST_RESPONSE"
    229     exit_fail "Order status should be 'paid'. got: $ORDER_STATUS"
    230 fi
    231 
    232 # Wait for long-poller
    233 echo -e "Wait for long-poller ..."
    234 wait $LP_PID &> /dev/null
    235 LP_END=$(date +%s)
    236 
    237 if (( "$LP_END" - "$LP_START" > 10 ))
    238 then
    239     exit_fail "Expected long-poller to return quickly. Instead took from $LP_START to $LP_END"
    240 fi
    241 echo " OK"
    242 
    243 echo -n "Sending refund for TESTKUDOS:1 ..."
    244 
    245 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}/refund" \
    246     -H "Authorization: Bearer $ADMIN_TOKEN" \
    247     -d '{"refund":"TESTKUDOS:1","reason":"duplicated"}' \
    248     -w "%{http_code}" \
    249     -s \
    250     -o "$LAST_RESPONSE")
    251 
    252 if [ "$STATUS" != "200" ]
    253 then
    254     jq . < "$LAST_RESPONSE"
    255     exit_fail "Expected 200, after refund. got: $STATUS"
    256 fi
    257 REFUND_URI=$(jq -e -r .taler_refund_uri < "$LAST_RESPONSE")
    258 echo " OK"
    259 
    260 echo -n "Checking refund HTML..."
    261 STATUS=$(curl -H 'Accept: text/html' \
    262     "http://localhost:9966/orders/${ORDER_ID}?token=${TOKEN}" \
    263     -w "%{http_code}" -s -o "$HTML_RESPONSE")
    264 if [ "$STATUS" != "200" ]
    265 then
    266     cat "$HTML_RESPONSE" >&2
    267     exit_fail "Expected 200 refund HTML. Got: $STATUS"
    268 fi
    269 assert_html_contains "$HTML_RESPONSE" 'Collect your refund'
    270 assert_html_contains "$HTML_RESPONSE" 'TESTKUDOS:1'
    271 assert_html_contains "$HTML_RESPONSE" 'class="qr-frame"'
    272 assert_html_rendered "$HTML_RESPONSE"
    273 echo "OK"
    274 
    275 REFUND_START=$(date +%s)
    276 echo "First refund order ${REFUND_URI} ..."
    277 set -x
    278 timeout 60 taler-wallet-cli \
    279     --no-throttle \
    280     --wallet-db="$WALLET_DB" \
    281     handle-uri "${REFUND_URI}" \
    282     -y \
    283     2> wallet-refund1.err \
    284     > wallet-refund1.log
    285 REFUND_END=$(date +%s)
    286 echo " OK (refund1 took $(( REFUND_END - REFUND_START )) secs)"
    287 
    288 echo -n "Increasing refund for TESTKUDOS:3 ..."
    289 
    290 STATUS=$(curl "http://localhost:9966/private/orders/${ORDER_ID}/refund" \
    291     -H "Authorization: Bearer $ADMIN_TOKEN" \
    292     -d '{"refund":"TESTKUDOS:5","reason":"duplicated"}' \
    293     -w "%{http_code}" -s -o "$LAST_RESPONSE")
    294 
    295 if [ "$STATUS" != "200" ]
    296 then
    297     jq . < "$LAST_RESPONSE"
    298     exit_fail "Expected 200, after refund. got: $STATUS"
    299 fi
    300 REFUND_URI=$(jq -e -r .taler_refund_uri < "$LAST_RESPONSE")
    301 echo " OK"
    302 
    303 REFUND2_START=$(date +%s)
    304 echo -n "Second refund order ${REFUND_URI} ..."
    305 timeout 60 taler-wallet-cli \
    306     --no-throttle \
    307     --wallet-db="$WALLET_DB" \
    308     handle-uri "${REFUND_URI}" \
    309     -y \
    310     2> wallet-refund2.err \
    311     > wallet-refund2.log
    312 REFUND2_END=$(date +%s)
    313 echo " OK (refund2 took $(( REFUND2_END - REFUND_START )) secs)"
    314 
    315 echo "TEST PASSED"
    316 exit 0