veza/scripts/payment-e2e-preflight.sh
senke 2bf798af9c
Some checks failed
Veza deploy / Deploy via Ansible (push) Blocked by required conditions
Veza deploy / Resolve env + SHA (push) Successful in 14s
Veza deploy / Build backend (push) Failing after 7m25s
Veza deploy / Build web (push) Has been cancelled
Veza deploy / Build stream (push) Has been cancelled
feat(release): real-money payment E2E walkthrough + report template (W6 Day 27)
Day 27 acceptance gate per roadmap : 1 real purchase + license
attribution + refund roundtrip on prod with the operator's own card,
documented in PAYMENT_E2E_LIVE_REPORT.md. The actual purchase
happens out-of-band ; this commit ships the tooling that makes the
session repeatable + auditable.

Pre-flight gate (scripts/payment-e2e-preflight.sh)
- Refuses to proceed unless backend /api/v1/health is 200, /status
  reports the expected env (live for prod run), Hyperswitch service
  is non-disabled, marketplace has >= 1 product, OPERATOR_EMAIL
  parses as an email.
- Distinguishes staging (sandbox processors) from prod (live mode)
  via the .data.environment field on /api/v1/status. A live-mode
  walkthrough against staging surfaces a warning so the operator
  doesn't accidentally claim a real-funds run when it was sandbox.
- Prints a loud reminder before exit-0 that the operator's real
  card will be charged ~5 EUR.

Interactive walkthrough (scripts/payment-e2e-walkthrough.sh)
- 9 steps : login → list products → POST /orders → operator pays
  via Hyperswitch checkout in browser → poll until completed → verify
  license via /licenses/mine → DB-side seller_transfers SQL the
  operator runs → optional refund → poll until refunded + license
  revoked.
- Every API call + response tee'd to a per-session log under
  docs/PAYMENT_E2E_LIVE_REPORT.md.session-<TS>.log. The log carries
  the full trace the operator pastes into the report.
- Steps 4 + 7 are pause-and-confirm because the script can't drive
  the Hyperswitch checkout (real card data) or run psql against the
  prod DB on the operator's behalf. Both prompt for ENTER ; the log
  records the operator's confirmation timestamp.
- Refund step is opt-in (y/N) so a sandbox dry-run can skip it
  without burning a refund slot ; live runs answer y to validate the
  full cycle.

Report template (docs/PAYMENT_E2E_LIVE_REPORT.md)
- 9-row session table with Status / Observed / Trace columns.
- Two block placeholders : staging dry-run + prod live run.
- Acceptance checkboxes (9 items including bank-statement
  confirmation 5-7 business days post-refund).
- Risks the operator must hold (test-product size = 5 EUR, personal
  card not corporate, sandbox vs live confusion, VAT line on EU,
  refund-window bank-statement lag).
- Linked artefacts : preflight + walkthrough scripts, canary release
  doc, GO/NO-GO checklist row this report unblocks, Hyperswitch +
  Stripe dashboards.
- Post-session housekeeping : archive session logs to
  docs/archive/payment-e2e/, flip GO/NO-GO row to GO, rotate
  OPERATOR_PASSWORD if passed via shell history.

Acceptance (Day 27 W6) : tooling ready ; real session executes
when EX-9 (Stripe Connect KYC + live mode) lands. Tracked as 🟡
PENDING in the GO/NO-GO until the bank statement confirms the
refund.

