Model SaaS Subscription Billing

This tutorial models a subscription lifecycle with entitlements, plan changes, payment failures, and dunning.

Scenario

A SaaS company wants to generate a subscription management system that handles trials, paid plans, seats, entitlements, invoices, failed payments, and cancellation.

Events

  • Trial Started
  • Subscription Activated
  • Seat Added
  • Plan Changed
  • Invoice Issued
  • Payment Failed
  • Dunning Started
  • Entitlements Suspended
  • Subscription Cancelled

Aggregates

  • Subscription: plan, lifecycle, renewal date, cancellation state.
  • Account Entitlements: features and limits available to the account.
  • Invoice: issued amount, due date, payment state.
  • Dunning Case: payment recovery workflow and communications.

Commands

  • Start Trial
  • Activate Subscription
  • Add Seat
  • Change Plan
  • Issue Invoice
  • Record Payment Failure
  • Start Dunning
  • Suspend Entitlements
  • Cancel Subscription

Rules

  • A subscription cannot be activated without a billing account.
  • A seat cannot be added beyond the account’s plan limit unless overage billing is enabled.
  • A plan downgrade cannot remove features currently required by active commitments without confirmation.
  • Entitlements can only be suspended after the configured dunning window expires.

Policies And Saga

  • When Subscription Activated, enable account entitlements.
  • When Plan Changed, recalculate entitlements and billing schedule.
  • When Payment Failed, start dunning if the account is not already in dunning.
  • When Dunning Started, schedule payment retry and send customer notification.
  • Use a Dunning Process saga to track retries, notifications, deadlines, recovery, suspension, and cancellation.

Read Models

  • Account Subscription Summary: current plan, status, renewal, seats, entitlements.
  • Billing Timeline: invoices, payments, failures, refunds, dunning actions.
  • Dunning Work Queue: accounts needing support intervention.
  • Feature Access View: entitlements consumed by the product runtime.