Feature: Billing
Last updated: 2026-06-01 (Pass-2 docs audit sweep)
Status: Lago is the active billing rail. The pre-#1016 Stripe + RequestFinance + plan-tier model documented in earlier revisions of this file is gone.
Canonical reference
The leveraged design that drove the cutover lives in
docs/superpowers/specs/2026-05-26-billing-provider-leveraged-design.md.
Read that for the full rationale (vendor comparison, dual-strategy pricing, schema, rollout plan).
What shipped
| PR | What it landed | Date |
|---|---|---|
| #1016 | Phase 7 — legacy fixed-plan billing removed (agent_starter / agent_pro / enterprise plan strings, Stripe + RequestFinance providers, six-file billing module) | 2026-05-28 |
| #1069 | LagoProvider adapter — self-hosted Lago (Railway for dev; AWS for staging + prod — see #1287) | 2026-05-29 |
| #1105 | Dual-strategy pricing: plan_per_rate default (free-tier Lago) + plan_overrides (premium-licensed) | 2026-05-30 |
| #1151 | LlmCostRollupService — pivots messages.cost_cents on osa_id into the per-OSA billing record (#1119 series, ADR-020) | 2026-05-30 |
| #1155 | /client/billing/* surface (summary + portal-url) | 2026-05-31 |
| #1155 | /ops/billing/* + /client/settings/billing surfaces (list, customer detail, retry-sync) + Lago webhook intake (PR #1165 was closed-unmerged and superseded by #1155) | 2026-05-31 |
| #1217 | Launch-checklist §10 renamed Orb Billing Live → Lago Billing Live; tracking issues redirected from #702 (Orb) to the Lago set | 2026-06-01 |
| #1275 | Client payment-method add via Stripe Checkout — GET /client/billing/checkout-url returns a one-shot Checkout session URL the OrgAdmin redirects to; on success the saved card is attached to the Lago customer (Stripe is Lago's PSP, not a parallel billing rail). Closes P0 #1268. Design: docs/superpowers/specs/2026-06-01-client-payment-flow-design.md. | 2026-06-01 |
| #1220 | prorationFactor honoured on termination invoices even when the Lago invoice period is null (mid-cycle terminations) — fixes under-billing on early cancels. | 2026-06-02 |
| #1475 | In-app notifications on payment failure — Lago payment_failed webhook now fans out to the notifications drawer for OrgAdmin + billing-role members of the affected org. | 2026-06-03 |
| #1433 / #1551 | Grace-period gating + ops-billing surfacing for payment failures — failed-payment orgs enter a configurable grace window during which client surfaces show a soft warning; after the window expires, write paths gate at the org-RLS layer. /ops/billing/* now surfaces grace-period state per org so AMs/SAs can intervene before the gate trips. | 2026-06-03 |
Orb is dead. Tracking issue #702 ("Orb integration") is superseded by the Lago PRs above. Do not file new work under #702.
Module layout
api/src/billing/
├── billing.module.ts
├── application/ # use-cases, command/query handlers
├── domain/ # entities, value objects, MonthlyRateConfig
├── infrastructure/ # adapters
│ └── providers/lago.provider.ts # active provider (#1069)
├── interface/ # HTTP controllers
│ ├ ── client-billing.controller.ts # /client/billing/*
│ ├── ops-billing.controller.ts # /ops/billing/*
│ └── billing-webhook.controller.ts # /billing/webhooks/lago
├── llm-cost-rollup.service.ts # #1151
└── llm-cost-rollup.service.spec.ts
The pre-#1016 flat layout (payment-provider.interface.ts, stripe.provider.ts, request-finance.provider.ts, billing.service.ts, billing.controller.ts) is gone. Don't reintroduce it.
API surface
See docs/api/reference.md#billing for the live table. Summary:
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | /client/billing/summary | OrgMember | Org subscription summary |
| GET | /client/billing/portal-url | OrgAdmin | One-shot Lago portal URL |
| GET | /client/billing/checkout-url | OrgAdmin | One-shot Stripe Checkout URL for adding/updating the saved payment method (#1275) |
| GET | /ops/billing | SA/AM | All orgs + sub state |
| POST | /ops/billing/sync-customer/:orgId | SA | Reconcile Lago customer |
| GET | /ops/billing/customer/:orgId | SA/AM | Lago customer detail |
| POST | /ops/billing/subscriptions/:assignmentId/retry-sync | SA | Retry stuck OSA sync |
| POST | /billing/webhooks/lago | Lago signature | Lago webhook intake |
The pre-#1016 endpoints (POST /billing/subscriptions, POST /billing/checkout-session, POST /billing/webhooks/stripe, POST /billing/webhooks/request-finance, etc.) are removed; see "Recently Removed" in reference.md.
Pricing strategy (#1105)
Two strategies, selected per Lago instance capability:
plan_per_rate(default, works on free-tier self-hosted Lago) — one Lago plan per (rate, currency, billing_period) tuple. Specialist rate changes create new plans; old plans are deactivated.plan_overrides(requires Lago premium license) — single plan template with per-subscription rate overrides, no plan proliferation.
Rate-config endpoints live on the Org/assignment surface (not on the billing module):
- Catalog default:
specialists.monthly_rate_config(jsonb) - Per-org override + effective window:
org_specialist_assignments.monthly_rate_config/rate_effective_from/rate_effective_until - AM-facing read:
GET /am/orgs/:orgId/specialist-assignments/:assignmentId/rate-history(#631) - Onboarding read:
GET /onboarding/:token/specialistreturns resolvedmonthlyRate: { amount, currency, source }
LLM cost rollup (#1151)
LlmCostRollupService reads messages.cost_cents (added to messages in the ADR-020 / #1119 / #1148 column series), pivots on osa_id, and posts the rollup to the relevant Lago subscription so the invoice reflects real per-Specialist LLM spend.
Configuration
# Lago (active)
LAGO_API_URL=https://lago.<your-railway-host>
LAGO_API_KEY=...
LAGO_WEBHOOK_SECRET=...
LAGO_PRICING_STRATEGY=plan_per_rate # or plan_overrides if licensed
Do not add STRIPE_*, ORB_*, or ENABLE_REQUEST_FINANCE to new env files. The code that reads them is gone.
Related
- ADR-020 (docs/decisions/020-isolation-classification.md) —
cost_cents/actor_role/osa_idcolumns onmessagesare the audit primitiveLlmCostRollupServiceconsumes - docs/superpowers/specs/2026-05-26-billing-provider-leveraged-design.md — canonical spec
- docs/mvp-launch-checklist.md §10 — launch gate (renamed Lago Billing Live in #1217)