Deploy to Production
Test mode was training wheels. Production mode processes real payments with real money. This lesson walks through switching from test keys to live keys, configuring production environment variables, and verifying the complete subscription flow works end-to-end.
Outcome
Deploy your storefront to production with live Stripe payments and verify the complete user journey.
Fast Track
- Get production keys from Stripe and Supabase dashboards
- Add production environment variables in Vercel
- Deploy and test with a real card (then refund)
Hands-on Exercise 4.3
Deploy to production:
Requirements:
- Create or switch to production Stripe keys
- Configure production Supabase project
- Add all environment variables in Vercel dashboard
- Deploy to production
- Test complete flow: sign up → subscribe → access premium → cancel
Implementation hints:
- Stripe live keys start with
sk_live_andpk_live_ - Create a separate Supabase project for production (recommended)
- Stripe webhooks need production URLs
- Test with a real card, then immediately refund
Environment variables needed:
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
SUPABASE_SERVICE_ROLE_KEY
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
STRIPE_SECRET_KEY
STRIPE_WEBHOOK_SECRET
Try It
-
Deploy to Vercel:
git push origin mainOr trigger deploy from Vercel dashboard.
-
Test sign up:
- Visit your production URL
- Create a new account
- Verify email confirmation works
-
Test subscription:
- Navigate to pricing page
- Select a plan and checkout
- Use a real card (you'll refund it)
- Verify redirect to subscription page
-
Test premium access:
- Visit premium features page
- Generate a cat photo
- Verify entitlement check passes
-
Test cancellation:
- Cancel subscription from subscription page
- Verify status changes to "cancelling"
-
Refund the charge:
- Go to Stripe dashboard → Payments
- Find your test payment
- Issue full refund
Commit
No code changes in this lesson—configuration only.
Done-When
- Production Stripe keys in Vercel
- Production Supabase credentials in Vercel
- Stripe webhook configured for production URL
- Deployed successfully to production
- Sign up flow works
- Subscription checkout works with real card
- Premium features accessible after subscription
- Cancellation flow works
- Test payment refunded
Solution
Step 1: Get Production Stripe Keys
- Go to Stripe Dashboard
- Toggle off "Test mode" in the sidebar (or click "Activate your account" if first time)
- Complete account verification if prompted
- Go to Developers → API keys
- Copy your live keys:
- Publishable key:
pk_live_... - Secret key:
sk_live_...
- Publishable key:
Step 2: Create Production Stripe Products
Your test mode products don't transfer to live mode. Create them again:
- In Stripe dashboard (live mode), go to Products
- Create the same products you had in test mode:
- Basic Plan: $9/month
- Pro Plan: $29/month
- Copy the new price IDs
Step 3: Configure Stripe Webhook
- Go to Developers → Webhooks
- Click Add endpoint
- Enter your production URL:
https://your-app.vercel.app/api/webhooks/stripe - Select events to listen for:
checkout.session.completedcustomer.subscription.updatedcustomer.subscription.deleted
- Click Add endpoint
- Copy the webhook signing secret:
whsec_...
Step 4: Set Up Production Supabase
Option A: Use same project (simpler, less isolated):
- Keep using your existing Supabase project
- Production and development share the same database
Option B: Create new project (recommended for real apps):
- Go to Supabase Dashboard
- Click New Project
- Name it
storefront-production - Choose a strong database password
- Select a region close to your users
- Wait for project to provision
- Go to Settings → API and copy:
- Project URL
anonpublic key
If using Option B, also configure auth:
- Go to Authentication → URL Configuration
- Set Site URL to your production domain
- Add redirect URLs for your production domain
Step 5: Add Environment Variables in Vercel
- Go to Vercel Dashboard
- Select your project
- Go to Settings → Environment Variables
- Add each variable for Production environment:
| Variable | Value | Environment |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | https://xxx.supabase.co | Production |
NEXT_PUBLIC_SUPABASE_ANON_KEY | eyJ... | Production |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | pk_live_... | Production |
STRIPE_SECRET_KEY | sk_live_... | Production |
STRIPE_WEBHOOK_SECRET | whsec_... | Production |
- Click Save for each variable
Step 6: Deploy
Trigger a new deployment to pick up the environment variables:
git commit --allow-empty -m "chore: trigger production deploy"
git push origin mainOr in Vercel dashboard: Deployments → Redeploy
Step 7: Verify Deployment
-
Check build logs:
- Go to Vercel dashboard → Deployments
- Click latest deployment
- Verify build succeeded
-
Check environment:
- In deployment details, verify environment variables loaded
- Check for any build warnings
-
Test the live site:
- Visit your production URL
- Verify pages load without errors
- Check browser console for issues
Step 8: End-to-End Test
Perform a complete user journey:
-
Sign up:
- Create new account with real email
- Confirm email if required
- Verify redirect to protected area
-
Subscribe:
- Navigate to pricing
- Click subscribe on a plan
- Complete checkout with real card:
- Card: Your actual card
- Or use Stripe test card if still in test mode
- Verify redirect to subscription page
- Verify subscription shows as active
-
Access premium:
- Navigate to premium features
- Generate a cat photo
- Verify it works
-
Cancel:
- Click cancel on subscription page
- Verify status changes
-
Refund (important!):
- Go to Stripe dashboard
- Find the payment
- Click Refund → Full refund
- Confirm refund
Production Checklist
Before announcing your launch:
Authentication
- [ ] Sign up works with email confirmation
- [ ] Sign in works
- [ ] Sign out works
- [ ] Password reset works (if implemented)
Billing
- [ ] Pricing page shows correct prices
- [ ] Checkout redirects to Stripe
- [ ] Webhook processes successfully
- [ ] Subscription shows after checkout
- [ ] Cancel/reactivate works
Access Control
- [ ] Premium features blocked without subscription
- [ ] Premium features accessible with subscription
- [ ] Entitlement checks work correctly
Error Handling
- [ ] Error pages display correctly
- [ ] Loading states appear
- [ ] API errors handled gracefully
Performance
- [ ] Pages load in <3 seconds
- [ ] No console errors
- [ ] Images optimized
Environment Variable Reference
| Variable | Where to Get | Used For |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Supabase → Settings → API | Auth, database |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Supabase → Settings → API | Client auth |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Stripe → Developers → API Keys | Client billing |
STRIPE_SECRET_KEY | Stripe → Developers → API Keys | Server billing |
STRIPE_WEBHOOK_SECRET | Stripe → Developers → Webhooks | Webhook verification |
Troubleshooting
Checkout fails in production:
- Verify Stripe live keys are set (not test keys)
- Check Stripe dashboard for error logs
- Verify products exist in live mode
Webhook not working:
- Verify webhook URL is correct in Stripe
- Check webhook secret matches environment variable
- Look at Stripe webhook logs for delivery status
- Test with Stripe CLI:
stripe listen --forward-to localhost:3000/api/webhooks/stripe
Auth not working:
- Verify Supabase URL and keys are correct
- Check Supabase auth settings for production URL
- Verify redirect URLs include production domain
- Check email templates are configured
"Invalid API key" errors:
- Environment variables may not have reloaded
- Redeploy to pick up new variables
- Verify no typos in variable names
- Check variables are set for Production environment (not just Preview)
Subscription shows but access control doesn't work:
- Check that price IDs in your code match live mode (not test mode)
- Verify
hasActiveSubscriptionchecks are using the correct Stripe subscription status - Check browser console for API errors when loading subscription data
What's Next
Congratulations! You've built and deployed a complete subscription storefront with:
- User authentication with Supabase
- Subscription billing with Stripe
- Subscription-based access control
- Production-ready error handling and loading states
- Complete navigation and UI
Potential enhancements:
- Add more subscription tiers
- Implement usage-based billing
- Add team/organization features
- Build admin dashboard
- Add analytics tracking
- Implement email notifications
You now have a solid foundation for any subscription-based SaaS product.
Was this helpful?