STRIPE STARTER · DEPLOYING TO VERCEL
Deploying to Vercel
Push, connect, paste env vars, deploy. The production webhook secret has to come AFTER first deploy — circular setup we deal with every time.
Vercel (the path we test)
- Push to GitHub.
- Vercel → Import Project → pick the repo.
- Paste env vars: STRIPE_SECRET_KEY, NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, NEXT_PUBLIC_APP_URL, UPSTASH_* if using.
- Deploy. You'll get a Vercel preview URL — note it.
- Open Stripe Dashboard → Developers → Webhooks (live mode) → Add endpoint → paste your-deployment-url/api/webhooks/stripe.
- Stripe gives you a signing secret (whsec_xxx). Paste that as STRIPE_WEBHOOK_SECRET in Vercel and redeploy.
- Add your custom domain. Update NEXT_PUBLIC_APP_URL and the Stripe webhook URL to match. Redeploy.
Anywhere else
It's a standard Next.js 16 app. Render, Railway, Fly, your own VPS — all fine. Set the env vars, point the Stripe webhook at your-domain/api/webhooks/stripe, make sure the prod URL is HTTPS (Stripe rejects http:// webhook URLs in live mode).
Webhook URL must be HTTPS in live mode
Stripe enforces HTTPS for live webhooks. localhost is the only http:// exception (and only with the Stripe CLI). If your platform doesn't auto-provision TLS, fix that before launch.
Don't paste the test webhook secret into prod
The whsec_ from your dev CLI session is for localhost. The prod webhook gets its OWN whsec_ when you create the endpoint in the live-mode dashboard. They look identical. Label them in your password manager so you don't mix them up under pressure.
NEXT_PUBLIC_APP_URL has to be set in prod
The default fallback in getStripeRedirectUrl is http://localhost:3000. If you forget to set NEXT_PUBLIC_APP_URL in prod, your success_url / cancel_url will point at localhost, customers see a network error, and you'll get one of those panicked support tickets. Set it BEFORE first launch — and update it when you move to a custom domain.
Server Actions run on the Node runtime by default
Don't add `export const runtime = "edge"` to the webhook route or the Server Actions unless you know you need it. The Stripe SDK is Node-flavored — works on edge with caveats, but the marginal latency win isn't worth the debugging.