App Router, React 19, server components, route handlers. The billing settings UI lives in /d/$workspaceSlug/workspace/settings/billing and is gated by workspace.billing.manage.
Wiring Stripe by hand is a week you don't get back. Orbit's paid tier ships Next.js 16 + Stripe with checkout sessions, customer portal, signature-verified webhooks, an append-only billing event ledger, and the multi-tenant primitives — workspaces, PBAC, audit logs — that make subscriptions actually map to your product. Next.js and Stripe both live in the paid tier; the free public starter is TanStack Start + better-auth without billing.
App Router, React 19, server components, route handlers. The billing settings UI lives in /d/$workspaceSlug/workspace/settings/billing and is gated by workspace.billing.manage.
Checkout sessions for upgrades, customer portal for plan changes and invoices, webhook receiver that verifies the signature and translates events into domain updates inside a Unit of Work.
Every billing event Stripe sends is persisted to a billing_events table. Idempotent, replayable, auditable. If a webhook fires twice, your subscriptions don't double-flip.
A subscription belongs to a workspace, not a user. Ownership transfer keeps the customer ID with the workspace. The customer portal link is scoped to the right Stripe customer with no impersonation gymnastics.
Stripe is one adapter behind a BillingProvider port. Polar and Dodo are the others. Pick at scaffold; switch later by replacing one file. Product code never imports the Stripe SDK.
Built-in smee.io webhook tunnel forwards Stripe events to localhost:4002 in dev. No ngrok dance, no stripe listen process to babysit.