SecureStartKit

Payments

Stripe subscriptions, checkout, and Customer Portal.

Overview

Stripe handles all payment processing. The template uses Stripe SDK v21 with the 2026-03-25.dahlia API version. It includes subscription checkout, webhook handling, and Customer Portal integration.

Setup

  1. Create products and prices in your Stripe Dashboard
  2. Copy price IDs to config.ts
  3. Add your Stripe keys to .env.local
  4. Set up the webhook endpoint (see below)

Important: The template targets the Stripe dahlia API version (2026-03-25). Make sure your Stripe account's API version is compatible (check Dashboard > Developers > API version). Older API versions will cause webhook failures.

Checkout Flow

  1. User clicks a plan on the pricing page
  2. createCheckoutSession() Server Action is called
  3. A Stripe Customer is created (or retrieved) for the user
  4. User is redirected to Stripe Checkout
  5. On success, the webhook updates the subscriptions table

Webhook Setup

Local Development

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

Copy the webhook signing secret to STRIPE_WEBHOOK_SECRET in .env.local.

Production

Add a webhook endpoint in Stripe Dashboard pointing to:

https://yourdomain.com/api/webhooks/stripe

Events to listen for:

  • checkout.session.completed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • invoice.payment_succeeded
  • invoice.payment_failed

Common mistake: If you add the webhook endpoint but don't select these specific events, Stripe will log events but never deliver them to your app. Make sure all 6 events are checked.

Stripe API Version (dahlia)

The template uses Stripe API version 2026-03-25.dahlia. Key differences from older versions:

  • Subscription period fields are on subscription.items.data[0], not the top-level subscription object
  • Invoice subscription ID is at invoice.parent.subscription_details.subscription, not invoice.subscription

The webhook handler already accounts for these changes. If you customize the webhook, keep this in mind.

Customer Portal

Users can manage their subscription via the Stripe Customer Portal:

import { createPortalSession } from '@/actions/billing'

// In a Server Action or form:
await createPortalSession()
// Redirects to Stripe Customer Portal

Testing

Use Stripe test mode and the test card 4242 4242 4242 4242.

For a free test flow, create a 100% discount coupon in Stripe and apply it at checkout.