⚠ This document is superseded (v1 reference — not confirmed v2 design).

Module 11: Billing

SUPERSEDED 2026-06-10: This file is the pre-refactor SaaS-subscription spec describing Vrida's billing of its tenants (subscriptions, tiers, dunning, MRR, Enterprise contracts — 115 features). That responsibility now belongs to the Platform module, which already has all the schema (subscription, subscription_invoice, payment, billing_account, tier_definition, tenant_entitlement — see docs/SCHEMA.md § platform and PROJECT_DECISIONS "Platform Module").

The current billing schema is MERCHANT-SIDE A/R + A/P (tenant charges its own customers; tenant pays its own vendors). The module boundary and seams are defined in PROJECT_DECISIONS "Billing Module Boundary (Clarified 2026-06-10)". The merchant-side billing schema has no feature-spec file; it is designed from its seams (see PROJECT_DECISIONS for the authoritative boundary).

This file is retained for reference only — the 115-feature SaaS subscription content may be useful when Platform's subscription UX/admin spec is written. Do NOT use this file to drive billing schema design. Do NOT delete.

⚠️ Module renamed (2026-05-13 per Billing Ownership Split) from "Billing & Subscription" to "Billing" — customer-facing A/R only. The SaaS subscription (Vrida → tenant) responsibility has moved to the Platform module (subscription, subscription_invoice, payment, billing_account, tier_definition, tenant_entitlement, etc. — 16 platform tables total; see PROJECT_DECISIONS "Platform Module (Locked 2026-05-13)").

Incoming: charge_account from CRM (the tenant → their customers A/R relationship). This is the natural home for customer-facing A/R now that SaaS subscription has moved out.

Stripe access continues to route via PaymentsService (Payments module) per the Architecture Redesign — no change there. The Stripe webhook ownership annotation added in Phase 4B-2 (webhook handler moves to PaymentsService) remains valid.

Status: ⛔ SUPERSEDED 2026-06-10 — see note above. Original ✅ Locked for v1.0 status preserved for historical reference only. Schema: billing — merchant-side A/R + A/P (NOT SaaS subscription — see supersession note) Feature count: 115 features in v1.0SUPERSEDED — these 115 features describe Platform's SaaS subscription responsibility, not the current billing module scope. Build estimate: Strategic spec only — implementation effort TBD Last updated: 2026-05-12 (supersession note added 2026-06-10)

Overview

Billing & Subscription handles tenant subscription to Vrida's SaaS platform — the payment flow where nurseries pay Vrida for the service. This is distinct from:

  • Module 4 (Purchasing): tenant pays vendors for inventory
  • Module 5 (CRM): tenant collects A/R from their own customers via charge accounts

Module 11 is the smallest of the three billing flows because Stripe handles ~70% of the heavy lifting. The module covers tier definitions, signup/trial flow, recurring billing, usage metering, failed payment dunning, plan changes, invoices, taxes, promotions, reporting, multi-tenant pricing, add-on subscriptions, and Enterprise contracts.

Billing is consumed by every other module for tier enforcement. Billing depends on Stripe for payment processing and Module 10 (Admin) for tenant context.

Target Customer Profile

  • Mid-size growth-stage retail nursery, $500K–$5M revenue
  • Subscribes to Pro tier ($99.99/mo or $999/yr); some upgrade to Enterprise
  • Spring-weighted usage; some demand for seasonal pause
  • Mix of monthly and annual subscriptions
  • Multi-site tenants on Enterprise tier with custom contracts
  • Tenant churn risk highest in winter slowdown months

Architecture Principle: Configurability

Every threshold, default, and policy in Billing is configurable per tenant via the Owner Dashboard (Module 10).

Tier Behavior

Tier Billing capability
Starter Self-service signup; 30-day trial; manage card on file; basic billing dashboard
Pro All Starter + plan changes, pause for seasonal, usage analytics, promotional codes, multi-payment-methods, add-on subscriptions
Enterprise All Pro + custom pricing, multi-year contracts, ACH/wire, MSA/TOS signing, sales-quoted plans, contract terms management, per-tenant subscription notes

