Skip to content
Event storming templates

Event Storm — Subscription Billing

Trial, invoicing and dunning for a SaaS product: four policies chain the contexts together and a failed payment routes into collections.

Template previewEvent storming
Subscription billing — trial to dunningBounded contexts3Domain events7Event coverage85.7%Hotspots2Model smells1Domain eventCommandActorAggregatePolicyRead modelExternal systemHotspotSubscriptions2 events · 1 command · 1 policy · 1 hotspotSubscriptionBilling3 events · 2 commands · 2 policies · 0 hotspotsInvoiceInvoiceCollections2 events · 2 commands · 0 policies · 1 hotspotDunning caseSubscriberStart trialTrial startedPlan and usagesummaryTrial expiredDoes a pausedsubscription stillconsume seats?When trial expired,raise invoiceBilling schedulerRaise invoiceInvoice raisedWhen invoice raised,charge cardBilling schedulerCharge cardPayment takenPayment failedMRR and churndashboardCard processorWhen payment failed,start dunningCollections serviceStart dunningDunning startedEmail deliveryserviceCollections serviceSuspend accountAccount suspendedThree failed cards ina month — retry orsuspend?Workshop checksEvents with no producing command1Trial expiredCommands with no resulting event0noneCommands with no aggregate0noneAggregates with no events0nonePolicies with a missing trigger event0nonePolicies with a missing command0noneHotspots per context2Subscriptions 1 · Collections 1Cross-context flows2Subscriptions → Billing · Billing → Collections

Make it your own.

title "Subscription billing — trial to dunning"

context "Subscriptions"
  actor Subscriber
  aggregate Subscription
  command "Start trial" by Subscriber on Subscription
  event "Trial started" from "Start trial"
  readmodel "Plan and usage summary"
  event "Trial expired"
  hotspot "Does a paused subscription still consume seats?"
  policy "When trial expired, raise invoice" then "Raise invoice"

context "Billing"
  aggregate Invoice
  command "Raise invoice" by "Billing scheduler" on Invoice
  event "Invoice raised" from "Raise invoice"
  policy "When invoice raised, charge card" then "Charge card"
  command "Charge card" by "Billing scheduler" on Invoice
  event "Payment taken" from "Charge card"
  event "Payment failed" from "Charge card"
  readmodel "MRR and churn dashboard"
  external "Card processor"
  policy "When payment failed, start dunning" then "Start dunning"

context "Collections"
  aggregate "Dunning case"
  command "Start dunning" by "Collections service" on "Dunning case"
  event "Dunning started" from "Start dunning"
  external "Email delivery service"
  command "Suspend account" by "Collections service" on "Dunning case"
  event "Account suspended" from "Suspend account"
  hotspot "Three failed cards in a month — retry or suspend?"