Search

Search Kavel...

Documentation menu

Payments

Stripe subscriptions on the edge, checkout, a billing portal, and signature-verified webhooks.

Note

Payments requires the auth module, subscriptions are tied to a user. The CLI selects it for you automatically.

What you get

  • Typed oRPC procedures (createCheckoutSession, createPortalSession, and getSubscription) all behind requireAuth
  • A webhook at /api/stripe/webhook that verifies signatures and upserts each user's subscription row
  • A /billing page that starts checkout and links to the Stripe customer portal

Edge-native Stripe

There's no Node runtime on Workers, so the module uses Stripe's fetch-based HTTP client and the Web Crypto SubtleCrypto provider to verify webhook signatures asynchronously, no node_compat required.

ts
const event = await stripe.webhooks.constructEventAsync(
  payload,
  signature,
  env.STRIPE_WEBHOOK_SECRET,
  undefined,
  Stripe.createSubtleCryptoProvider(),
);

Setup

  1. Create a recurring price in Stripe and copy its id into STRIPE_PRICE_ID.
  2. Add STRIPE_SECRET_KEY (use a sk_test_… key while developing).
  3. Forward webhooks locally and copy the signing secret into STRIPE_WEBHOOK_SECRET.
bash
stripe listen --forward-to localhost:8787/api/stripe/webhook

Tip

Without a Stripe key the checkout endpoints stay dormant, so the rest of the app still builds and runs. See Deployment for the production webhook setup.