fix(payment): correlate PaymentIntent/Charge-referencing webhooks to the right transaction
Real Stripe TEST traffic (Phase 9.1) exposed a genuine defect the deterministic TestProvider never could: payment_intent.payment_failed and charge.refunded events reference Stripe's PaymentIntent/Charge object, never the Checkout Session, but payment_transactions. provider_reference only ever stored the Session id. A real failure or refund webhook would have silently failed to match any transaction (UNKNOWN_TRANSACTION). - payment-provider.js: session creation now also sets payment_intent_data.metadata (the same metadata already carrying our transaction_id), so it propagates onto the PaymentIntent Stripe creates. normalizeEvent() (now async) reads transaction_id back from the PaymentIntent's own metadata directly for payment_intent.payment_failed, and via one extra paymentIntents.retrieve call for charge.refunded (Charges don't inherit PaymentIntent metadata automatically). - commerce.js: the transaction lookup now matches provider_reference OR transaction_id — one additional OR clause, no schema/migration change. - webhook-routes.js: added the now-required await on verifyAndParseWebhook (TestProvider's synchronous return is unaffected). - docker-compose.dev.yml: wires PAYMENT_PROVIDER/STRIPE_SECRET_KEY/STRIPE_WEBHOOK_SECRET through to the api container (previously entirely absent — Phase 9 never needed it against the deterministic provider), empty/unset by default matching EMAIL_PROVIDER's own convention. Verified fixed against a real Stripe TEST refund (Phase 9.1); e2e-phase9.js 20/20 and the Winter Break commerce rehearsal 13/13 rerun clean after the fix.
This commit is contained in:
@@ -95,6 +95,14 @@ services:
|
||||
# e2e-phase5c.js sets this to "1" via .env for one test to prove production gating for
|
||||
# real, then unsets it again — see that test's own comment.
|
||||
COOKIE_SECURE: ${COOKIE_SECURE:-}
|
||||
# Phase 9.1 — real-Stripe-TEST-mode local validation. Empty/unset by default (fail-safe:
|
||||
# payment-provider.js defaults to the deterministic TestProvider when PAYMENT_PROVIDER is
|
||||
# unset — the same "dev by default, real provider opt-in" pattern EMAIL_PROVIDER already
|
||||
# uses above). Set all three in platform/.env only for a deliberate real-Stripe-TEST
|
||||
# session; STRIPE_SECRET_KEY must be a TEST key (sk_test_...) — never a live one.
|
||||
PAYMENT_PROVIDER: ${PAYMENT_PROVIDER:-}
|
||||
STRIPE_SECRET_KEY: ${STRIPE_SECRET_KEY:-}
|
||||
STRIPE_WEBHOOK_SECRET: ${STRIPE_WEBHOOK_SECRET:-}
|
||||
# TRUST_PROXY: "1" # set once fronted by a trusted reverse proxy
|
||||
depends_on:
|
||||
postgres:
|
||||
|
||||
Reference in New Issue
Block a user