Feature Hierarchy (115 features across 14 groups)

Group 1: Subscription Plans & Tiers (8 features)

# Feature Notes
1.1 Tier definition Starter $49.99 / Pro $99.99 / Enterprise $199.99 monthly
1.2 Annual vs monthly billing options Annual: $499 / $999 / $2999
1.3 Per-tier feature gating What each tier includes; enforced application-side
1.4 Per-tier usage limits SKU count, user count, site count caps per tier
1.5 Tier comparison page Marketing-style display of tier features
1.6 Tier change history Past upgrades/downgrades audit
1.7 Tier promo codes One-time discounts at signup
1.8 Tier-grandfathering Existing tenants on older pricing maintain rate

Group 2: Subscription Signup & Trial (8 features)

# Feature Notes
2.1 New tenant signup flow Email, password, business info → Stripe Customer created
2.2 30-day free trial No credit card required
2.3 Trial activation tracking Days remaining, days used
2.4 Trial extension by Vrida support Manager-approved extensions
2.5 Trial-to-paid conversion Add payment method → trial ends, subscription starts
2.6 Trial-end read-only mode If no payment added, app is read-only; data preserved
2.7 Trial conversion analytics What % of trials convert to paid
2.8 Tenant onboarding integration with billing Billing setup is part of onboarding wizard

Group 3: Stripe Connect & Payment Setup (9 features)

Scope note: Per-tenant Stripe Customer for SaaS billing is distinct from per-site Stripe Connect Account for in-person payment routing (Module 9 feature 1.14). One tenant has one Stripe Customer; one tenant can have N Connect Accounts. See PROJECT_DECISIONS Stripe Architecture.

Routing note (Architecture Redesign 2026-05-13): All Stripe Customer creation, payment-method capture, ACH/wire setup, Customer Portal integration, and tax info collection route via PaymentsService (Payments module). Billing does not call Stripe APIs directly. Billing owns the subscription lifecycle (tier, plan, billing cycle, dunning policy); PaymentsService owns the Stripe interaction (creating customers, capturing payment methods, charging, refunding).

# Feature Notes
3.1 Stripe Customer creation Per-tenant Stripe Customer for SaaS subscription
3.2 Payment method (credit card) capture Stripe Elements UI for card entry
3.3 Default payment method Card used for recurring charges
3.4 Multiple payment methods Backup card; ACH for Enterprise
3.5 Payment method update Edit card on file
3.6 Payment method verification Card validation at update
3.7 ACH / wire transfer setup Enterprise tier
3.8 Tax info collection Sales tax for SaaS in tenant's jurisdiction
3.9 Stripe Customer Portal integration Tenant manages payment methods via Stripe-hosted page

Group 4: Recurring Billing & Charges (11 features)

Routing note (Architecture Redesign 2026-05-13): All recurring charges, invoice generation, charge retries, refunds, and credit balance applications execute via PaymentsService (Payments module). Billing computes what to charge (proration math, tier transitions, credit application order); PaymentsService executes the charge against Stripe and reports back via events.

# Feature Notes
4.1 Recurring subscription charge Monthly or annual, executed by Stripe
4.2 Billing cycle / anniversary Subscription anniversary day of month
4.3 Prorated charges on upgrade Charged immediately on tier upgrade
4.4 Prorated credits on downgrade Credit applied to future charges
4.5 Invoice generation Stripe invoice for each charge
4.6 Invoice email to tenant Sent on charge success
4.7 Invoice PDF Downloadable invoice document
4.8 Charge retry logic Failed charges retry per Stripe schedule
4.9 Charge success notification Email + dashboard alert on successful charge
4.10 Charge timing Monthly: same day each month; Annual: same day yearly
4.11 Subscription credit balance Account credit accumulates from prorations, refunds, comp; auto-applied to next invoice

Group 5: Usage Metering & Tier Enforcement (14 features)

