Skip to content
This repository was archived by the owner on Aug 11, 2026. It is now read-only.
This repository was archived by the owner on Aug 11, 2026. It is now read-only.

feat(subscription-billing): add subscription, invoice, credit, renewal, and dunning state machines #876

Description

@ahliweb

Parent epic: #868
Depends on: #869, #870, #871, #873, #875

Context

AWCMS-Mini needs reusable SaaS subscription billing orchestration, but it must not become a tenant general ledger, AR/AP, tax engine, or payment provider implementation. Commercial records need exact amounts, immutable issued documents, idempotent period generation, and deterministic lifecycle requests.

Objective

Implement a provider-neutral subscription_billing capability for subscription terms, renewals, invoices, line items, credits, refunds-as-commercial-requests, dunning schedules, and lifecycle/entitlement coordination.

Scope

  • Add admitted module/extension descriptor, permissions, jobs, events, lifecycle descriptors, and admin navigation.
  • Add schema for:
    • subscriptions and immutable plan-version binding;
    • billing periods and anchors;
    • invoice drafts, issued invoices, line items, totals, due dates, and status history;
    • credit notes/adjustments linked to original invoice lines;
    • renewal, upgrade, downgrade, cancellation, proration-policy metadata, and scheduled changes;
    • payment allocation references without accounting-ledger semantics;
    • dunning attempts/schedules and lifecycle requests.
  • Implement state machines for subscription and invoice lifecycles.
  • Generate invoice drafts idempotently from catalog price components and usage aggregates.
  • Support review/issue/void/credit operations; issued invoices are immutable.
  • Use exact decimal/minor-unit arithmetic with currency consistency and explicit rounding policy.
  • Integrate with entitlements and lifecycle through commands/events, not direct cross-module table writes.
  • Request payment sessions through feat(payment-gateway): add provider-neutral checkout, signed webhook inbox, retries, and reconciliation #877 adapter contract; no provider call in invoice transaction.
  • Add scheduled renewal/invoice/dunning jobs with leases, bounded batches, retries, and reconciliation.
  • Add OpenAPI/AsyncAPI, admin UI, tenant-facing invoice read/download metadata, audit, metrics, and reporting projections.

Out of scope

Security and integrity requirements

  • Platform billing permissions are separate from tenant administration.
  • Tenant users can read only authorized tenant commercial records and cannot change issued invoices.
  • Invoice generation is idempotent per subscription/period/version.
  • Amount/currency/rounding constraints prevent overflow and mixed-currency totals.
  • Upgrade/downgrade/cancel changes are concurrency-safe and preserve historical terms.
  • Payment status is updated only through validated adapter/reconciliation outcomes.
  • Lifecycle suspension requests are reasoned and auditable; billing does not directly bypass feat(tenant-lifecycle): enforce trial, active, grace, suspended, canceled, restore, and downgrade semantics #873 policy.
  • Sensitive billing contact/provider references are minimized and masked.

Acceptance criteria

Testing

  • Unit tests for subscription/invoice state machines, period boundaries, proration policy, rounding, credits, and dunning.
  • PostgreSQL integration tests for RLS, uniqueness, immutable issued records, idempotent concurrent generation, and event same-commit behavior.
  • Usage-to-invoice reconciliation tests.
  • Worker restart/lease tests and failure injection.
  • Cross-tenant and authorization-negative tests.
  • E2E plan assignment → subscription → invoice issue → manual payment reference/dunning.
  • Mutation tests for duplicate invoice generation, float use, or issued-invoice edit.

Documentation

  • ERD/data dictionary, state diagrams, monetary/rounding policy, OpenAPI/AsyncAPI, billing operator and tenant guides, manual-payment SOP, dunning/lifecycle matrix, retention/backup impact, module README, and changeset.

Dependencies

Consumes payment outcomes from #877 and feeds control-plane reporting #880.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:apiKontrak OpenAPI/RESTarea:databaseSchema, migration, pooling, RLSarea:reportingManagement reporting viewsarea:securitySecurity and 2FA workpriority:p1Prioritas tinggi - core domaintype:taskAtomic implementation task

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions