How billing works
Stripe objects, webhook flow, trials, invoices, and proration expectations.
Checkout & provisioning
Typical Stripe Checkout session:
User clicks upgrade → Stripe Checkout completes → Stripe sends `checkout.session.completed`
→ Our webhook persists `customers`, `subscriptions`, and `stripe_price_id`
→ Postgres `billing_plans` row maps price → entitlement snapshot
→ API keys inherit new limits immediately after cache TTL (seconds–minutes).Always prefer listening to webhooks over polling Stripe from the Worker — Stripe is authoritative for money movement; Postgres is authoritative for LogoRouter entitlement evaluation.
Subscriptions lifecycle
Stripe models subscription items, trial windows, current_period_start / current_period_end, cancel_at_period_end, and more. LogoRouter reacts to:
- Created / updated subscriptions — plan upserts, feature unlocking.
invoice.payment_succeeded— marks periods paid, restores access if suspended.invoice.payment_failed— starts dunning-aware behaviour (see Payment failures).
If you delete a customer from Stripe or via our dashboard, entitlement cleanup runs promptly — pending invoices stop once Stripe marks the subscription terminal.
Trials
Trials defer the first invoice. If the first paid charge fails, Stripe schedules retries LogoRouter observes through invoice webhooks — access follows the grace policy in Payment failures.
Invoices & receipts
Customers receive Stripe-hosted invoices PDFs/emails depending on Stripe Customer Portal configuration. LogoRouter dashboards link out to Stripe-managed billing artefacts when available — we do not store full PDF binaries.
Proration & plan bumps
Stripe prorates upgrades mid-cycle unless you customise checkout behaviour. Neon records the effective plan id — usage meters keyed by billing period reset on Stripe’s anchored billing date.