# Feature Notes
5.1 SKU count tracking Current count vs tier limit
5.2 User count tracking Active users vs tier limit
5.3 Site count tracking Active sites vs tier limit
5.4 Real-time usage display Owner Dashboard shows current usage
5.5 Approaching limit alerts "You're at 90% of Pro SKU limit" — email + dashboard
5.6 Limit-reached behavior Block new additions until upgrade OR allow with overage charge
5.7 Tier-appropriate UI gating Disable features not in tenant's tier
5.8 Tier downgrade impact preview "Downgrade will affect: 50 SKUs, 5 users, 2 sites — proceed?"
5.9 Usage analytics for tenant Tenant sees their own usage patterns
5.10 Tier recommendation engine "Based on usage, Pro tier would save you $X"
5.11 Per-seat billing Charge per user beyond included tier seats
5.12 Usage-based billing Charge per AI chat, per SMS, per transaction (configurable per feature)
5.13 Metered billing for overages Allow tenant to exceed tier limits with monthly overage charges
5.14 Subscription preview / what-if Tenant calculates impact of adding SKUs, users, features before committing

Group 6: Failed Payments & Dunning (11 features)

# Feature Notes
6.1 Failed payment detection Stripe webhook on failed charge
6.2 Failed payment email to tenant Notify tenant immediately
6.3 Failed payment retry schedule Stripe Smart Retries (3 retries over 14 days)
6.4 Failed payment dashboard alert Banner in admin UI
6.5 Account suspension on persistent failure Read-only mode after Stripe's retry window
6.6 Customer-facing app degradation If suspended, customer app shows "service temporarily unavailable"
6.7 Tenant remediation workflow Update payment → automatic resume
6.8 Manual payment processing Vrida support handles ACH or manual card
6.9 Dunning email sequence Multiple touch reminders before suspension
6.10 Account recovery audit Track payment failures, recovery times
6.11 Refund processing for subscription payments Vrida-issued refunds if tenant disputes charge or special circumstances

Group 7: Plan Changes & Upgrades (10 features)

# Feature Notes
7.1 Upgrade tier (manual) Tenant changes from Starter to Pro
7.2 Downgrade tier (manual) Tenant changes from Pro to Starter
7.3 Upgrade tier (auto-suggested) "You've hit limits — upgrade?"
7.4 Downgrade restrictions Can't downgrade if over current tier's limits
7.5 Subscription pause (seasonal) Pause for X months; resume later (Pro+ feature)
7.6 Subscription cancellation Tenant cancels
7.7 Cancellation cooling-off period "Are you sure?" + retention attempt
7.8 Cancellation reason capture Why is tenant leaving?
7.9 Data preservation on cancellation Tenant operational data preserved for 90 days post-cancel (reactivation window). At 90 days, operational data deleted; audit log + financial records (incl. billing.invoice) retained 7 years in archived form; global tables (customer, plant library, garden plans, chat sessions) are consumer-owned and NOT deleted. See PROJECT_DECISIONS Tenant Lifecycle and Data Retention.
7.10 Re-subscription within 90 days Easy reactivation

Group 8: Invoices & Billing History (10 features)

Routing note (Architecture Redesign 2026-05-13): Invoice PDFs, payment receipts, and tax-breakdown calculations are produced by PaymentsService (Payments module) and stored against the Billing module's invoice record. Billing surfaces the tenant-facing invoice list/search UI; PaymentsService handles the Stripe-side document retrieval and storage.

# Feature Notes
8.1 All past invoices viewable Searchable by date, amount
8.2 Invoice download PDF for accounting
8.3 Invoice email re-send Resend to billing contact
8.4 Invoice line item details Subscription, prorations, overage, taxes
8.5 Invoice currency display USD for now (multi-currency deferred)
8.6 Invoice tax breakdown Per-jurisdiction tax on subscription
8.7 Receipt of payment Confirmation per successful charge
8.8 Billing history export All invoices for time period
8.9 Tenant-initiated invoice generation Tenant requests custom invoice for specific period or scenario
8.10 Invoice customization Tenant logo, custom terms, custom message on invoices (Pro+)

Group 9: Tax & Compliance (Subscription) (6 features)

