Recipe — Stripe in test mode
Get end-to-end Stripe checkout working in test mode before going live.
A full Stripe test loop in cartwright is: Stripe test keys configured → webhook listening → a 4242 card placed through the storefront → the order appearing in /admin/ordrer with the test charge linked. About 15 minutes if you have a Stripe account already.
Steps
-
Get test keys from Stripe. Stripe dashboard → Developers → API keys → Reveal test keys. Copy:
sk_test_...(secret key)pk_test_...(publishable key)
-
Configure in
/admin/integrations(recommended path — DB-stored, encrypted).Visit
http://localhost:3000/admin/integrations. Paste both keys. Save. The secret key is encrypted AES-256-GCM at rest; the publishable key is plaintext but is a public value anyway.Prefer this over env vars. DB-first means switching between test and live is a few clicks, not an env update + redeploy. And you don't accidentally commit a
.envwith live keys.Alternative — env vars for headless setups:
STRIPE_SECRET_KEY="sk_test_..." STRIPE_PUBLISHABLE_KEY="pk_test_..." -
Forward webhooks to your local dev server. Install the Stripe CLI if you have not yet (
brew install stripe/stripe-cli/stripe). Then:stripe login stripe listen --forward-to localhost:3000/api/webhook/stripeThe CLI prints a
whsec_...value. Copy it. This is your local webhook signing secret. -
Wire the webhook secret. Back in
/admin/integrations, pastewhsec_...as the Stripe webhook secret. (Or setSTRIPE_WEBHOOK_SECRETenv var.) Keep thestripe listenprocess running while you test. -
Place a test order. In the storefront:
- Add a product to the cart.
- Go to
/checkout. - Use test card
4242 4242 4242 4242, any future expiry, any CVC, any postal code. - Complete.
-
Verify the loop end-to-end.
- Storefront shows the success page with an order ID.
- The
stripe listenterminal showspayment_intent.succeededforwarded with a 200 response from/api/webhook/stripe. /admin/ordrershows the new order linked to the Stripe Payment Intent.- If
RESEND_API_KEYis set: a receipt email arrives. If not: check.mail-previews/for the HTML preview file.
Edge cases worth testing
Card: 4000 0025 0000 3155Stripe forces a 3-D Secure authentication challenge. Verify your redirect flow handles /checkout/return correctly.
Card: 4000 0000 0000 0002Card declines. Storefront should show an error and keep the customer on the checkout page with the cart preserved.
Stop the stripe listen process mid-test. Place an order. The Payment Element succeeds, but the webhook never reaches you. The order will sit in pending. The reconcile-stripe cron — or a manual call to it — should sweep it up.
Production switch
To flip to live mode:
- In Stripe dashboard, get live keys (
sk_live_...,pk_live_...). - Set up a real webhook endpoint in the Stripe dashboard pointing at
https://your-shop.com/api/webhook/stripe. Grab its signing secret. - Update
/admin/integrationswith the three live values (secret, publishable, webhook secret). - Place a real order with a real card. Refund yourself.
Never put live keys in .env files committed to git. Use Vercel project env vars (Production scope) or /admin/integrations DB storage.