ADR-036 — SaaS billing (in-app)

Architecture decision record — status: Accepted.

Source: docs/adr/ADR-036-saas-billing-deferred.md

ADR-036: SaaS billing (in-app)

Estado

Accepted — 2026-08-23
Amendment 2026-08-24: billing SaaS is in-product (plan catalog, checkout, entitlements). Filename kept for stable links.
Amendment 2026-09-08: el pagador es el Subscriber (DOC-002), no una Organization B2B. Entitlements = límites de producto (watchlist, corridas, …), no max_users de un tenant. Cobro al deudor Cashlane fuera de alcance.

Contexto

Pricing hipótesis (DOC-001): planes self-serve para traders retail. El piloto necesita un pago real en producto, no un Payment Link suelto.

Cashlane mezclaba billing SaaS de la org con cobro al deudor (invoice). IVPrior solo cobra la suscripción al Subscriber.

Decisión

Plan catalog (platform) → public pricing + signup picker → Stripe Checkout → Subscription + entitlements
  1. V1: catálogo Plan administrado en /platform/plans. Solo PUBLISHED + selfServe aparecen en /pricing y en el picker de /signup.
  2. Checkout hospedado Stripe (intervalo month/year según flags del plan). Portal de billing en settings del Subscriber.
  3. Entitlements se aplican en use cases del scanner / cuenta (límites de producto). Overrides por cuenta son de plataforma (staff).
  4. Planes de sistema (trial interno, Enterprise) no son self-serve.
  5. Cobro al deudor de una Invoice (Cashlane) no es este ADR y no se implementa.

Alternativas

OpciónNota
In-app catalog + Stripe CheckoutElegida — DOC-002 / este ADR
Solo Payment Link manualRechazada para factory; no escala ops
Billing diferido a V1.5Superado por este amendment

Consecuencias

  • Slice billing entrega Prisma Plan/Subscription, OpenAPI, UI platform + app del Subscriber, Help.
  • Secretos Stripe fuera de git (ADR-015). Local puede seedear catálogo sin cobrar.
  • UI/schema que aún diga “tenant” es leftover; el pagador es Subscriber.