Payments
Payments use one active billing provider, local catalog configuration, checkout services, portal access, webhook projection, and provider-specific troubleshooting.
On this page
Billing module
Provider selection, catalog, checkout, webhooks, and billing rules.
Customer billing
Customer history, portal access, ledgers, exports, refunds, and disputes.
Production safety
Webhook idempotency, duplicate delivery, request ids, and cron safety.
Troubleshooting
Provider setup, webhook secrets, customer projection, and empty history checks.
Provider model
| Area | How the app handles it |
|---|---|
| Stripe | Supports checkout, portal, subscriptions, one-time purchases, usage, base-plus-usage, credits, invoices, refunds, disputes, and exports. |
| Lemon Squeezy | Supports checkout, subscriptions, one-time purchases, usage-oriented catalog setup, portal-style customer flows, and provider webhooks. |
| One-time purchases | Use licensed_one_time catalog entries and provider price ids. |
| Customer portal | Use the active provider and current signed-in billing customer record. |
| Webhooks | Verify signature, claim event row, dispatch by event type, project local billing state, and mark event status. |
Recipe: switch payment provider
Move between Stripe and Lemon Squeezy without leaving catalog, setup, checkout, and webhook behavior inconsistent.
Inspect
- src/features/billing/server/runtime/provider.ts
- src/features/billing/server/catalog/configuration.ts
- src/features/billing/server/runtime/readiness.ts
- src/features/billing/server/providers/stripe/checkout.ts
- src/features/billing/server/providers/lemonsqueezy/checkout.ts
Edit
- BILLING_PROVIDER
- BILLING_CATALOG_JSON
- BILLING_ENABLED_MODELS
- src/features/billing/server/catalog/configuration.ts
Steps
- Select the active provider and decide whether settings may override env.
- Replace catalog product and price ids with provider-compatible values.
- Configure the matching webhook endpoint and secret.
- Open /billing/setup and resolve every readiness failure.
- Run a provider test checkout and confirm local billing projection updates.
Verify
- pnpm run test:features
- pnpm run quality
- Open /billing/setup and run provider test mode.
Common mistakes
- Do not keep Stripe-only credit products enabled for Lemon Squeezy.
- Do not reuse webhook secrets from a different endpoint.
- Do not assume provider events arrive in order.