Stripe Setup — Payment Integration
Add Stripe payments to a Next.js + Supabase project.
Interview (minimal)
- Billing model: Subscription / One-time / Both
- Number of plans: How many (e.g., Free / Pro / Enterprise)
- Pricing: Amount for each plan
- Currency: JPY / USD / etc.
What Gets Built
1. Environment Variables
# .env.local
STRIPE_SECRET_KEY=sk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Production keys go in Vercel env vars (never in code)
2. Stripe Library Setup
src/lib/stripe.ts # Server-side Stripe client
src/lib/stripe-client.ts # Client-side (loadStripe)
3. API Routes
src/app/api/stripe/
├── checkout/route.ts # Create Checkout Session
├── webhook/route.ts # Webhook handler
├── portal/route.ts # Customer Portal session
└── prices/route.ts # List prices (optional)
4. Webhook Handler
Events to handle:
checkout.session.completed-> Save subscription info to DBcustomer.subscription.updated-> Reflect plan changescustomer.subscription.deleted-> Handle cancellationinvoice.payment_failed-> Notify payment failure
5. Supabase Integration
-- subscriptions table
create table subscriptions (
id uuid primary key default gen_random_uuid(),
user_id uuid references auth.users(id),
stripe_customer_id text,
stripe_subscription_id text,
plan text,
status text,
current_period_end timestamptz,
created_at timestamptz default now()
);
-- RLS
alter table subscriptions enable row level security;
create policy "Users can view own subscription"
on subscriptions for select using (auth.uid() = user_id);
6. UI Components
- Pricing table (PricingTable)
- Subscription status display
- Upgrade CTA
Checklist
- Test keys and production keys are separated
- Webhook signature verification is implemented (
stripe.webhooks.constructEvent) - Webhook endpoint is registered in Stripe Dashboard
- DB is updated on successful payment
- Payment failure is handled
- Customer Portal works
- Raw body parsing is correct (for Next.js App Router)