# Feature Notes
9.1 Sales tax on subscription Per-jurisdiction; Stripe Tax handles automatically
9.2 Tax-exempt status If tenant is tax-exempt (govt, nonprofit)
9.3 Reverse-charge / VAT (international) For non-US tenants (deferred v1.5+)
9.4 W-9 / 1099 forms If tenant needs Vrida's tax info
9.5 Receipt of taxes paid Detailed tax record
9.6 Tax compliance reports For tenant accounting

Group 10: Promotions & Discounts (6 features)

# Feature Notes
10.1 Promo code support Discount code at signup or upgrade
10.2 Promo code expiration Limited-time codes
10.3 Promo code usage tracking How many used, which tenants
10.4 Tenant referral codes Existing tenant refers another tenant
10.5 Referral reward (discount or credit) What both get
10.6 Promotional pricing override Per-tenant special pricing

Group 11: Subscription Reporting & Analytics (6 features)

# Feature Notes
11.1 MRR / ARR tracking (per tenant) Tenant's monthly recurring revenue contribution
11.2 Trial conversion rate What % of trials become paid
11.3 Churn rate (per tenant cohort) Retention metrics
11.4 Failed payment rate Stripe-level failure tracking
11.5 Upgrade rate % of tenants who upgrade tier
11.6 Tenant lifetime value Cumulative revenue per tenant

Group 12: Multi-Tenant Pricing (Enterprise) (4 features)

# Feature Notes
12.1 Custom pricing per Enterprise tenant Negotiated contracts
12.2 Volume discounts Multi-site discount tiers
12.3 Bundle pricing Multi-product bundles
12.4 Customer-specific contract terms Non-standard terms with audit

Group 13: Add-on Subscriptions & Bundles (8 features)

Billing model: Add-ons are billed separately from base tier subscription. Stripe Customer has one subscription with multiple line items (base tier + active add-ons). See ARCHITECTURE Stripe Architecture.

# Feature Notes
13.1 SMS Pack add-on 10K SMS/mo $20 Pro / $50 Enterprise; 50K SMS/mo $80 Pro / $200 Enterprise. Stacks on top of tier quota.
13.2 Premium AI add-on Unlimited consumer plant care chat (removes per-tenant Bedrock rate limits). $30/mo Pro / $75/mo Enterprise.
13.3 Additional Site add-on $25/mo per site Pro (when multi-site UI ships v1.5+); Enterprise includes 5 sites, $20/mo per site beyond.
13.4 Extra Users add-on $10/mo per user beyond tier cap (Pro); $15/mo per user (Enterprise unlimited tier, billed if user count exceeds contracted seat count).
13.5 Picas CSV Import Pack $100 one-time when Picas import ships (per PASS 9.1 decision). Includes guided migration support.
13.6 Add-on subscription lifecycle Tenant adds/removes add-ons mid-cycle; prorated billing; immediate quota update.
13.7 Add-on usage display Owner Dashboard shows current add-on subscriptions, monthly cost, usage against add-on quotas.
13.8 Add-on cancellation Mid-cycle cancellation refunds unused portion; effective end-of-cycle option available.

Group 14: Enterprise Contracts & Quotes (4 features)

# Feature Notes
14.1 Subscription quotation / proposal Sales-quoted custom plans before tenant signs up
14.2 Subscription contract management Multi-year contracts with auto-renewal terms, custom dates
14.3 MSA / TOS signing flow Tenant signs legal docs during signup or upgrade. Uses HelloSign (Dropbox Sign) for legal binding; signed PDF + envelope ID stored in R2 with metadata in billing schema. See ARCHITECTURE.md "Signature Infrastructure".
14.4 Subscription notes per tenant Sales team notes, special agreements, internal-only context

Configurable Defaults (Owner Dashboard)

