Dunning & Payment Enforcement
En bref
Dunning and Payment Enforcement runs the involuntary collection ladder for unpaid platform invoices, escalating banner_only -> final_warning -> read_only -> pre_deletion -> deleted with persistent UI banners visible to every tenant user, admin email cascades on every transition, Stripe webhook integration that opens cases on payment_failed and closes them on paid up to final_warning, contract-billing trigger at 30 days overdue and a manual platform-admin waive that requires a documented reason in the governance audit log.
Comment ça fonctionne
When Stripe emits invoice.payment_failed for a tenant, the dunning engine opens a DunningCase tied to the failing Invoice and starts the involuntary lifecycle at banner_only. A persistent payment-overdue banner is rendered to every authenticated tenant user — not only admins — so the consequences are visible to the entire organisation. As scheduled offsets elapse, the case escalates through final_warning, read_only (the tenant can read but cannot mutate billable data), pre_deletion and finally deleted.
Each transition triggers an email cascade to all tenant admins, with template, channel and offset taken from the BillingProfile dunning configuration. Contract billing has a separate trigger: 30 days overdue on a signed services contract opens a dunning case directly without a Stripe failure. Stripe webhook integration closes the loop at invoice.paid: if the case is at or below final_warning the case is closed cleanly, banners disappear and read access is restored; once read_only has been entered, automatic reactivation is explicitly disabled and a platform admin must manually waive.
The waive endpoint requires a mandatory reason that is written to the governance audit log so every override is traceable to an operator and a justification. Voluntary cancellation during an active case closes the dunning cleanly and prevents post-cancellation escalation. The PL-T047 implementation is documented in specs/api/endpoints/dunning.md and the policy ladder in docs/domain/dunning-policy.md, both linked from the feature inventory.
Capacités clés
- Five-stage involuntary lifecycle: banner_only -> final_warning -> read_only -> pre_deletion -> deleted
- Persistent payment-overdue banner shown to every tenant user, not just admins
- Email cascade to all tenant admins on every stage transition
- Stripe webhook integration: invoice.payment_failed opens a case, invoice.paid closes it up to final_warning
- Contract billing trigger at 30 days overdue without requiring a Stripe failure
- Platform-admin manual waive with mandatory reason written to the governance audit log
- No automatic reactivation past read_only, and clean closure on voluntary cancellation
En pratique
A small federation's Stripe subscription charge fails on renewal. Within minutes a banner appears for every logged-in user reading Payment overdue and an email cascade reaches all four tenant admins. Two stages later, with no successful retry, the case escalates to final_warning and a stronger email goes out.
The treasurer fixes the card, Stripe emits invoice.paid, the case closes automatically and the banner disappears. A different federation ignores the cascade; thirty days in the case enters read_only, the platform freezes mutations, and only a platform admin's manual waive — with reason Payment plan agreed via support ticket #4821 — can lift it. The waive is recorded in the governance audit log against the operator's user id.
Fonctionnalités de ce sous-système
8| ID | Status | Fonctionnalités |
|---|---|---|
| F08.09.01 | Livré | Involuntary dunning lifecycle: banner_only → final_warning → read_only → pre_deletion → deleted ✅ PL-T047 |
| F08.09.02 | Livré | Persistent payment-overdue banner visible to all tenant users (not just admins) ✅ PL-T047 |
| F08.09.03 | Livré | Email cascade to all tenant admins at each dunning stage transition ✅ PL-T047 |
| F08.09.04 | Livré | Stripe webhook integration: invoice.payment_failed opens case, invoice.paid closes (if ≤ final_warning) ✅ PL-T047 |
| F08.09.05 | Livré | Contract billing integration: 30-day overdue triggers dunning case ✅ PL-T047 |
| F08.09.06 | Livré | Platform-admin manual waive with mandatory reason + governance audit log ✅ PL-T047 |
| F08.09.07 | Livré | Anti-scope: no auto-reactivation after read_only — manual waive required ✅ PL-T047 |
| F08.09.08 | Livré | Voluntary cancellation during active dunning case closes dunning cleanly ✅ PL-T047 |
Parties prenantes qui ont besoin de ce sous-système
Apparaît dans 1 analyses de parties prenantes