Skip to content

SaaS & Commerce — Ecosystem Overview

Granit provides a complete SaaS & Commerce ecosystem through five interdependent modules. Together they cover the full monetization lifecycle: plans → subscriptions → usage tracking → invoicing → credit balance → payment collection, with sovereignty-first design (SEPA transfer works without any external dependency).

graph TD
    subgraph "Granit SaaS Ecosystem"
        SUB[Granit.Subscriptions] -->|CreateInvoiceCommand| INV[Granit.Invoicing]
        MET[Granit.Metering] -->|UsageSummaryReadyEto| SUB
        INV -->|InvoiceFinalizedEto| PAY[Granit.Payments]
        PAY -->|PaymentSucceededEto| INV
        INV -->|InvoicePaidEto| SUB
        INV -->|OverpaymentDetectedEto| BAL[Granit.CustomerBalance]
        BAL -->|IInvoicePrePaymentProcessor| PAY
    end

    SCH[Granit.Scheduling] -.->|scheduled plan changes| SUB
    FEA[Granit.Features] -.->|plan-driven cascade| SUB

    style SUB fill:#4a9eff,color:#fff
    style INV fill:#ff9f43,color:#fff
    style PAY fill:#2ed573,color:#fff
    style MET fill:#a55eea,color:#fff
    style BAL fill:#ff6b81,color:#fff

The modules communicate exclusively via integration events (Wolverine outbox). Subscriptions never listens to Payment events directly — this is critical for credit note scenarios.

Metering ──UsageSummaryReadyEto──→ Subscriptions (billing cycle orchestrator)
├── fixed line items (plan price)
├── usage line items (from IUsageReader)
└──CreateInvoiceCommand──→ Invoicing
InvoiceFinalizedEto ←───┘
IInvoicePrePaymentProcessor
(CustomerBalance deducts credit,
or PassThrough if not installed)
Payments
PaymentSucceededEto ───→ Invoicing (RecordPayment)
InvoicePaidEto ←───┘
Subscriptions (renews/activates)
ModulePurposePhase
SubscriptionsPlans, subscriptions, seats, entitlements, billing cycle orchestration1
InvoicingInvoices, credit notes, partial payments, tax, external accounting sync1
PaymentsProvider-agnostic payment processing, webhooks, refunds, disputes1
MeteringUsage event recording, watermark aggregation, quota enforcement1
TaxTax calculation (EU VAT, Stripe Tax), VIES validation, rate management2
Customer BalancePer-tenant credit ledger, pre-payment deduction, promotional credits with expiration3

Each module has a .Notifications package with NotificationType<TData> definitions (15 types total: 6 Subscriptions, 4 Invoicing, 5 Payments). Email templates are Phase 2.

ModuleRole in SaaS
SchedulingOne-shot future actions (scheduled plan changes, trial expiration)
Background JobsRecurring scans (trial expiration, period end, aggregation, quota checks)
FeaturesPlan-driven feature cascade via Subscriptions.Features bridge
WorkflowFSM for subscription and plan lifecycle
NotificationsPayment reminders, trial expiration, quota alerts

Every payment flow has a zero-dependency option. SEPA bank transfer works without Stripe, Mollie, or any US cloud provider — critical for HDS/sovereign hosting.

Invoicing and Payments are not SaaS-specific. InvoiceLineItem.SourceType accepts Subscription, Usage, OneShot, or Credit — enabling future Granit.Commerce (e-commerce) to reuse the same billing and payment infrastructure.

Granit is the source of truth for subscription and payment status. External providers (Stripe, Mollie) are executors with declared capabilities. A tenant can have multiple providers active simultaneously (Card → Stripe, BankTransfer → SEPA, iDEAL → Mollie).

PhaseScopeStatus
1Subscriptions + Invoicing + Payments (Stripe + Mollie) + Metering + NotificationsImplemented
2SEPA providers, Invoicing.Internal (PDF), Invoicing.Odoo, Tax (EU VAT + Stripe Tax), dunning, multi-currency, pricing resolverImplemented
3Email templates, customer balance (credit ledger), Open Banking (PSD2), Granit.CommerceImplemented
RequirementImplementation
GDPRTenant isolation, data minimization, right to erasure on billing data
ISO 27001Immutable audit trails on invoices and payment transactions, 3-year retention
PCI DSSHosted payment pages only — no card data in Granit
HDSSovereign hosting capable — SEPA transfer has zero external dependency