Stripe Setup

Subscriptions per workspace: create Dashboard products/prices, paste IDs into env, then register the webhook endpoint this repo expects.

1. Create products and prices

In the Stripe Dashboard:

  1. Go to ProductsAdd product
  2. Create your plans (e.g., Starter, Pro, Enterprise)
  3. For each plan, add a recurring price (monthly and/or yearly)
  4. Copy the Price ID for each price (starts with price_)

2. Configure environment variables

STRIPE_SECRET_KEY=sk_live_...        # or sk_test_... for development
STRIPE_WEBHOOK_SECRET=whsec_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...

# Price IDs (comma-separated for multiple billing periods)
STRIPE_STARTER_PRICE_ID=price_starter_monthly,price_starter_yearly
STRIPE_PRO_PRICE_ID=price_pro_monthly,price_pro_yearly
STRIPE_ENTERPRISE_PRICE_ID=price_enterprise_monthly,price_enterprise_yearly

# Used in billing UI (public)
NEXT_PUBLIC_STRIPE_PRO_MONTHLY_PRICE_ID=price_pro_monthly
NEXT_PUBLIC_STRIPE_PRO_YEARLY_PRICE_ID=price_pro_yearly
NEXT_PUBLIC_STRIPE_ENTERPRISE_MONTHLY_PRICE_ID=price_enterprise_monthly
NEXT_PUBLIC_STRIPE_ENTERPRISE_YEARLY_PRICE_ID=price_enterprise_yearly

3. Set up the webhook

Local development

Use the Stripe CLI to forward webhooks:

stripe listen --forward-to localhost:3000/api/stripe/webhook

Copy the webhook signing secret from the CLI output to STRIPE_WEBHOOK_SECRET.

Production

In Stripe Dashboard → Developers → Webhooks:

  1. Add endpoint: https://your-app.com/api/stripe/webhook
  2. Select events:
    • checkout.session.completed
    • customer.subscription.updated
    • customer.subscription.deleted
  3. Copy the signing secret to STRIPE_WEBHOOK_SECRET

4. How billing works

  1. Workspace OWNER clicks UpgradecreateCheckoutSession() server action
  2. Stripe Checkout session created → user redirected to Stripe
  3. After payment → Stripe sends checkout.session.completed event
  4. Webhook handler at /api/stripe/webhook upserts subscriptions row
  5. User redirected back to /w/[workspaceId]/billing?success=1

The subscriptions table stores:

  • stripe_customer_id: for Customer Portal sessions
  • stripe_subscription_id: for webhook matching
  • plan: derived from the price ID (starter, pro, enterprise)
  • status: mirrors Stripe subscription status
  • current_period_end: for displaying renewal date

5. Test the flow

Use Stripe's test card: 4242 4242 4242 4242 with any future expiry and any CVC.