Skip to main content

Steps

1

Create Stripe Account

Get your Stripe account ready:
  1. Go to stripe.com and sign up
  2. Complete account setup
  3. Switch to Test Mode (toggle top-right)
Test mode lets you test payments without real money 💳
2

Get API Keys

Grab your credentials:
  1. Click Developers (top right)
  2. Click API keys
  3. You’ll see two keys:
    • Publishable key (starts with pk_test_)
    • Secret key (starts with sk_test_ - click “Reveal”)
Add to .env.local:
.env.local
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx
STRIPE_SECRET_KEY=sk_test_xxxxx
Never commit STRIPE_SECRET_KEY to git. Keep it in .env.local only.
3

Create Products

Set up your pricing plans in Stripe:
  1. Go to Product catalogAdd product
  2. Fill in:
    • Name: Basic Plan
    • Description: What customers get
    • Pricing: Choose “Recurring” for subscriptions, “One-off” for one-time payments
    • Price: $29 (or your price)
  3. Click Save product
  4. Copy the Price ID (starts with price_)
    • On the product page, under Pricing, click the menu next to the price and select Copy Price ID.
Repeat for each plan (Starter, Pro, etc.)
Price IDs connect your buttons to Stripe products. Don’t lose them!
4

Add Price IDs to Config

Open /config.ts:
/config.ts
export const config = {
    // ... other settings
    stripe: {
        ...
        mode: "subscription", // or "payment" for one-time
        plans: [
        {
            isFeatured: true,
            name: "Individual Plan",
            description: "",
            price: 19, // Display price
            priceId: 'price_xxxxx', // 👈 Your Price ID here    
            features: [
            { text: "Feature 1" },
            ...
            { text: "Lifetime updates", isAvailable: false },
            ],
        },
    },
}
Your pricing page will now show these plans automatically.
5

Set Up Webhooks

Webhooks tell your app when payments happen:
  1. In Stripe, search for Webhooks and select it
  2. Click Add Destination
  3. Click Select events and choose:
    • checkout.session.completed
    • checkout.session.expired
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.paid
    • invoice.payment_failed
  4. Click Continue
  5. Destination type > Webhook endpoint
  6. Endpoint URL: https://yourapp.com/api/stripe/webhook
  7. Copy the Signing secret (starts with whsec_)
Add to production environment variables (Vercel, etc.):
STRIPE_WEBHOOK_SECRET=whsec_xxxxx
Webhook logic lives in /app/api/stripe/webhook/route.ts. Customize it for your needs.
6

Test Local Webhooks

To test webhooks locally, install Stripe CLI:
Terminal
# Install Stripe CLI (macOS)
brew install stripe/stripe-cli/stripe

# Login
stripe login

# Forward webhooks to your local server
stripe listen --forward-to localhost:3000/api/stripe/webhook
Copy the webhook signing secret and add to .env.local:
.env.local
STRIPE_WEBHOOK_SECRET=whsec_xxxxx
Keep this terminal running while testing.
Trigger events:
Terminal
# In a separate terminal tab, trigger events e.g.
stripe trigger checkout.session.completed
7

Test a Payment

Time to see it work:
  1. Start dev server: npm run dev
  2. Start webhook forwarding (from Step 6)
  3. Go to http://localhost:3000/#pricing
  4. Click a “Get Started” button
  5. Use Stripe test card:
    • Card: 4242 4242 4242 4242
    • Expiry: Any future date (12/34)
    • CVC: Any 3 digits (123)
  6. Complete checkout
Success! Check:
  • Stripe dashboard for the payment
  • Supabase profiles table for has_access = true
8

Customer Portal

Users can manage subscriptions themselves:
  • Cancel subscription
  • Update payment method
  • View invoices
  • Download receipts
Already set up at /dashboard/account 🎉

Going Live

Ready to accept real payments?
1

Complete Verification

Stripe needs to verify your business:
  • Business details
  • Bank account
  • Identity verification
2

Switch to Live Mode

  1. Toggle to Live Mode in Stripe dashboard
  2. Get your live API keys (pk_live_ and sk_live_)
  3. Create live products (same as test)
  4. Copy live Price IDs
3

Update Production

In Vercel/your host:
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_xxxxx
STRIPE_SECRET_KEY=sk_live_xxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxx (from live webhook)
Update /config.ts with live Price IDs.
4

Create Live Webhook

Same as Step 5, but in live mode:
  • Endpoint: https://yourapp.com/api/stripe/webhook
  • Same events
  • Get new signing secret

Troubleshooting

Check these:
  • Webhook events in Stripe dashboard (any errors?)
  • .env.local has correct keys
  • Webhook secret is correct
  • Supabase connection works
  • Check logs - /app/api/stripe/webhook/route.ts
  • Check webhook URL is correct
  • Verify endpoint is reachable (try curl)
  • Look at webhook logs in Stripe dashboard
  • For local testing, ensure stripe listen is running
  • Check STRIPE_SECRET_KEY is set
  • User must have a customer_id in database
  • Try logging in again to refresh session