Skip to content

Features

Subscription aggregate

ISubscription / SubscriptionEntity (IAggregateRoot<Guid>, ITenantScopedEntity) with child collections:

  • ISubscriptionCycle / SubscriptionCycleEntity - edition assignment / billing cycle rows.
  • ISubscriptionSeatPolicy / SubscriptionSeatPolicyEntity - seat policy overrides.

Smart enums: SubscriptionLifecycleStatusEnumeration (Draft -> Active -> Suspended -> Decommissioned), BillingCadenceEnumeration (e.g. Monthly), InvoiceLifecycleStatusEnumeration.

Published integration events

Event Topic
SubscriptionCreatedIntegrationEvent billing.subscriptions.v1.subscription-created
SubscriptionUpgradedIntegrationEvent billing.subscriptions.v1.subscription-upgraded
SubscriptionCanceledIntegrationEvent billing.subscriptions.v1.subscription-canceled
InvoiceIssuedEvent billing.invoices.v1.invoice-issued
PaymentCapturedIntegrationEvent billing.payments.v1.payment-captured
EntitlementsSyncRequestedIntegrationEvent billing.entitlements.v1.entitlements-sync-requested

Cross-context reactions (sagas)

Billing is the platform reaction hub. Inbound stubs (MessagingModel/Inbound/) feed six MassTransit state machines (FlowModel.MassTransit/):

Inbound event Saga
TenantActivatedInboundIntegrationEvent (tenants.domain.v1.tenant-activated) TenantActivationBillingProvisioningStateMachine
EffectiveEntitlementsUpdatedInboundIntegrationEvent EntitlementsChangedBillingReactionStateMachine
CatalogProductUpdatedInboundIntegrationEvent CatalogEditionBillingReactionStateMachine
CatalogProductRetiredInboundIntegrationEvent (catalog.domain.v1.product-retired) CatalogProductRetiredBillingReactionStateMachine
MeteringQuotaExceededInboundIntegrationEvent (metering.quota.v1.quota-exceeded) MeteringQuotaExceededBillingReactionStateMachine
Subscription lifecycle upgrade/cancel requested SubscriptionLifecycleStateMachine

Topology: BillingMassTransitTopology; event bus IEventBus -> MassTransitAdapter.

Orleans

SubscriptionEditorGrain (ISubscriptionEditorGrain : ISubscriptionEditorActor, IGrainWithStringKey keyed by tenant id) serializes writes - enforcing the one-subscription-per-tenant invariant. Grain storage: SubscriptionsGrainStorage.

Scheduling and metrics

  • IBillingScheduler / HangFireBillingScheduler for background work.
  • BillingMetrics counters for lifecycle and query paths.
  • Billing-owned GrpcRichErrorInterceptor (when Grpc:GrpcErrorHandlingStrategy = RichError).

See also