How to verify Stripe Checkout without a real credit card
Use Stripe test mode and PreFlight shadow verification to validate a real purchase path safely.
Guides
Verify Stripe Checkout without a real credit card
You do not need a customer card to prove your launch billing path works. PreFlight's Stripe Shadow Check runs a synthetic test-mode Checkout session, verifies webhook delivery, and confirms the Supabase side effect landed — end to end.
Shadow mode uses Stripe test keys only (sk_test_…). It creates a real hosted Checkout session, waits for payment completion, then polls your mapped Supabase table for the fulfillment row your webhook handler should write.
What success proves
| Stage | Probe | Proves |
|---|---|---|
| Session creation | stripe_shadow_checkout_start | Checkout session and hosted URL are valid |
| Payment | stripe_shadow_checkout_payment | Session reached paid in Stripe |
| Side effect | supabase_shadow_side_effect | Expected row exists in mapped table/column |
A passing shadow run validates the same path Revenue Ledger Watch reconciles in production.
Prerequisites
- Stripe connected with a test-mode secret key (sk_test_…)
- Supabase connected with service role access for verification
- A test Price ID saved as priceId on the Stripe integration
- verifyTableName and verifyTraceColumn mapping where your webhook writes fulfillment rows
- A publicly reachable webhook URL (or tunnel) that accepts signed Stripe events
Recommended workflow
Use Stripe test mode. Create a reusable test Price in Stripe Dashboard. Save the secret key, webhook signing secret, and webhook URL in PreFlight's Stripe integration.
Configure verification fields. Set
priceId,verifyTableName, andverifyTraceColumn. Optionally setverifyStatusColumn,verifyExpectedStatus,verifyCreatedAtColumn, andverifyWindowSecondsfor async handlers.Start the shadow run. From Checks or via API, call shadow/start. PreFlight returns a hosted
checkoutUrlandtraceId.Complete Checkout with test credentials. Open the hosted URL and pay with Stripe test card
4242 4242 4242 4242(any future expiry, any CVC). No real card is charged.Finalize the run. Call shadow/finalize (or use the dashboard action). PreFlight verifies payment status and polls Supabase until the side effect appears or the window expires.
Test mode only
Shadow checks reject live secret keys. Use test mode end to end, then repeat provider checks with production credentials before opening signups.
Dashboard flow
- Open Checks for the project.
- Ensure Stripe and Supabase integrations show connected.
- Start Stripe Shadow Check from the checks workspace or Stripe integration panel.
- Complete the hosted Checkout session in a browser tab.
- Finalize and review the three probe rows in the run timeline.
API flow (CI and preview deploys)
Shadow endpoints are documented separately from API v1 because they are Stripe-specific:
/api/projects/:projectId/shadow/startCreates a test-mode Checkout session. Optional body: previewUrl, source. Send Idempotency-Key from CI.
/api/projects/:projectId/shadow/finalizeVerifies payment and waits for the Supabase side effect. Body: runId, traceId, checkoutSessionId.
Example start response:
{
"runId": "uuid",
"status": "running",
"traceId": "pf_trace_…",
"checkoutSessionId": "cs_test_…",
"checkoutUrl": "https://checkout.stripe.com/…"
}
PreFlight embeds preflight_trace_id in Checkout session metadata and client_reference_id so your webhook handler can write the same trace to Supabase.
Mapping discovery
If the saved mapping misses during a shadow run, PreFlight attempts discovered trace-bearing tables from the connected Supabase OpenAPI schema before failing. Still, explicit mapping is recommended — discovery is a fallback, not a substitute for knowing your schema.
Common failures
| Symptom | Likely cause | Fix |
|---|---|---|
| Checkout never creates | Wrong key, invalid price, or blocked preview URL | Confirm sk_test_ key and priceId; set previewUrl to a reachable origin |
| Payment succeeds, DB fails | Webhook route or trace mapping wrong | Check handler logs for the traceId; align verifyTraceColumn |
| Verification window expires | Async side effect too slow | Increase verifyWindowSeconds or optimize webhook handler |
| Shadow start rate limited | More than 4 starts/minute per project | Use Idempotency-Key in CI to reuse existing runs |
Same path as Revenue Watch
The table and column you map for shadow verification should match Revenue Ledger Watch reconciliation. One correct mapping validates both launch rehearsal and ongoing drift detection.
