Subscription statuses
A subscription moves through a defined set of statuses across its lifecycle. The status drives what your frontend shows, what API operations are allowed, and which webhooks fire.
Status values
| Status | Meaning |
|---|---|
pending | Subscription created, first payment not yet completed. The customer completes the first payment on the hosted payment form before the subscription becomes active. |
active | Subscription is running normally. Renewals charge on schedule against the active payment instrument. |
trial-ended | The trial period has finished. Transitions to active once the first paid renewal succeeds. |
paused | Subscription is temporarily paused. No renewals are charged until the pause is resumed. See Subscription pauses. |
unpaid | A renewal payment has failed and dunning is in progress. Further retries follow the configured schedule — see Dunning and retries. |
suspended | Subscription is administratively suspended (for example, on risk review). |
canceled | Subscription has been canceled. See Subscription cancellations. |
churned | Subscription has ended after the paid period expired without further renewal. |
completed | Subscription reached its planned end (for example, a fixed number of cycles defined by recurringInterval.limit). |
voided | Subscription was voided before it ever became active. |
abandoned | Subscription was abandoned without ever reaching active. |
connected | Subscription is connected but not yet started. |
pending — the first-subscription case
Most integrators see pending for the first time when they create a subscription with a new payment instrument. The instrument is inactive — PaymentsAI does not auto-charge inactive instruments. The create response includes a recentInvoicePaymentFormUrl and the subscription stays in pending until the customer completes the first payment on the hosted form.
Two consequences for your code:
- Frontend:
pendingmust be in the set of statuses that trigger a redirect to the hosted payment form. A frontend that only checksstatus === 'waiting'(the 3DS transaction status) misses this case. - Backend: read
recentInvoicePaymentFormUrlfrom the response and pass it to the frontend as the redirect URL.
See Create a subscription for the flow and code snippets, and Hosted payment form for what happens on the form itself.
State transitions
What the frontend should show
| Status | Recommended UI |
|---|---|
pending | Redirect to recentInvoicePaymentFormUrl. After return, poll the subscription. |
active, trial-ended | Normal subscription view: next renewal date, manage button. |
paused | Paused badge, "Resume" action. |
unpaid | "Payment failed" message with retry-status indicator. Surface link to update the payment instrument. |
canceled (recent) | "Canceled" view with "Reactivate" action if applicable. |
canceled (older), churned, completed, voided, abandoned | Read-only history view. |
suspended | "On review" message; suggest contacting support. |