STRIPE STARTER · PRODUCTION CHECKLIST
Production checklist
The list we run before launching anyone else's app with this template. Skip a step at your own risk — most of them are silent failures.
Stripe configuration
- Live keys in env: STRIPE_SECRET_KEY=sk_live_..., NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
- Production webhook endpoint created in Stripe dashboard (live mode), pointed at your-domain/api/webhooks/stripe, listening to the events your mode needs.
- STRIPE_WEBHOOK_SECRET set from the prod endpoint (NOT the CLI secret).
- Customer Portal configured in dashboard (Settings → Billing → Customer portal) — cancel policy, plan switches, allowed actions.
- Every Product + Price re-created in live mode. Price IDs in src/config/pricing.ts updated.
- Every price_REPLACE_* placeholder is gone.
Env & app config
- NEXT_PUBLIC_APP_URL set to your real domain (https://).
- payments.config.ts mode matches your business model — one-time vs subscription vs hybrid.
- customerPortal.enabled is consistent with what you've set up in Stripe.
- UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN set (rate limiting is meaningful in prod).
Webhook handlers
- Every TODO in src/lib/stripe-events/* is implemented or deliberately left as no-op.
- Idempotency: handlers check event.id (or a deterministic key) before writing.
- DB writes are inside transactions where they need to be.
- Errors throw — so Stripe retries — instead of being swallowed.
Smoke test
- Real purchase with a real card, $0.50 or smallest viable price. Refund yourself after.
- Confirm the webhook fired (Stripe dashboard → event log).
- Confirm your fulfillment ran (DB row, email sent, access granted).
- Click "Manage Subscription" — portal opens, you can change plan, change card, cancel.
- Confirm canceling fires subscription.updated, end-of-period fires subscription.deleted.
Never enable Stripe production until you've done one real test
"It worked in test mode" has lied to every team at least once. Live keys, real card, $0.50 purchase, refund. The 90 seconds it takes are the cheapest insurance you'll buy this quarter.
Wire alerting before launch
Stripe's dashboard has email alerts for failed payments and webhook errors (Developers → Webhooks → endpoint → "Email me on failure"). Turn them on. They're the fastest signal that something's broken in prod.