Configurable Default
Trial duration 30 days
Trial requires credit card OFF (no CC)
Trial extension allowed Manager-approved per tenant
Read-only mode duration after trial end Indefinite until payment added
Auto-charge on subscription ON (default)
Invoice delivery method Email
Failed payment retry count Stripe default (3)
Failed payment retry window Stripe default (14 days)
Suspension after failed payment After Stripe retry window
Auto-resume on payment update ON
Dunning email sequence 1 day, 7 days, 14 days before suspension
Subscription pause max duration 6 months (seasonal nurseries)
Cancellation cooling-off 24 hours
Cancellation retention attempts 1 (call/email)
Data preservation after cancel 90 days
Referral program enabled OFF (configurable to ON)
Custom pricing for Enterprise Per-tenant; agreement required
Subscription credit balance enabled ON
Per-seat billing enabled OFF (configurable; opt-in)
Usage-based billing enabled OFF (configurable per feature)
Metered overages allowed OFF (configurable; default is "block at limit")
Stripe Customer Portal enabled ON
MSA/TOS auto-include at signup ON for Enterprise; OFF for Starter/Pro
Auto-renewal default ON (configurable to manual renewal)

AI Features in Billing & Subscription

Feature # AI capability
5.10 AI tier recommendation engine ("based on usage, X tier would save you Y")
5.13 AI overage forecasting and warnings
5.14 AI subscription preview / impact calculation
6.9 AI dunning email personalization
7.3 AI auto-suggested tier upgrades
11.3 AI churn prediction
11.1 AI revenue forecasting at tenant level

All AI features route via AIService (AI / Intelligence module; model-as-config; AWS Bedrock Claude Haiku 4.5 is the default model). Billing does not call Bedrock directly.

Events Emitted

  • billing.tenant_signed_up
  • billing.trial_started
  • billing.trial_extended
  • billing.payment_method_added
  • billing.payment_method_updated
  • billing.subscription_started
  • billing.subscription_charged
  • billing.charge_failed
  • billing.charge_retried
  • billing.subscription_upgraded
  • billing.subscription_downgraded
  • billing.subscription_paused
  • billing.subscription_resumed
  • billing.subscription_cancelled
  • billing.tenant_suspended
  • billing.tenant_reactivated
  • billing.invoice_generated
  • billing.invoice_paid
  • billing.referral_code_used
  • billing.tier_limit_reached
  • billing.tier_limit_approaching
  • billing.add_on_subscription_added
  • billing.add_on_subscription_removed
  • billing.refund_processed
  • billing.credit_balance_updated
  • billing.credit_applied_to_invoice
  • billing.usage_overage_recorded
  • billing.contract_signed
  • billing.contract_renewed
  • billing.quote_created
  • billing.quote_accepted
  • billing.subscription_note_added
  • billing.dispute_opened
  • billing.dispute_resolved
  • billing.payment_method_removed
  • billing.webhook_received
  • billing.webhook_processed
  • billing.webhook_dead_lettered

Stripe Webhook Subscriptions

⚠️ Ownership move (Architecture Redesign 2026-05-13): The Stripe webhook handler ownership moves to PaymentsService (Payments module). PaymentsService is the only module with a Stripe webhook endpoint; it verifies signatures, persists event.id, dispatches side effects to a queue, and emits internal events that Billing (and other modules) consume.

