All docs

Billing (Stripe)

Billing uses Stripe for subscriptions: Checkout, the Customer Portal, and webhooks that sync subscription state into the database. Plans and credit allowances are defined in .

1. Add your secret key

bash
STRIPE_SECRET_KEY="sk_test_..."NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_test_..."

Both are in your .

2. Create products & prices

Run the helper once — it creates a product and monthly price for each paid plan and prints the env lines to paste in:

bash
npm run stripe:setup
env
STRIPE_PRICE_ID_PRO="price_..."STRIPE_PRICE_ID_BUSINESS="price_..."

Prices are derived from priceMonthly in config/plans.ts.

3. Forward webhooks locally

Install the , then:

bash
stripe listen --forward-to localhost:3000/api/webhooks/stripe

Copy the printed signing secret into .env:

env
STRIPE_WEBHOOK_SECRET="whsec_..."

4. Test the flow

  1. Sign in and go to Billing.
  2. Upgrade to a paid plan — use Stripe's test card 4242 4242 4242 4242.
  3. The webhook syncs the subscription; your plan and credits update.
  4. Manage subscription opens the Stripe Customer Portal.

Production

Add a webhook endpoint in the Stripe dashboard pointing at https://your-domain.com/api/webhooks/stripe, subscribe to subscription and checkout events, and set the resulting STRIPE_WEBHOOK_SECRET. Use your live keys and re-run npm run stripe:setup on the live account.

How it fits together

  • config/plans.ts — plans, prices, credit allowances (source of truth)
  • features/billing/server/ — checkout, portal, subscription sync
  • app/api/webhooks/stripe/route.ts — signature-verified webhook handler