Ship/Now

Ship it · 2 min

Deploy

Push to Vercel, keep staging and production genuinely separate, and know which of the two a webhook just hit.

First deploy

Push to a repository

Vercel imports from GitHub, GitLab or Bitbucket. It detects Next.js; there is nothing to configure about the build.

Add the environment variables

Every value from .env, plus NEXT_PUBLIC_SITE_URL set to the real domain. See Environment variables for the trap in how you mark them.

Deploy, then point Stripe at it

The webhook endpoint is https://yourdomain.com/api/webhooks/stripe. Copy the signing secret it gives you into STRIPE_WEBHOOK_SECRET and redeploy, because a webhook secret that is not present at boot is a webhook that returns 503.

Two environments

The split that works with the least ceremony:

BranchVercel targetKeysDomain
mainProductionStripe live, live Supabaseyourdomain.com
developPreviewStripe teststaging.yourdomain.com

Vercel scopes environment variables per target, so the same variable name holds the test key on preview and the live key on production. Nothing in the code branches on the environment, which is the point: the code cannot get it wrong.

Proving they are separate

Do not assume. Take a signed webhook payload from live and post it at staging. It must return 400, because staging is verifying against a different signing secret. If it returns 200, the two environments share a secret and a live sale is being fulfilled by your staging deployment.

curl -i https://staging.yourdomain.com/api/webhooks/stripe \
  -H "stripe-signature: t=...,v1=..." \
  -d @live-payload.json
# expect 400

Somewhere other than Vercel

Nothing here is Vercel-specific except the OG image runtime and per-target environment variables. npm run build && npm run start runs anywhere with Node 20. On Fly or Railway you supply the environment separation yourself, usually as two apps.

Cost at zero users

Vercel Hobby, Supabase free, Resend free, Stripe pay-per-sale. Nothing is billed until somebody buys, and the first thing that will exceed a free tier is Resend's monthly send limit, long after that stops being a problem.

Something wrong or missing on this page? Tell us.