ADR: Stripe Owns Full Billing Stack Except Invoice Presentation
- Status: Accepted
- Date: 2026-04-23
- Decider: Jeffrey Lambert
- Project: Stripe Billing Transition
Context
Section titled “Context”The viability assessment asked, subsystem-by-subsystem, what moves to Stripe. Jeffrey is already on Stripe Billing + Invoicing + Checkout, and wants to centralize as much billing logic as possible in Stripe — subscriptions, tiered pricing, metering, discounts, calculations, retries, dunning — while keeping only the invoice PDF look-and-feel in-house (see ADR 2026-04-23-custom-invoice-pdf-retained.md).
Decision
Section titled “Decision”Stripe owns these subsystems as the system of record:
| Subsystem | Stripe product | Notes |
|---|---|---|
| Customer record | Customer | Adventive carries a thin customer mirror for joins against product data |
| Product / price catalog | Product, Price | Full migration of pricing to Stripe |
| Subscriptions | Stripe Billing subscriptions | Covers flat, tiered, and hybrid pricing |
| Usage-based / metered | Stripe Billing metered prices + usage records | Adventive reports meters, Stripe calculates |
| Discounts / coupons | Coupon, PromotionCode | |
| Invoice assembly | Invoice, InvoiceItem | Items attached as they accrue, not rolled up at month-end |
| Tax calculation | Stripe Tax (future) | Not enabled today — wired up when tax liability triggers |
| Failed-payment retries | Stripe Billing Smart Retries | Replaces any custom retry logic |
| Dunning emails | Stripe Billing dunning (decided 2026-04-23) | Stripe owns the full failed-payment lifecycle: retries, dunning sequence, and customer comms. No custom dunning via Mailgun. |
| Payment collection | Stripe + Hosted Invoice Page | Unchanged |
| Disputes | Stripe Radar + API | |
| Refunds / credits | Stripe Refunds + Credit Notes | |
| Accounting sync | Acodei → QuickBooks (unchanged) | Stripe events, captured by Acodei, pushed to QuickBooks |
Adventive owns:
| Subsystem | Rationale |
|---|---|
| Invoice PDF rendering | Brand fidelity non-negotiable (separate ADR) |
| Email delivery | Mailgun is a shared service — auth emails, onboarding, billing, etc. Kept |
| Metering signal source | Adventive products know what usage to meter; Stripe receives usage reports |
| Operator-side billing UI | Surfaced in the new admin (Stripe data, Adventive presentation) |
Retiring the monthly rollup
Section titled “Retiring the monthly rollup”The current pipeline accumulates billable events internally, then rolls up at month-end and creates a Stripe invoice. After this transition:
- Billable events are posted to Stripe as
InvoiceItems on the customer’s draft invoice as they happen (or via scheduled Worker flushes if batch-friendly). - Stripe’s billing cycle controls finalization.
- The custom rollup job is retired.
This simplifies reconciliation — Stripe becomes the source of truth for what was billed, and Acodei syncs that directly to QuickBooks.
Customer portal
Section titled “Customer portal”Stripe Customer Portal is in scope as an optional customer self-service surface (update card, see invoice history, download Adventive-branded PDFs). Final decision on enabling it is deferred — it’s additive to the migration and doesn’t gate cutover.
Consequences
Section titled “Consequences”Positive:
- One source of truth for billing (Stripe) — reconciliation becomes trivial.
- Stripe handles the things that are hard to get right (tax, retries, dunning, disputes, card updates).
- Acodei → QuickBooks pipeline simplifies because it becomes purely Stripe-driven.
- Retiring the rollup job + custom billing calculations removes significant admin-side complexity.
Negative / to-mitigate:
- Stripe pricing model must exactly mirror Adventive’s current pricing — mismatches would change customer charges.
- Metering signal reliability becomes important — dropped usage events = lost revenue.
- Stripe’s billing cycle may not match Adventive’s current month-end cadence for all customers → cutover plan needs per-customer cycle alignment.
- Roughly 200 customers, mix of pricing models, some non-standard arrangements → migration must handle outliers individually.
Follow-ups
Section titled “Follow-ups”- Inventory current pricing models (flat / tiered / usage / discount / custom contracts) → map each to a Stripe construct.
- Plan the non-standard-arrangement handling strategy (Stripe can handle most, but some manual-invoice customers may need a separate flow).
- Define the metering event contract — what Adventive product emits, what the Worker posts to Stripe.
- Confirm Acodei’s handling of the new Stripe event shape (invoice-item-per-event instead of month-end invoice-with-items).
Design the dunning decision— Resolved 2026-04-23: Stripe handles dunning end-to-end. Follow-up is content review of Stripe’s dunning email templates to confirm they meet Adventive’s tone bar.