Docs
Stripe Billing

Stripe Billing

Stripe checkout, portal, subscription, and webhook checks for Cascades-hosted commercial billing (internal reference).

This page documents optional commercial billing hooks for hosted Cascades offerings—it is not required to deploy or self-host the orchestration plane. For product deployment, prioritize Database & Storage, Identity Provider Configuration, and Environment Checklist.

Cascades preserves the template Stripe foundation. The product copy and pricing tiers are Cascades-specific, but checkout, portal, subscription state, and webhook processing remain powered by the existing Stripe integration.

Self-serve tier amounts (USD)

Amounts and Stripe catalog alignment are defined in config/plan-definition.ts (mirrored on /pricing via config/subscriptions.ts). Drift vs committed Stripe/Auth0 snapshots is enforced by npm run verify:entitlements-drift; refresh snapshots with npm run pull-billing-catalog when catalog or Auth0 RBAC changes.

TierMonthlyYearly (prepaid)
Starter$39$374
Pro$89$854
Business$219$2,099
EnterpriseContact sales

Yearly prices target roughly 20% off twelve monthly installments — typical SaaS annual leverage without underpricing the top self-serve tier (Business) relative to orchestration / verification-heavy competitors.

Align Stripe Products / Prices

With STRIPE_SECRET_KEY set (same .env* merge as npm run db:migrate):

  1. Preview: npm run stripe:catalog
  2. Create catalog rows: npm run stripe:catalog -- --apply
  3. Paste printed NEXT_PUBLIC_STRIPE_*_PLAN_ID lines into .env(.local) and restart Next.js.
  4. Verify with npm run validate-stripe-prices.

Products are tagged with metadata cascades_tier (starter | pro | business) so re-running --apply reuses matching Products and Prices instead of duplicating identical intervals.

Every recurring Price also carries metadata.cascades_tier and metadata.cascades_interval (month | year). Subscription webhooks expose these on line-item prices — Cascades persists stripe_tier_slug from price.metadata.cascades_tier so tier routing stays stable even if price_id rotates during repricing.

Runtime surfaces

  • /pricing renders plan cards and starts checkout for authenticated users.
  • /dashboard/billing shows subscription state and billing portal access.
  • actions/generate-user-stripe.ts creates checkout or billing portal sessions.
  • Checkout success returns to /pricing?checkout=complete; cancel to /pricing?checkout=canceled.
  • POST /api/billing/subscription-sync pulls Stripe subscription state when webhooks are slow (used by post-checkout client sync).
  • actions/open-customer-portal.ts opens the Stripe customer portal.
  • /api/webhooks/stripe validates signatures and updates subscription state.

See Stripe integration (CLI-first workflow) for stripe listen, stripe trigger, price ID wiring, and the bundled DAG template wf-stripe-subscription-provisioning.

Required validation

  1. Free user selects Pro or Business from /pricing and reaches Stripe Checkout.
  2. checkout.session.completed creates or updates the user's Stripe customer and subscription fields.
  3. invoice.payment_succeeded updates price and period-end fields for renewals or plan changes.
  4. Billing portal opens from /dashboard/billing for paid users.
  5. Cancellation or plan changes in Stripe are reflected by the next handled invoice/subscription event.
  6. Invalid webhook signatures return 400 and do not mutate the database.

Use Stripe CLI or dashboard test events for webhook verification. Do not disable signature validation for local convenience.

CommunityReport issue / Discuss(tags: Cascades, workflows)