#!/bin/bash # Sanity / ops: check paid orders wired? bank transfers? balances? # Run on koopa as root. # # Usage: # check_settlement.sh # all paid orders for goa-demo # check_settlement.sh ORDER_ID # one order # MERCHANT_INSTANCE=foo check_settlement.sh set -euo pipefail ROOT=$(cd "$(dirname "$0")" && pwd) # shellcheck source=lib.sh source "$ROOT/lib.sh" need_root INST="${MERCHANT_INSTANCE:-goa-demo-cp4zqk}" ORDER_ID="${1:-}" if ! read_pw MPW "/root/merchant-${INST}-password.txt"; then read_pw MPW /root/merchant-goa-demo-cp4zqk-password.txt || true fi if [ -z "${MPW:-}" ]; then fail "no merchant password for $INST" exit 1 fi AUTH=$(merchant_auth_header "$MPW") echo "=== Settlement check instance=$INST ===" tmp=$(mktemp) curl -sk -m 15 -H "$AUTH" -o "$tmp" \ "${MERCHANT_URL}/instances/${INST}/private/orders?paid=YES" python3 - "$tmp" "$ORDER_ID" <<'PY' import json,sys,time d=json.load(open(sys.argv[1])) want=sys.argv[2] or None orders=d.get("orders") or [] if want: orders=[o for o in orders if o.get("order_id")==want] if not orders: print("FAIL no paid orders" + (f" matching {want}" if want else "")) sys.exit(1) print(f"INFO paid_orders={len(orders)}") for o in orders: print(f" - {o.get('order_id')} amount={o.get('amount')} summary={o.get('summary')!r} paid={o.get('paid')}") sys.exit(0) PY ec=$? [ "$ec" -eq 0 ] || FAILS=$((FAILS + 1)) # Detail each order mapfile -t OIDS < <(python3 -c 'import json,sys; d=json.load(open(sys.argv[1])); want=sys.argv[2] or None oids=[o["order_id"] for o in d.get("orders",[])] print("\n".join([x for x in oids if not want or x==want]))' "$tmp" "$ORDER_ID") for oid in "${OIDS[@]}"; do echo "--- order $oid ---" ot=$(mktemp) curl -sk -m 15 -H "$AUTH" -o "$ot" \ "${MERCHANT_URL}/instances/${INST}/private/orders/${oid}" python3 - "$ot" <<'PY' import json,sys,time d=json.load(open(sys.argv[1])) ct=d.get("contract_terms") or {} ts=(ct.get("timestamp") or {}).get("t_s") rd=(ct.get("refund_deadline") or {}).get("t_s") wd=(ct.get("wire_transfer_deadline") or {}).get("t_s") now=int(time.time()) print(" status", d.get("order_status"), "wired", d.get("wired"), "deposit_total", d.get("deposit_total")) print(" amount", ct.get("amount"), "summary", ct.get("summary")) if ts and rd and wd: print(f" age_s={now-ts} refund_in_s={rd-now} wire_in_s={wd-now}") print(f" windows: refund={rd-ts}s wire_from_pay={wd-ts}s (wire_after_refund={wd-rd}s)") if now >= wd and not d.get("wired"): print(" FAIL wire deadline passed but wired=false") sys.exit(2) if now < wd: print(" INFO still before wire deadline — settlement not due yet") if d.get("wired"): print(" OK wired=true") sys.exit(0) PY ec=$? [ "$ec" -eq 2 ] && FAILS=$((FAILS + 1)) rm -f "$ot" done echo "=== private/transfers ===" tr=$(mktemp) curl -sk -m 15 -H "$AUTH" -o "$tr" \ "${MERCHANT_URL}/instances/${INST}/private/transfers" python3 -c 'import json,sys; d=json.load(open(sys.argv[1])); t=d.get("transfers") or []; print(f" transfers={len(t)}"); [print(" ", x) for x in t[:10]]' "$tr" rm -f "$tr" "$tmp" # Bank balances BANK_USER="${BANK_USER:-$INST}" if read_pw BPW "/root/bank-${BANK_USER}-password.txt" || read_pw BPW /root/bank-goa-demo-cp4zqk-password.txt; then BT=$(bank_token "$BANK_USER" "$BPW") if [ -n "$BT" ]; then curl -sS -m 12 -H "Authorization: Bearer ${BT}" \ "${BANK_URL}/accounts/${BANK_USER}" | python3 -c 'import sys,json; d=json.load(sys.stdin); print("merchant_bank_balance", d.get("balance"))' curl -sS -m 12 -H "Authorization: Bearer ${BT}" \ "${BANK_URL}/accounts/${BANK_USER}/transactions?delta=-10" \ | python3 -c 'import sys,json; d=json.load(sys.stdin); txs=d.get("transactions") or []; print(f"merchant_bank_tx={len(txs)}"); [print(f" {t.get(\"direction\")} {t.get(\"amount\")} {t.get(\"subject\",\"\")[:60]}") for t in txs[:8]]' fi fi if read_pw EPW /root/bank-exchange-password.txt; then ET=$(bank_token exchange "$EPW") if [ -n "$ET" ]; then curl -sS -m 12 -H "Authorization: Bearer ${ET}" \ "${BANK_URL}/accounts/exchange" | python3 -c 'import sys,json; d=json.load(sys.stdin); print("exchange_bank_balance", d.get("balance"))' fi fi echo "=== summary fails=$FAILS ===" exit "$FAILS"