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/HangFireBillingSchedulerfor background work.BillingMetricscounters for lifecycle and query paths.- Billing-owned
GrpcRichErrorInterceptor(whenGrpc:GrpcErrorHandlingStrategy = RichError).