Phase 5 Xendit: Stages 1-7 (XENDIT_ENABLED=false; Stage 8 pending creds)
Backend - payment_sessions → payment_requests rename across DB schema + 29 files - payment.service.js becomes product-agnostic owner: EventEmitter + Xendit wrapper + requestPayment / confirmPayment public API; legacy aliases retained for existing chat callers - Webhook handler at POST /api/shared/payment/webhooks/xendit, with constant-time token verification (8 vitest cases) - Server-driven pairing: payment.service emits payment_request.confirmed → pairing subscriber starts the blast. Legacy POST /chat/request still works during the cutover. - Reconciliation sweeper extended (re-emits events for confirmed rows with no chat session) - SIGTERM drain + startup reconciliation pass in server.js Customer app - waiting_payment_screen opens xendit_invoice_url via LaunchMode.inAppBrowserView - searching / no-bestie / targeted-waiting / pairing-notifier updated to consume the new payment_request_id contract - pending_payments_provider + bestie-unavailable dialog migrated Dev / testing - XENDIT_ENABLED=false is the safe default; .env.example documents the four new vars - backend/.dev/xendit-fake-webhook.sh exercises the handler without ngrok - 90/92 backend tests pass (two pre-existing session-timer flakes, unrelated); client_app analyzer clean - requirement/phase5-xendit-plan.md is the canonical reference Stage 8 (live E2E) blocked on Xendit test-mode keys. The dashboard's single-webhook-URL constraint will be worked around via a self-poll script next session. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
35
backend/.dev/xendit-fake-webhook.sh
Executable file
35
backend/.dev/xendit-fake-webhook.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fire a fake Xendit Invoice callback at the local backend so you can exercise
|
||||
# the webhook handler without going through ngrok / a real Xendit invoice.
|
||||
#
|
||||
# Usage:
|
||||
# ./xendit-fake-webhook.sh <payment_request_id> [PAID|EXPIRED] [amount]
|
||||
#
|
||||
# Requires XENDIT_WEBHOOK_TOKEN in your environment. Pull from backend/.env:
|
||||
# source <(grep '^XENDIT_WEBHOOK_TOKEN=' ../backend/.env)
|
||||
#
|
||||
# NOT a Maestro replacement — Maestro keeps using /internal/_test/force-confirm-payment
|
||||
# (no token needed, faster). The fake webhook is for testing the handler itself:
|
||||
# signature verify, idempotency on retry, amount mismatch, etc.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PAYMENT_ID="${1:?usage: $0 <payment_request_id> [PAID|EXPIRED] [amount]}"
|
||||
STATUS="${2:-PAID}"
|
||||
AMOUNT="${3:-50000}"
|
||||
TOKEN="${XENDIT_WEBHOOK_TOKEN:?XENDIT_WEBHOOK_TOKEN env not set}"
|
||||
BASE_URL="${BASE_URL:-http://localhost:3000}"
|
||||
|
||||
INVOICE_ID="inv_fake_$(date +%s)_${RANDOM}"
|
||||
|
||||
curl -sS -X POST "${BASE_URL}/api/shared/payment/webhooks/xendit" \
|
||||
-H "x-callback-token: ${TOKEN}" \
|
||||
-H "content-type: application/json" \
|
||||
-d "{
|
||||
\"id\": \"${INVOICE_ID}\",
|
||||
\"external_id\": \"${PAYMENT_ID}\",
|
||||
\"status\": \"${STATUS}\",
|
||||
\"amount\": ${AMOUNT},
|
||||
\"payment_method\": \"BCA\"
|
||||
}" | jq . 2>/dev/null || cat
|
||||
echo
|
||||
Reference in New Issue
Block a user