# Stripe Setup

> Stripe payment integration setup. Checkout Session, Webhook, Subscription management, Customer Portal, and env var separation — all at once. Use when adding Stripe payments to a Next.js + Supabase project.

- Skill: `koach08/stripe-setup` (Agent Skill)
- Install (CLI): `npx skillmds@latest add koach08/stripe-setup`
- Raw SKILL.md: https://api.skillmd.com/api/skills/koach08/stripe-setup/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: koach08 (https://skillmd.com/u/koach08)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/koach08/stripe-setup

---


# 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
# .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 DB
- `customer.subscription.updated` -> Reflect plan changes
- `customer.subscription.deleted` -> Handle cancellation
- `invoice.payment_failed` -> Notify payment failure

### 5. Supabase Integration

```sql
-- 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)