The detailed spec below — subscribed types, idempotency, signature verification, retry handling, failure mode, and the webhook → internal event mapping — now describes PaymentsService's handling, not Billing's. It is preserved here verbatim because Billing remains the primary consumer of the resulting billing.* events and needs to understand the upstream pipeline. The billing.webhook_* events listed above continue to fire (emitted by PaymentsService on Billing's behalf, or by Billing as it processes the PaymentsService events — final boundary TBD in Foundation implementation phase). Do not delete this section.

Subscribed webhook types (Stripe API):

  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • customer.subscription.trial_will_end
  • invoice.created
  • invoice.paid
  • invoice.payment_failed
  • invoice.payment_action_required
  • invoice.finalized
  • charge.refunded
  • charge.dispute.created
  • charge.dispute.closed
  • customer.updated
  • payment_method.attached
  • payment_method.detached
  • payment_method.updated
  • setup_intent.succeeded
  • payment_intent.payment_failed

Idempotency: every webhook event includes a unique event.id from Stripe. We persist event.id to billing.stripe_event_log on receipt; duplicate events with the same id are deduped and not reprocessed. Idempotency key on outbound API calls to Stripe uses pattern tenant_{tenant_id}_{operation}_{request_id}.

Signature verification: every webhook request verifies the Stripe-Signature header using STRIPE_WEBHOOK_SECRET. Requests failing signature verification return 400 and are logged to audit.

Retry handling: Stripe retries failed webhooks with exponential backoff for up to 3 days. Our webhook endpoint returns 200 OK as soon as event.id is persisted, NOT after side effects complete. Side effects (state changes, notifications, ledger entries) run from a background queue keyed by event.id; queue processor is idempotent.

Failure mode: if event processing fails after webhook ack, the queue retries with backoff. After max retries, the event is moved to billing.stripe_event_dead_letter and an admin alert fires (notifications.system_alert).

Critical webhook → internal event mapping:

  • customer.subscription.createdbilling.subscription_started
  • customer.subscription.updatedbilling.subscription_upgraded / downgraded / paused / resumed
  • customer.subscription.deletedbilling.subscription_cancelled
  • invoice.paidbilling.invoice_paid + billing.subscription_charged
  • invoice.payment_failedbilling.charge_failed
  • charge.refundedbilling.refund_processed
  • charge.dispute.createdbilling.dispute_opened
  • payment_method.attachedbilling.payment_method_added
  • payment_method.detachedbilling.payment_method_removed

Events Consumed

  • admin.tenant_settings_changed (track tenant changes that affect billing)
  • pos.sale_completed (usage metering)
  • crm.customer_created (active user tracking)
  • inventory.variant_created (SKU count)
  • multi_loc.site_created (site count tracking)

API Contract (BillingService — public methods)

High-level surface (detailed signatures during implementation):

  • Subscription lifecycle: createSubscription, upgradeTier, downgradeTier, pauseSubscription, resumeSubscription, cancelSubscription, reactivateSubscription
  • Payment methods: addPaymentMethod, updatePaymentMethod, setDefaultPayment, enableCustomerPortal
  • Recurring billing: getNextChargeDate, chargeImmediately, retryFailedCharge, processRefund, applyCreditBalance
  • Usage metering: trackUsage, getTierStatus, previewWhatIf, recordOverage, getUsageReport
  • Add-ons: addAddOnSubscription, removeAddOnSubscription, getAddOnUsage
  • Enterprise: generateQuote, signContract, getMSAStatus, addSubscriptionNote, renewContract
  • Invoices: getInvoices, downloadInvoice, generateCustomInvoice, customizeInvoiceTemplate
  • Promotions: applyPromoCode, trackReferral, applyDiscount
  • Reporting: getMRR, getChurnRate, getLTV, getTrialConversion

Out of Scope

Capability Why excluded
Multi-currency subscription Defer to v1.5+
Subscription marketplace (different add-ons from third parties) Defer
Affiliate commission tracking Future v2.0
Enterprise contract management UI (rich editing) Manual via sales for v1.0
Custom tax calculations beyond Stripe Tax Use Stripe Tax
Tenant-funded discounts (tenant pays for customer promos) Out of scope
Cross-tenant pricing (volume discounts across multiple tenants of same company) Out of scope
Payment processor failover Stripe is primary; no backup
Dispute / chargeback management Stripe handles
Hibernation / long-term low-cost state Pause is sufficient for v1.0
Subscription win-back campaigns Marketing feature; defer
Subscription handoff to sales (auto-trigger) Defer to internal Vrida CRM
Subscription reseller / partner pricing Future v2.0

Gaps Identified from Market Research

Source: See docs/MARKET_RESEARCH_GAPS.md for the master gap registry. Status: All gaps below are Open — pending decision. None have been accepted into scope yet.

Gap # Gap What's missing in this module Research source Possible options
17 Per-terminal pricing model Flat tier pricing is locked Research §3.1 Rejected — Option (b): flat tier pricing retained; add-ons (Group 13) cover terminal-heavy tenants.
18 Sandbox / forever-free dev account No forever-free non-production sandbox yet Research §10.B Deferred (v1.2) — Ships when API surface stabilizes. See ROADMAP v1.2.
Last modified: Jun 17, 2026, 6:57 PM PT
On this page
Esc