Stripe Billing Gap Matrix
Purpose
This document turns the current Stripe billing surface into a concrete gap matrix for invoices, subscriptions, customer billing identity, and collection flows.
Use it to answer:
- what the app already covers well
- what is only partially covered
- what still requires Stripe Dashboard or hosted Stripe flows
- what should stay Stripe-side on purpose
This is scoped to the agency-operated Stripe Connect billing layer, not starter SaaS billing.
Related docs:
- Agency Stripe Client Billing Model
- Agency Billing Workflows
- Stripe Connect Client Billing:
docs/dev/integrations/stripe-connect-client-billing.md
Status Key
Complete: supported in-app for normal operationsPartial: supported in-app for common cases, but important Stripe behavior is still missingMissing: not meaningfully supported in-app yetStripe-side: intentionally reasonable to leave in Stripe unless we choose to own that admin surface
Current Source Of Truth
Primary implementation files today:
packages/backend/convex/lib/stripeNode.tspackages/backend/convex/org/clientBillingNodeActions.tspackages/backend/convex/org/clientBillingWebhooks.tspackages/backend/convex/portal/workspace.tsapps/app/src/app/[locale]/org/(dashboard)/subscriptions/[subscriptionRecordId]/page.tsxapps/app/src/app/[locale]/portal/(dashboard)/billing/subscriptions/[subscriptionId]/billing-subscription-detail.client.tsxapps/app/src/app/[locale]/org/(dashboard)/invoices/**apps/app/src/app/[locale]/portal/(dashboard)/billing/**
Gap Matrix
| Area | Status | Current in-app support | Missing or limited vs Stripe | Main repo surfaces | Priority |
|---|---|---|---|---|---|
| Subscription create/update/cancel/reactivate | Complete | Create subscription, update plan/amount/interval/quantity, cancel now, cancel at period end, reactivate, preview invoice before change | Still modeled around a single primary subscription item | stripeNode.ts, clientBillingNodeActions.ts, org/portal subscription detail pages | Done |
| Subscription discounts / promo codes | Complete | Apply, clear, preview | No broader campaign-management UI for coupons/promotion codes themselves | same as above | Done |
| Trial management | Complete | Set trial end, end now, preview billing impact | No higher-order trial policy management | same as above | Done |
| Pause / resume subscription lifecycle | Partial | Pause collection, true pause, resume paused subscription, preview resume | Stripe has no equivalent invoice preview for every pause-collection toggle; those remain direct actions | same as above | Medium |
| Subscription schedules | Partial | Inspect schedule, set next phase, release schedule, preview scheduled change | Not a full phase composer: no multi-phase builder, future-start wizard, backdating flow, or broader schedule editing model | stripeNode.ts, clientBillingNodeActions.ts, portal/workspace.ts, subscription detail pages | High |
| Multi-item / multi-product subscriptions | Missing | None beyond a single primary item pattern | Stripe supports multiple subscription items, add-ons, mixed recurring lines, bundled pricing | subscription code currently assumes items.data[0] in stripeNode.ts and UI drafts only model one recurring line | High |
| Charge automatically subscriptions | Complete | Subscription create/update supports send_invoice and charge_automatically, including saved default payment methods and incomplete-payment state | Revenue-recovery policy remains Stripe-side | subscription actions, create dialogs, payment-method manager | Done |
| Payment methods fully in-app | Complete | SetupIntent-based add, remove, and default-payment-method management is available in-app | Card entry remains Stripe-hosted/Elements by design; recovery policy remains Stripe-side | customer snapshot and setup-intent flows, org client billing surfaces | Done |
| Usage-based / metered billing | Missing | None as an app-native operational surface | No meters, no usage event recording UX, no metered subscription item flows, no billing-credit workflow for usage products | no app surfaces or backend action family for Stripe meters/usage | Highest if pricing model needs usage |
| Invoice draft workflow | Complete | Create draft invoice, update draft, line items, finalize, send | Normal standalone invoice drafting is present | invoice actions in clientBillingNodeActions.ts, org invoice pages | Done |
| Invoice state handling | Complete | Draft/open/paid/void/uncollectible visibility and sync via webhooks | Normal state coverage exists | invoice record sync, invoice pages, portal billing invoice list/detail | Done |
| Invoice revision / advanced editing | Partial | Draft invoices are editable; standard lifecycle actions exist | No in-app support for revising finalized standalone open/uncollectible invoices; subscription-invoice revision is constrained by Stripe itself | invoice backend/actions and org invoice UI | Medium |
| Partial payments | Complete | Open invoices can collect an explicit partial amount from a saved payment method and attach it to the invoice | Complex installment schedules remain unsupported | invoice actions and invoice detail payment surfaces | Done |
| Invoice payment plans | Missing | None | No installment plan creation/update for invoices | no payment-plan backend/UI surface | High for enterprise invoicing |
| Credit notes / refunds | Complete | Credit note and refund operations exist | No broader finance workflow layer around them | invoice actions in backend, invoice detail surfaces | Done |
| Customer credit balance / invoice balance adjustments | Complete | Customer balance transactions are visible and authorized users can create debit/credit adjustments | Broader approval workflows remain out of scope | transaction actions and client billing surfaces | Done |
| Tax IDs | Partial | Customer tax IDs are stored in the client business profile and synchronized through Stripe's tax-ID API on create/update | Stripe remains the source of validation status; account-level registrations and liability configuration still require Stripe | client account billing fields, stripeNode.ts customer tax sync | High |
| Automatic tax / tax behavior | Partial | Quotes support automatic tax/default tax rates; catalog products and prices support tax codes/tax behavior | No workspace-wide tax-liability setup or complete invoice/subscription automatic-tax policy | catalog, quote, invoice, and subscription flows | High |
| Invoice rendering templates / invoice presentation controls | Partial | Templates are listed and some billing defaults exist in model | No full admin UI for assigning, editing strategy, grouping rules, branding/memo/footer policy management | template listing exists in backend; no full settings UI | Medium |
| Hosted invoice page / hosted payment page | Complete | Open hosted invoice URLs and PDFs from app | Stripe-hosted payment remains underlying payment surface by design | portal billing pages, invoice detail pages | Done |
| Public billing artifact sharing | Complete | Copy Stripe-hosted invoice, quote, and receipt links for a payer without granting portal access | Billing portal sessions, saved payment methods, collections, drafts, and subscription controls intentionally remain authenticated | org invoice/quote/transaction actions and portal billing | Done |
| Quotes | Complete | Create/update/finalize/cancel/accept/get/PDF flows exist in backend | Quote UI depth may still be thinner than subscription/invoice UI, but core API support is present | stripeNode.ts, clientBillingNodeActions.ts, org quote surfaces | Medium |
| Dunning / retries / reminder policy | Missing | App reflects billing outcomes | No in-app policy editor for Smart Retries, retry schedule, reminder cadence, collection automation | currently Stripe-config side, not app-managed | Medium |
| Billing portal deep links | Complete | Hosted Stripe entry points exist where useful | Still hosted by Stripe, but this is acceptable for payment collection and customer self-service edges | portal session helpers and billing pages | Done |
What Still Forces People Back To Stripe
If the goal is "agents and clients should almost never need Stripe," these are the biggest remaining reasons someone would still need it:
multi-item subscriptionsinvoice payment planstax liability and automatic-tax policyusage-based billing, if the product will need itadvanced dunning and reminder policy
Recommended Work Order
Wave 1: Remove the biggest operational escapes to Stripe
- In-app payment method management
-
charge_automaticallysubscription support - Partial payments on invoices
- Customer credit balance adjustments
- Customer tax-ID synchronization and billing identity
Wave 2: Close structural billing-model gaps
- Multi-item subscriptions
- Automatic tax, price tax behavior, and tax-code support
- Invoice payment plans
- Fuller subscription schedule composer
Wave 3: Expand to advanced billing models
- Usage-based billing
- Billing credits for usage products
- Richer invoice revision workflows
- Invoice rendering template administration
Wave 4: Optional Stripe-admin replacement work
- Dunning / retry policy editor
- Reminder automation editor
- Revenue recovery control surface
Recommended Completion Standard
Do not mark a row complete just because the backend API exists.
Mark a row Complete only when all of the following are true:
- org users can perform the normal workflow in-app
- portal/client users can perform their allowed workflow in-app or through an app-launched hosted Stripe payment surface where that is the intended model
- public payers can use a resource-scoped hosted invoice link without receiving access to the customer's broader portal or billing account
- webhook sync keeps the mirrored records trustworthy
- important billing-impacting actions have preview or review steps where Stripe supports them
- there is no routine operational reason to open the Stripe Dashboard for that workflow
What Is Reasonable To Leave Stripe-Side
These are valid candidates to leave in Stripe unless we intentionally want to own finance-admin tooling:
| Area | Recommendation | Why |
|---|---|---|
| Smart Retries strategy | Stripe-side | Finance-policy configuration, not core day-to-day product workflow |
| Reminder cadence | Stripe-side | Similar to retries; useful but not essential to product-native billing ops |
| Invoice branding/template editing | Stripe-side or Partial | Needed by some teams, but not required to eliminate most Stripe Dashboard usage |
| Obscure subscription schedule edge cases | Stripe-side until needed | Low-frequency, high-complexity |
| Private-preview Stripe billing features | Stripe-side | Product should not depend on unstable/private-preview admin features unless explicitly chosen |
Stripe References
- Subscription schedules: https://docs.stripe.com/billing/subscriptions/subscription-schedules
- Pause payment collection: https://docs.stripe.com/billing/subscriptions/pause-payment?locale=en-GB
- Pause subscriptions: https://docs.stripe.com/billing/subscriptions/pause?locale=en-GB
- Customer portal limitations: https://docs.stripe.com/billing/subscriptions/customer-portal
- Subscription invoices: https://docs.stripe.com/billing/invoices/subscription
- Invoice preview: https://docs.stripe.com/invoicing/preview?locale=en-GB
- Invoice edits: https://docs.stripe.com/invoicing/invoice-edits
- Partial payments: https://docs.stripe.com/invoicing/partial-payments?locale=en-GB
- Invoice payment plans: https://docs.stripe.com/invoicing/payment-plans?locale=en-GB
- Automatic tax on invoices: https://docs.stripe.com/tax/invoicing
- Tax on subscriptions: https://docs.stripe.com/tax/subscriptions
- Tax IDs: https://docs.stripe.com/tax/invoicing/tax-ids?locale=en-GB
- Customer credit balance: https://docs.stripe.com/invoicing/customer/balance?dashboard-or-api=api
- Usage-based billing: https://docs.stripe.com/billing/subscriptions/usage-based
- Record usage: https://docs.stripe.com/billing/subscriptions/usage-based/recording-usage
- Meters: https://docs.stripe.com/billing/subscriptions/usage-based/meters/configure
- Billing credits: https://docs.stripe.com/billing/subscriptions/usage-based/billing-credits
- Smart Retries: https://docs.stripe.com/billing/revenue-recovery/smart-retries?locale=en-GB
- Invoice rendering templates: https://docs.stripe.com/invoicing/invoice-rendering-template?locale=en-GB