Stripe Configuration
This guide covers setting up Stripe for subscription payments.
Create a Stripe Account
- Go to stripe.com and create an account
- Complete the account setup (you can skip this for test mode)
Get API Keys
- Go to Developers > API keys
- Copy to
.env.local:
# Use test keys for development
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
Important: Never expose the secret key to the client!
Create Products and Prices
Via Stripe Dashboard
-
Go to Products > Add Product
-
Create Free tier:
- Name: Free
- Description: Get started with basic features
- Price: $0/month (or skip pricing for free tier)
-
Create Pro tier:
- Name: Pro
- Description: Everything you need to grow
- Price 1: $29/month
- Price 2: $279/year (click "Add another price")
-
Create Enterprise tier:
- Name: Enterprise
- Description: For large-scale operations
- Price 1: $99/month
- Price 2: $950/year
-
Copy the Price IDs (start with
price_) to.env.local:
NEXT_PUBLIC_STRIPE_PRICE_ID_FREE=price_...
NEXT_PUBLIC_STRIPE_PRICE_ID_PRO_MONTHLY=price_...
NEXT_PUBLIC_STRIPE_PRICE_ID_PRO_YEARLY=price_...
NEXT_PUBLIC_STRIPE_PRICE_ID_ENTERPRISE_MONTHLY=price_...
NEXT_PUBLIC_STRIPE_PRICE_ID_ENTERPRISE_YEARLY=price_...
Via Stripe CLI
# Create products
stripe products create --name="Free" --description="Get started with basic features"
stripe products create --name="Pro" --description="Everything you need to grow"
stripe products create --name="Enterprise" --description="For large-scale operations"
# Create prices (replace prod_xxx with actual product IDs)
stripe prices create --product=prod_xxx --unit-amount=0 --currency=usd --recurring[interval]=month
stripe prices create --product=prod_xxx --unit-amount=2900 --currency=usd --recurring[interval]=month
stripe prices create --product=prod_xxx --unit-amount=27900 --currency=usd --recurring[interval]=year
stripe prices create --product=prod_xxx --unit-amount=9900 --currency=usd --recurring[interval]=month
stripe prices create --product=prod_xxx --unit-amount=95000 --currency=usd --recurring[interval]=year
Set Up Webhooks
Local Development
- Install Stripe CLI:
# macOS
brew install stripe/stripe-cli/stripe
# Windows
scoop install stripe
# npm
npm install -g stripe
- Log in:
stripe login
- Forward webhooks:
stripe listen --forward-to localhost:3000/api/stripe/webhooks
- Copy the webhook signing secret to
.env.local:
STRIPE_WEBHOOK_SECRET=whsec_...
Production
- Go to Developers > Webhooks
- Click Add endpoint
- Enter your endpoint URL:
https://yourdomain.com/api/stripe/webhooks - Select events to listen to:
checkout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.payment_failed
- Click Add endpoint
- Copy the signing secret to your production environment variables
Configure Customer Portal
- Go to Settings > Billing > Customer portal
- Enable the features you want:
- Update payment methods
- View invoices
- Cancel subscriptions
- Update subscriptions
- Configure the return URL:
https://yourdomain.com/dashboard/billing
Test Cards
Use these cards for testing:
| Card Number | Description |
|-------------|-------------|
| 4242 4242 4242 4242 | Successful payment |
| 4000 0000 0000 3220 | 3D Secure authentication required |
| 4000 0000 0000 9995 | Payment declined |
| 4000 0000 0000 0341 | Attaching card fails |
Use any future expiration date (e.g., 12/34) and any 3-digit CVC.
Webhook Events
Our webhook handler processes these events:
checkout.session.completed
- Triggered when a customer completes checkout
- Updates the user's Stripe customer ID
customer.subscription.created / updated
- Triggered when a subscription is created or changed
- Creates/updates the subscription record in the database
customer.subscription.deleted
- Triggered when a subscription is canceled
- Updates the subscription status to "canceled"
invoice.payment_succeeded
- Triggered when a payment succeeds
- Can trigger confirmation emails
invoice.payment_failed
- Triggered when a payment fails
- Updates subscription status to "past_due"
- Can trigger alert emails
Going Live Checklist
Before switching to live mode:
- [ ] Create products and prices in live mode
- [ ] Update API keys to live keys
- [ ] Set up production webhook endpoint
- [ ] Configure customer portal for production
- [ ] Test the complete flow with real card
- [ ] Verify webhook signatures are working
- [ ] Set up email notifications for failed payments
Troubleshooting
Webhook signature verification failed
- Make sure
STRIPE_WEBHOOK_SECRETis correct - For local development, ensure Stripe CLI is running
- Check that the raw request body is being passed (not parsed JSON)
Checkout redirects to wrong URL
- Check
NEXT_PUBLIC_APP_URLis set correctly - Verify success/cancel URLs in checkout session creation
Customer portal not showing subscriptions
- Ensure the customer has active subscriptions
- Check that subscriptions were created with the correct customer ID