Retry Engine Overview
Automatically retry failed recurring payments and recover lost revenue.
When a recurring payment fails to collect, the Retry Engine is the solution that automatically recovers.
Revenue that would otherwise be lost due to expired cards, temporary declines, or insufficient funds can be recovered without any manual intervention.
This page describes the routes by which a failed payment reaches the Retry Engine, and what the Retry Engine does once it arrives: the recovery strategies you can apply, the recovery lifecycle, and how to retrieve and manage recoveries.
How a payment reaches the Retry Engine
There are two routes for sending a failed recurring payment to the Retry Engine. Both create the same payment recovery object, and everything described on the rest of this page — retry advice, recovery strategies, the lifecycle, and management — applies to every recovery, whatever its route.
| Route | Best for | How the recovery is created |
|---|---|---|
| Acquired Billing | Subscriptions billed by Acquired Billing | Automatically, when a bill payment fails on a subscription enrolled with a recovery_strategy. |
| Standalone Retry Engine | Recurring card payments processed through Acquired outside Acquired Billing, including those scheduled by your own billing system | By you, when you send the declined payment to POST /payment_recoveries. |
Route 1: Acquired Billing
If you bill your customers with Acquired Billing, recovery is built in. Enrol a subscription by setting recovery_strategy on its payment_failure_configuration, and Acquired creates a payment recovery automatically whenever one of its bills fails to collect. The bill and subscription statuses then follow the outcome of the recovery.
See Recovering subscription payments for how to enrol a subscription and what happens when its bills fail.
Route 2: Standalone Retry Engine
The Standalone Retry Engine opens recovery up to any recurring card transaction in the Acquired system — not only those created by Acquired Billing. If you run your own subscription or billing logic and process recurring card payments through Acquired, you can still hand failed payments to the Retry Engine.
A transaction can be sent to the Retry Engine when it:
- is a recurring transaction
- has a status of
declined - is not a subscription bill payment — these are recovered through Route 1
- is not already part of a payment recovery — a retry attempt made by the Retry Engine belongs to a recovery that is already working through a recovery strategy, so it can't be sent to the Retry Engine again
Identifying subscription payments and Retry Engine retriesTransactions taken by Acquired Billing or the Retry Engine carry an identifier in the
GET /transactions/{transaction_id}response, and the same identifiers in the Webhook-Version 2status_updatewebhook body:
subscription_idorbill_idpresent (withoutrecovery_id) — the transaction is a subscription bill payment, recovered through Route 1.recovery_idpresent — the transaction is a Retry Engine retry and can't be sent to the Retry Engine.- None of these present — the transaction was not taken by Acquired Billing or the Retry Engine.
-
Process a recurring payment as normal — for example, with
POST /payments/recurring. -
The payment is declined. Check that the transaction's
statusisdeclined, and check theretry_advicereturned in the response to confirm the payment can be retried — see Retry Advice. -
Send the failed payment to the Retry Engine with
POST /payment_recoveries, supplying the declined transaction'stransaction_idandorder_id, and therecovery_strategyto apply. Acquired looks up the original transaction and takes the amount, currency, customer and stored card from it.{ "order_id": "order-100245", "transaction_id": "0b6b5a6e-3f0e-4c47-9c2f-1d7e8a4b2c91", "recovery_strategy": "example_strategy" }A successful request returns
201 Createdwith the new payment recovery in the body. The recovery'sorder_idis theorder_idyou supplied.next_action_scheduled_dateisnullin this response because the first retry is scheduled just after the recovery is created — retrieve the recovery to see it. -
The Retry Engine takes over, retrying the payment exactly as described on this page. Track it with the
recovery_id, and cancel it or mark it recovered if the payment is settled another way.
Because you choose which failed payments to submit, the standalone route lets you decide recovery on a payment-by-payment basis, while your own system remains the source of truth for the customer's subscription or account status.
Each transaction can have at most one recovery, and each order_id at most one recovery on your account. A second request for the same transaction or order_id returns 409 Conflict. A request for a transaction that isn't eligible, or with an unrecognised recovery_strategy, returns 400 Bad Request. none is not accepted as a strategy.
Only declined payments with retry advice that allows a retry can be recoveredThe recovery gate applies from the very first request. A payment whose
retry_adviceis do not retry will not be recovered, so check the advice before sending it to the Retry Engine. See Retry Advice for the advice categories and what each one means.
How the Retry Engine works
- A failed recurring payment is sent to the Retry Engine, either automatically from Acquired Billing or via
POST /payment_recoveries. Acquired creates a payment recovery for it and begins working through the assigned recovery strategy. - Acquired retries the payment according to the strategy's schedule. Each recovery attempt's
order_idmatches the original payment being recovered. The recovery stays in therecoveringstatus while this is in progress. - The recovery ends when a retry succeeds (
recovered), when the strategy gives up (unrecovered), or when it is cancelled via the API (cancelled).
Retry Advice: the recovery gate
Before any schedule is considered, the Retry Engine first checks whether the failed payment should be retried at all.
Every failed card payment returns a retry_advice object in the API response — see Retry Advice for how it works and the advice categories returned. The advice category indicates whether— and when — it is worth trying the card again. This advice is the gate that decides whether a recovery can begin or continue:
- Retry later — a temporary decline (for example, insufficient funds). Recovery is allowed to proceed.
- Do not retry — the decline is effectively permanent for this card (for example, a blocked or closed card). The gate closes: the recovery stops immediately with
advice_do_not_retry, rather than wasting attempts and risking penalties.
Retry advice is re-evaluated on every attempt, not just the first. A recovery that is mid-schedule will stop the moment an attempt comes back as do-not-retry, even if scheduled retries remain. Only once this gate is open does the assigned strategy decide how and when the payment retries happen.
Recovery strategies
A recovery strategy is a named schedule that determines how and when a failed payment is retried. The flexibility is in when each retry fires. The Retry Engine supports any strategy your business needs to effectively recover failed payments.
- Fixed delays — wait a set period after the previous attempt (for example, retry one day later).
- Calendar windows — retry only at specific times or on specific days (for example, the next Tuesday or Friday morning, or the last working day of the month). This lets you target times when funds are more likely to be available, such as just after typical pay days.
- Retry advice timing — when
retry_adviceindicates a decline should be retried after a particular time, the schedule respects that time. This timing advice is abstracted from Mastercard's Merchant Advice Codes (MAC), which provide granular guidance including specific retry timing windows (e.g. retry after 1 hour, after 24 hours, after 2 days, up to 10 days).
When more than one applies, recovery uses the most informed signal: retry advice timing first, then any configured calendar window, then the fixed delay as a fallback.
Retries are measured from the attempt, not from "now"Each wait is calculated from when the previous attempt actually completed, so if a retry is delayed for operational reasons the intended gap between attempts is still honoured rather than compounded.
Protected dates
A strategy can be configured to avoid certain dates — for example weekends or public holidays such as Christmas Day. If a retry would land on a protected date, it is moved forward to the next allowed day.
Built-in safety limits
Every recovery is bounded so it can never run indefinitely:
- Maximum attempts — once the maximum number of retry attempts allowed for the recovery is reached, the recovery ends with
max_retries_exceeded. - Scheme retry caps — card schemes also impose their own limits on how many times a payment may be retried within a window. If a scheme's cap is reached before the next retry, the recovery ends with
retry_limit_reachedwithout attempting that retry. - Maximum age — a recovery running longer than the maximum age ends with
payment_too_old.
Recovery strategiesThe set of strategies available to you — and their names, such as
example_strategy— is provided as part of your onboarding. Use the exact name supplied to you.
The recovery lifecycle
Every payment recovery has a status describing where it is in its lifecycle:
| Status | Description |
|---|---|
recovering | The recovery is in progress. Acquired is retrying the payment according to the strategy's schedule. |
recovered | The payment was successfully collected, or marked as settled externally. This is a terminal status. |
unrecovered | The recovery ended without collecting the payment — the strategy was exhausted or otherwise terminated. This is a terminal status. |
cancelled | The recovery was cancelled via the API before it completed. This is a terminal status. |
When a recovery reaches a terminal status, the termination_reason field explains why it ended:
| Termination reason | Description |
|---|---|
payment_successful | A retry succeeded and the payment was collected. |
end_of_strategy | The strategy ran to completion without a successful payment. |
max_retries_exceeded | The maximum number of retry attempts allowed by the strategy was reached. |
retry_limit_reached | A card-scheme retry cap for the payment was reached, so no further retries were allowed. |
payment_too_old | The original failed payment aged past the maximum window allowed for recovery. |
advice_do_not_retry | The payment gateway advised that the payment should not be retried. |
recovery_cancelled | The recovery was cancelled via the API. |
recovery_settled_externally | The recovery was marked as recovered via the API after the payment was settled elsewhere. |
internal_error | The recovery was terminated because of an unexpected internal error. |
While a recovery is still in progress, termination_reason is null.
Retrieving and managing recoveries
| Action | Endpoint | Notes |
|---|---|---|
| Create | POST /payment_recoveries | Sends a declined recurring card payment to the Retry Engine — see Route 2: Standalone Retry Engine. |
| List | GET /payment_recoveries | Returns a paginated list. Supports filtering by customer_id, status, and order_id. |
| Retrieve one | GET /payment_recoveries/{recovery_id} | Looked up by the recovery's own ID. |
| Cancel | POST /payment_recoveries/{recovery_id}/cancel | Stops an in-progress recovery. It transitions to cancelled (recovery_cancelled). |
| Mark recovered | POST /payment_recoveries/{recovery_id}/recovered | Use when the payment was settled outside the recovery pipeline. It transitions to recovered (recovery_settled_externally). |
Cancel and mark-recovered are only valid while the recovery is in the recovering status; calling them on a terminal recovery returns an error.
Example recovery object:
{
"id": "01JE3X4Y5Z6A7B8C9D0E1F2G3H",
"order_id": "01HNY4G8G8P4E1T4YJ9N8B1Z9M",
"customer_id": "c3e06b6f-bb52-4b2c-81a3-899860652240",
"status": "recovering",
"amount": 19.99,
"currency": "GBP",
"recovery_strategy": "example_strategy",
"termination_reason": null,
"created_at": "2025-11-17T17:00:00Z",
"next_action_scheduled_date": "2025-11-20T09:00:00Z",
"payment_retry_attempt_count": 1,
"links": [
{
"rel": "self",
"href": "/v1/payment_recoveries/01JE3X4Y5Z6A7B8C9D0E1F2G3H"
}
]
}order_ididentifies the original failed payment this recovery relates to.next_action_scheduled_dateis when the next retry is scheduled. It isnullwhen the recovery is not in therecoveringstatus or no retry is currently scheduled.payment_retry_attempt_countis the number of retry attempts made so far.amountis returned in major currency units (e.g.19.99).
Updated 10 days ago