Status & lifecycle reference
Four state machines drive the platform. Illegal transitions are rejected
with a 422 carrying a stable problem discriminator.
Subscription
pending_activation ──► trialing ──► active ──► past_due ──► canceled │ │ │ ▼ ▼ ▼ active paused canceled │ └──► active (resume)| From | To | Trigger |
|---|---|---|
pending_activation | trialing | Activation with trial. |
pending_activation | active | Activation without trial. |
pending_activation | incomplete_expired | Activation deadline elapsed. |
trialing | active | Trial end reached; first invoice issued. |
trialing | canceled | Cancellation during trial. |
active | past_due | A payment failed. |
active | paused | POST /v1/subscriptions/{id}/pause. |
active | canceled | Cancellation, immediate. |
active | ended | Commitment ended without renewal. |
past_due | active | A retry succeeded (dunning recovered). |
past_due | canceled | Dunning exhausted with on_exhaustion: cancel_subscription. |
past_due | paused | Dunning exhausted with on_exhaustion: pause_subscription. |
paused | active | Auto-resume on paused_until, or manual resume. |
paused | canceled | Cancellation during pause. |
Terminal: canceled, ended, incomplete_expired.
Invoice
draft ──► open ──► partially_paid ──► paid │ │ │ ▼ ▼ ▼ void uncollectible …| From | To | Trigger |
|---|---|---|
draft | open | POST /v1/invoices/{id}/finalize. |
draft | (deleted) | DELETE /v1/invoices/{id} on a draft. |
open | partially_paid | A payment ≤ amount_due succeeded. |
open | paid | A payment cleared the balance to ≤ 0. |
open | void | POST /v1/invoices/{id}/void. |
open | uncollectible | POST /v1/invoices/{id}/mark-uncollectible. |
partially_paid | paid | A subsequent payment cleared the balance. |
partially_paid | uncollectible | Operator marks unrecoverable. |
Terminal: paid, void, uncollectible.
Payment
pending ──► processing ──► requires_action ──► succeeded │ │ │ ▼ ▼ ▼canceled failed refunded / partially_refunded / charged_back| From | To | Trigger |
|---|---|---|
pending | processing | Sent to provider. |
pending | canceled | Manual cancel before send. |
processing | requires_action | Provider returned 3DS / SCA challenge. |
processing | succeeded | Capture cleared. |
processing | failed | Provider declined. |
requires_action | processing | Customer completed the action. |
requires_action | failed | Action timed out / rejected. |
requires_action | canceled | Manual cancel. |
succeeded | refunded | Sum of refunds equals payment amount. |
succeeded | partially_refunded | Sum of refunds < payment amount, > 0. |
succeeded | charged_back | Provider notified of chargeback. |
charged_back | dispute_won (meta) | Dispute resolved in your favour. (status returns to succeeded.) |
charged_back | dispute_lost (meta) | Dispute resolved against you. |
Terminal: failed, canceled, refunded, dispute_lost (charged-back final).
Dunning cycle
active ──► retry_scheduled ──► awaiting_customer_action ──► resolved │ │ ▼ ▼ exhausted exhausted| From | To | Trigger |
|---|---|---|
active | retry_scheduled | Failed payment, next retry queued. |
retry_scheduled | awaiting_customer_action | Provider hint says step-up needed. |
awaiting_customer_action | retry_scheduled | Customer updated method. |
retry_scheduled | resolved | A retry succeeded. |
retry_scheduled | exhausted | Policy ran out. |
awaiting_customer_action | exhausted | Action window elapsed. |
Terminal: resolved, exhausted.
Common rejection problems
problem | When |
|---|---|
subscription.illegal_transition | Trying to cancel a canceled subscription, etc. |
subscription.commitment_active | Cancellation rejected because commitment forbids it. |
invoice.locked | Mutation attempted on a non-draft invoice. |
invoice.cannot_void_paid | Voiding an invoice with amount_paid > 0. |
payment.requires_action | Wraps the next-action contract, not strictly a rejection. |
payment.cannot_refund_failed | Refund attempted on a non-succeeded payment. |