# Payment & Billing Flow (Provider‑agnostic) --- **Phase:** Phase 0 (Planning) **Status:** Draft — finalize in Phase 1 **Owner:** Backend Architect **References:** - `/docs/project-overview.md` - `/docs/backend/architecture.md` - `/docs/backend/api-design.md` - `/docs/backend/security.md` --- Single source of truth for subscription billing with an external payment provider. No raw card data is handled by our app. ## 1) High-Level Flow 1. Frontend calls backend to create a Checkout/Portal Session (`POST /billing/session`) with tenant/context. 2. Backend creates/updates the Customer (if needed) and Session at the payment provider; returns `sessionUrl`. 3. User completes checkout on provider‑hosted page. 4. Payment provider sends webhooks (e.g., subscription created/updated/canceled). 5. Backend verifies signatures, updates subscription state in DB, and logs events (`BILLING_UPDATED`). 6. Frontend reads subscription status from backend (`/billing/status`) — webhook‑driven source of truth. ## 2) Required Endpoints - `POST /billing/session` — init checkout/plan change. Request: tenant ID inferred from auth; plan/tier; success/cancel URLs. Response: `sessionUrl`. - `GET /billing/status` — return subscription status, current plan, renewal/cancel info (cached from webhook‑driven DB state). - `POST /billing/webhooks/provider` — verify signature; idempotent upsert of subscription state; update tenant access. ## 3) Data Model Notes - Store provider customer ID, subscription ID, price/plan, status, current period dates, cancel_at/canceled_at, seats (if applicable). - All writes must be idempotent (webhook retries). Use provider event IDs for dedupe. - Permissions are enforced per tenant based on subscription status. ## 4) States & Mapping (common) - `trialing`, `active`, `past_due`, `canceled`, `incomplete/incomplete_expired`, `unpaid` → map to internal states that drive access. Deny critical actions when subscription is inactive. ## 5) Security & Compliance - Verify webhook signatures with provider secret; reject if invalid; log failures with trace IDs. - Do not log sensitive payloads; store only necessary billing identifiers. - Expose no card data; rely on provider‑hosted UIs (Checkout/Portal) for payment method management. ## 6) Frontend UX Notes - Use provider trust cues and clear statuses after redirect: success/pending/fail with recovery (retry checkout, contact support). - All status displays must read from backend (webhook‑driven), not query params.