Recurring Payments status lifecycles
Using Lean's Payment scheduler with Account-on-file for recurring payment use cases
This guide describes the lifecycle of a schedule, scheduled payments and an initiated payment : the status enums, what each status means, and how resources move between them.
There are two levels of state to track, from the plan down to individual executions:
| Resource | Enum | Where you see it |
|---|---|---|
| Schedule entity | ScheduleStatus | Create/list/get schedule responses, lifecycle action responses |
| Scheduled payment entity | ScheduledPaymentStatus | /schedules/v1/payments list and detail responses |
| AoF payment status events | status | payment.created and payment.updated web hook events |
- The schedule status gates everything: payments are only attempted while the schedule is
ACTIVE. - Each scheduled payment is an individual entity that progresses independently as its due date arrives; its terminal status is determined by the outcome of payment initiation attempts in relation to the scheduled payment entity .
- A
SUCCEEDEDscheduled payment attempt produces an initiated AoF payment, which then follows the standard payment status lifecycle and emits the standard payment.created and payment.updated events - When the final scheduled payment of a bounded schedule reaches a terminal state, the schedule itself moves to
COMPLETED.
Status changes at the payment level reach you via your existing AoF webhooks. To sync schedule-level and scheduled-payment-level state, re-fetch the schedule (
GET /schedules/v1/two levels of) or its payments (GET /schedules/v1/individual ex/payments) when you receive a related payment or consent event.
Schedule statuses
A schedule is the resource you register and link to an AUTHORISED Account-on-File consent. Its status controls whether payments are attempted on their due dates.
stateDiagram-v2
PENDING --> ACTIVE
ACTIVE --> PAUSED
PAUSED --> ACTIVE
ACTIVE --> COMPLETED
ACTIVE --> CANCELLED
PAUSED --> CANCELLED
PENDING --> CANCELLED
ACTIVE --> CONSENT_BLOCKED
PAUSED --> CONSENT_BLOCKED
PENDING --> CONSENT_BLOCKED
CONSENT_BLOCKED --> CANCELLED
| Status | Description | Terminal |
|---|---|---|
PENDING | The schedule has been registered but is not yet active. No payments are attempted. | No |
ACTIVE | The schedule is active. Payments are attempted on their due dates. | No |
PAUSED | The schedule is temporarily paused. No payments are attempted until it is resumed. | No |
CONSENT_BLOCKED | The underlying consent is no longer usable (for example revoked, suspended or expired). No payments are attempted. | No |
CANCELLED | The schedule was terminated — either by you via the cancel action, or due to the state of the underlying consent. No further payments will ever be attempted. | Yes |
COMPLETED | All planned payments have been executed. | Yes |
- Registration. A newly registered schedule starts in
PENDINGorACTIVE— read the status returned by the create call rather than assuming. - Pause and resume are client-driven. Only you can move a schedule between
ACTIVEandPAUSED, viaPOST /schedules/v1/{schedule_id}/pauseand/resume. Both accept an optional reason for your audit trail CONSENT_BLOCKEDis consent-driven, not client-driven. You cannot set or clear it through the Payment scheduler API — it reflects the state of the underlying AoF consent. Watchconsent.status.updatedwebhooks to know when this happens, then run a re-consent journey with the customer and register a new schedule against the new consent.- Use links, not assumptions. Every schedule response includes a links object in which cancel, pause and resume appear only when that action is currently available. Drive your UI and your API calls from these links instead of encoding the transition rules yourself.
Scheduled payment statuses
Each schedule entity is made up of individual scheduled payment entities — one per planned occurrence (a due date and an amount). Each moves through its own lifecycle as its due date approaches and execution runs. For each scheduled payment Lean will execute up to 5 reattempts if initial and successive payments fail. You will receive payment status web hook events for each reattempt that is performed.
As standard Lean performs reattempts every 3-5 minutes. However, if you have specific reattempt requirements please inform your Lean solutions engineer.
The scheduled payment entity status model has its own unique status model detailed in the state diagram below.
stateDiagram-v2
PLANNED --> SCHEDULED
SCHEDULED --> PROCESSING
PROCESSING --> COMPLETED
PROCESSING --> FAILED
PLANNED --> SKIPPED
SCHEDULED --> SKIPPED
SCHEDULED --> EXPIRED
PLANNED --> CANCELLED
SCHEDULED --> CANCELLED
| Status | Description | Terminal |
|---|---|---|
| PLANNED | The payment has been planned but has not yet been scheduled for execution. | No |
| SCHEDULED | The payment is scheduled and waiting to be attempted. | No |
| PROCESSING | The payment is currently being attempted. | No |
| COMPLETED | The payment completed successfully. | Yes |
| FAILED | The payment reached a failed terminal state. | Yes |
| SKIPPED | The payment was skipped and will not be attempted. | Yes |
| EXPIRED | The payment expired before completion. | Yes |
| CANCELLED | The payment was cancelled before completion (for example because the schedule was cancelled). | Yes |
- The happy path is
PLANNED→SCHEDULED→PROCESSING→COMPLETED. - Five terminal states. Once a scheduled payment reaches
COMPLETED,FAILED,SKIPPED,EXPIREDorCANCELLED, it never changes again. A failed occurrence is not re-created — handle recovery (retry, dunning, customer outreach) in your own flows. - In-flight payments and cancellation. We do not recommend cancelling a payment that is in
PROCESSINGbecause the payment may still complete at the bank. However if try you attempt to cancel a scheduled payment that is already inPROCESSINGafter cancelling, reconcile viaGET /schedules/v1/{schedule_id}/payments.
Account-on-file consent and payment statuses
A SUCCEEDED scheduled payment attempt produces an initiated AoF payment, which then follows the standard payment status lifecycle and emits the standard payment.created and payment.updated web hook events. Read our Payment status lifecycle guide for more details.
The underling consent Account-on-file consent relies on the same consent statuses and consent status web hooks. Read out Account-on-file consent status lifecycle guide for more details
Ensure that you implement web hook-driven state sync on payment.created / payment.updated, resolve the payment to its scheduled payment entity and update local status. Also ensure that you implement consent.status.updated handling for CONSENT_BLOCKED recovery (customer notification + re-consent journey).
| Event | When it fires | What to do |
|---|---|---|
payment.created | A scheduled payment attempt has initiated an AoF payment with the bank. | Record payload.id as the payment_id; match it to the scheduled payment via the attempts endpoint. |
payment.updated | The payment's status changed (e.g. reached a terminal state at the bank). | Update your ledger; on terminal failure, check the attempt's failure_reason and trigger your dunning flow. |
consent.status.updated | The underlying consent changed state (e.g. AUTHORISED, SUSPENDED, REVOKED, EXPIRED). | If the consent is no longer usable, expect affected schedules to move to CONSENT_BLOCKED. Notify the customer and start a re-consent journey; register a new schedule once a new consent is authorized. |
