fix: harden invoice reconciliation
This commit is contained in:
@@ -117,6 +117,7 @@ Current rule:
|
||||
- The system must treat an invoice as `paid` only after the payment provider reports a final successful status, meaning the funds are accepted strongly enough for access activation.
|
||||
- Worker reconciliation now polls provider status for stored `pending` invoices.
|
||||
- If the provider reports final `paid`, the worker activates access from provider `paidAt` when that timestamp is available.
|
||||
- If the provider reports final `paid` after a local fallback expiry, provider `paid` still wins and access is activated.
|
||||
- If the provider reports final `expired` or `canceled`, the worker finalizes the local invoice to the same terminal status.
|
||||
|
||||
## Worker reconciliation flow
|
||||
@@ -128,6 +129,9 @@ Current rule:
|
||||
6. After provider polling, the worker also expires any still-pending invoices whose local `expiresAt` has elapsed.
|
||||
7. If a manual admin action or another worker already finalized the invoice, reconciliation degrades to replay/no-op behavior instead of duplicating side effects.
|
||||
|
||||
Implementation note:
|
||||
- invoice creation paths take a per-subscription database lock so manual invoice creation and worker renewal creation do not create duplicate invoices for the same subscription at the same time.
|
||||
|
||||
## Invoice listing flow
|
||||
- `GET /api/billing/invoices` returns the user's invoices ordered by newest first.
|
||||
- This is a read-only view over persisted `PaymentInvoice` rows.
|
||||
|
||||
Reference in New Issue
Block a user