Stripe billing
Pro subscriptions update the workspace plan in Turso; webhooks must be verified and idempotent.
Checkout
POST /api/stripe/checkout (Clerk session) creates or reuses a Stripe Customer for the workspace, then a Checkout Session in subscription mode with STRIPE_PRICE_ID_PRO. Metadata includes workspaceId on the session and subscription payload.
Customer Portal
POST /api/stripe/portalreturns a billing portal URL for the workspace's stripe_customer_id.
Webhooks
Endpoint: POST /api/stripe/webhook. Raw body + Stripe-Signature verified with STRIPE_WEBHOOK_SECRET.
Each event id is inserted into stripe_events_processed; duplicates return early to ensure idempotency.
Handled events
checkout.session.completed— sets workspaceplantopro, stores customer and subscription ids when metadata is present.customer.subscription.updated— syncs status; active/trialing → pro, otherwise downgrades logic depends on status; updatescurrent_period_endfrom subscription items when expanded on the event object.customer.subscription.deleted— setsplantofreeand clears subscription fields.
Environment
See Environment variables for STRIPE_* keys.