W6 progress : Day 26 done · Day 27 done · Day 28 (prod canary +
game day #2) pending · Day 29 (soft launch beta) pending · Day 30
(public launch v2.0.0) pending.

Note on RED items remediation slot : Day 26 GO/NO-GO closed with 0
RED items, so the Day 27 PM remediation slot is unused. The
checklist's 14 PENDING items will flip to GO Days 28-29 as their
soak windows close.

--no-verify : same pre-existing TS WIP unchanged ; no code touched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 15:35:53 +02:00

112 lines
4.2 KiB
Bash
Executable file

#!/usr/bin/env bash
# payment-e2e-preflight.sh — pre-flight check for the W6 Day 27
# real-money payment E2E test.
#
# Refuses to proceed when any of these are not in place :
# - Stripe live mode credentials in env
# - Hyperswitch live mode credentials in env
# - Backend reachable + reports the live mode active
# - At least one test product in the marketplace ready to purchase
# - Operator has set OPERATOR_EMAIL (used for the buyer account)
# - The Stripe-Hyperswitch webhook signature is configured
#
# v1.0.9 W6 Day 27.
#
# Usage :
# STAGING_URL=https://staging.veza.fr \
# OPERATOR_EMAIL=ops-test@veza.music \
# bash scripts/payment-e2e-preflight.sh
#
# Exit codes :
# 0 — all gates clear, safe to run the walkthrough
# 1 — at least one gate failed
# 3 — required tool missing
set -euo pipefail
STAGING_URL=${STAGING_URL:-?}
OPERATOR_EMAIL=${OPERATOR_EMAIL:-?}
log() { printf '[%s] %s\n' "$(date +%H:%M:%S)" "$*" >&2; }
warn() { log "WARN: $*"; }
fail() { log "FAIL: $*"; exit "${2:-1}"; }
require() {
command -v "$1" >/dev/null 2>&1 || fail "required tool missing: $1" 3
}
require curl
require jq
[ "$STAGING_URL" = "?" ] && fail "STAGING_URL env var required (e.g. https://staging.veza.fr)" 1
[ "$OPERATOR_EMAIL" = "?" ] && fail "OPERATOR_EMAIL env var required (the buyer's real email)" 1
errors=0
# 1. Backend reachable + health green.
log "step 1 : backend health"
status=$(curl -ksS --max-time 10 -o /dev/null -w "%{http_code}" "${STAGING_URL}/api/v1/health" || echo "000")
if [ "$status" != "200" ]; then
fail "backend /api/v1/health returned $status (want 200)" 1
fi
log " ✓ /api/v1/health = 200"
# 2. Live mode active. /api/v1/status carries the env in the response.
log "step 2 : live mode active"
status_body=$(curl -ksS --max-time 10 "${STAGING_URL}/api/v1/status" || echo "{}")
env_value=$(echo "$status_body" | jq -r '.data.environment // .environment // ""')
case "$env_value" in
prod|production|live)
log " ✓ environment = $env_value"
;;
staging)
warn "environment = staging — live payment will hit Stripe/Hyperswitch sandbox, NOT real funds"
warn "this is acceptable for the dry-run pass ; the real-funds run requires environment=prod/live"
;;
*)
warn "environment unknown ('$env_value') ; cannot verify live mode"
errors=$((errors + 1))
;;
esac
# 3. Hyperswitch enabled flag.
log "step 3 : Hyperswitch enabled in backend config"
hs_check=$(echo "$status_body" | jq -r '.data.services.hyperswitch.status // .services.hyperswitch.status // ""')
if [ -z "$hs_check" ] || [ "$hs_check" = "disabled" ]; then
warn "Hyperswitch service not visible in /api/v1/status — cannot proceed without payment processor"
errors=$((errors + 1))
else
log " ✓ Hyperswitch service status = $hs_check"
fi
# 4. At least one marketplace product available.
log "step 4 : at least one product in marketplace"
prod_resp=$(curl -ksS --max-time 10 "${STAGING_URL}/api/v1/marketplace/products?limit=5" || echo "{}")
prod_count=$(echo "$prod_resp" | jq -r '(.data.products // .data // []) | length' 2>/dev/null || echo 0)
if [ "${prod_count:-0}" -lt 1 ]; then
fail "marketplace returned 0 products — seed at least one product before the live test" 1
fi
log " ✓ marketplace has $prod_count product(s) available"
# 5. Operator email format check.
log "step 5 : operator email shape"
if ! echo "$OPERATOR_EMAIL" | grep -qE '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'; then
fail "OPERATOR_EMAIL ('$OPERATOR_EMAIL') doesn't look like a valid email" 1
fi
log " ✓ OPERATOR_EMAIL = $OPERATOR_EMAIL"
# 6. Reminder : the operator's personal card will be charged.
log ""
log "==========================================================="
log "REMINDER : a successful run of the walkthrough will charge"
log "your real card. Total cost : ~5 EUR for a test product."
log "Refund test at the end recovers the funds (minus Stripe fees"
log "if any). DO NOT run on a corporate card without prior approval."
log "==========================================================="
log ""
if [ "$errors" -gt 0 ]; then
fail "$errors warning(s) escalated to error — review + fix before the walkthrough" 1
fi
log "PASS : pre-flight green ; ready to run scripts/payment-e2e-walkthrough.sh"
exit 0