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.

RouteBest forHow the recovery is created
Acquired BillingSubscriptions billed by Acquired BillingAutomatically, when a bill payment fails on a subscription enrolled with a recovery_strategy.
Standalone Retry EngineRecurring card payments processed through Acquired outside Acquired Billing, including those scheduled by your own billing systemBy 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 retries

Transactions 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 2 status_update webhook body:

  • subscription_id or bill_id present (without recovery_id) — the transaction is a subscription bill payment, recovered through Route 1.
  • recovery_id present — 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.
  1. Process a recurring payment as normal — for example, with POST /payments/recurring.

  2. The payment is declined. Check that the transaction's status is declined, and check the retry_advice returned in the response to confirm the payment can be retried — see Retry Advice.

  3. Send the failed payment to the Retry Engine with POST /payment_recoveries, supplying the declined transaction's transaction_id and order_id, and the recovery_strategy to 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 Created with the new payment recovery in the body. The recovery's order_id is the order_id you supplied. next_action_scheduled_date is null in this response because the first retry is scheduled just after the recovery is created — retrieve the recovery to see it.

  4. 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 recovered

The recovery gate applies from the very first request. A payment whose retry_advice is 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

  1. 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.
  2. Acquired retries the payment according to the strategy's schedule. Each recovery attempt's order_id matches the original payment being recovered. The recovery stays in the recovering status while this is in progress.
  3. 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_advice indicates 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_reached without attempting that retry.
  • Maximum age — a recovery running longer than the maximum age ends with payment_too_old.
📘

Recovery strategies

The 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:

StatusDescription
recoveringThe recovery is in progress. Acquired is retrying the payment according to the strategy's schedule.
recoveredThe payment was successfully collected, or marked as settled externally. This is a terminal status.
unrecoveredThe recovery ended without collecting the payment — the strategy was exhausted or otherwise terminated. This is a terminal status.
cancelledThe 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 reasonDescription
payment_successfulA retry succeeded and the payment was collected.
end_of_strategyThe strategy ran to completion without a successful payment.
max_retries_exceededThe maximum number of retry attempts allowed by the strategy was reached.
retry_limit_reachedA card-scheme retry cap for the payment was reached, so no further retries were allowed.
payment_too_oldThe original failed payment aged past the maximum window allowed for recovery.
advice_do_not_retryThe payment gateway advised that the payment should not be retried.
recovery_cancelledThe recovery was cancelled via the API.
recovery_settled_externallyThe recovery was marked as recovered via the API after the payment was settled elsewhere.
internal_errorThe recovery was terminated because of an unexpected internal error.

While a recovery is still in progress, termination_reason is null.


Retrieving and managing recoveries

ActionEndpointNotes
CreatePOST /payment_recoveriesSends a declined recurring card payment to the Retry Engine — see Route 2: Standalone Retry Engine.
ListGET /payment_recoveriesReturns a paginated list. Supports filtering by customer_id, status, and order_id.
Retrieve oneGET /payment_recoveries/{recovery_id}Looked up by the recovery's own ID.
CancelPOST /payment_recoveries/{recovery_id}/cancelStops an in-progress recovery. It transitions to cancelled (recovery_cancelled).
Mark recoveredPOST /payment_recoveries/{recovery_id}/recoveredUse 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_id identifies the original failed payment this recovery relates to.
  • next_action_scheduled_date is when the next retry is scheduled. It is null when the recovery is not in the recovering status or no retry is currently scheduled.
  • payment_retry_attempt_count is the number of retry attempts made so far.
  • amount is returned in major currency units (e.g. 19.99).

Did this page help you?