Functional contract
SaaS billing
Organization plan subscriptions, usage credits, and Stripe PaymentIntents. Not clinic AR / patient invoices — see Billing and finance.
Pricing and renewals
- Monthly amount =
plan.price_per_location_month× location count (USD cents via PaymentIntent). - Monthly credits = plan credits × locations when scoped per location;
nil= unlimited. - Billing day from first successful subscribe; renewals use the same calendar day (or last day of month).
- Charges are custom off-session PaymentIntents (not Stripe Billing Subscriptions). Webhook:
POST /webhooks/stripe. Daily job:Billing::RenewDueSubscriptionsJob.
Trial and testing credits
- Date-based free trial (
trial_ends_on, default fromPlatformSetting.free_trial_days). - On provision: 5 testing credits on a
CreditAccount. - Subscribe ends the trial, wipes remaining testing credits, grants plan credits × locations.
Plan upgrades and downgrades
Direction via Billing::PlanRank (price, then credits / position). Same plan is a no-op.
| Change | When | Behavior |
|---|---|---|
| Upgrade | Immediate | Prorated PaymentIntent (plan_change); credits adjust; plan switches now; billing day unchanged |
| Downgrade | Next renewal | pending_plan_id / pending_plan_scheduled_on; blocked if over target caps; applied by Billing::PendingPlanApplier before renew charge |
POST /app/billing/plan_change— upgrade now or schedule downgradeDELETE /app/billing/plan_change— cancel pending downgradeGET /api/v1/billing— includes pending plan fields- Admin org
plan_idusesBilling::PlanChangewhen subscribed
Other lifecycle
- Mid-cycle location proration — money and credits for remaining cycle fraction.
- Auto-recharge — when balance < 10% of cycle baseline, restore to full grant and invoice.
- Refunds / disputes — credit clawback (and restore if dispute won).
- Invoice PDFs — TaskPaws brand; Version Dos LLC DBA TaskPaws in footer.
UI
- Settings → Billing (
/app/settings?tab=billing): subscribe, card, change plan, pending banner, transactions, invoice PDF./app/billingredirects there. /admin/billing_transactions— past and upcoming charges.
Full contract: docs/functional/saas-billing.md.