A retry is the most dangerous button in a money transfer business. Pressed at the wrong moment, it charges a customer twice or pays a recipient twice, and the second payment is often far harder to get back than the first was to send.
This guide is for operations leads, finance teams and CTOs who decide when a failed payment or payout may be tried again. It covers how to sort failures, how to make repeated requests harmless, what to do when you simply do not know whether something went through, how long to keep trying, who decides, and what to tell the customer.
Sort the failure before anyone retries
"Failed" covers several very different situations. The first job is to decide which one you are in, because each has a different safe response.
- Definite refusal. The bank, card issuer or payout partner answered clearly and said no: insufficient funds, card declined, account closed. Nothing moved. A new attempt is safe, but repeating the identical request will usually fail the same way.
- Temporary refusal. The other side answered but could not act now: rate limit, maintenance, a service briefly unavailable. Nothing moved, and the same request is likely to work later.
- Unknown outcome. You sent the request and never got a usable answer: a timeout, a dropped connection, a response you could not read. The other side may have acted. This is the case that causes duplicates.
- Fault on your side before sending. A background job crashed or a configuration was missing, and the request never left your platform. Retrying is safe once the cause is fixed.
Payments (money coming in from the customer) and payouts (money going out to the recipient) fail in the same ways, but the cost of getting it wrong differs. A duplicate payment can be refunded from money you hold. A duplicate payout has left the building, and getting it back depends on a partner and a recipient who may not cooperate.
The rule: never treat "no answer" as "no". A timeout tells you about your connection, not about the other side's decision. Until you know what happened, the safe state is "unknown", and unknown is not retryable.
Make every money action safe to repeat
The defence is idempotency, which means repeating the same logical request produces the same result rather than a second effect.
- One reference per logical action. Give each payment attempt and each payout a unique reference, and send the same reference every time you retry that action. If the partner supports a client reference, use it consistently; many partners reject a reference they have already seen, which turns a dangerous duplicate into a harmless error.
- A new attempt is a new decision. If the customer pays again with a different card, that is a new payment attempt with a new reference, and it should only be created after you have checked that no earlier attempt on the same transfer is still pending, authorised or captured.
- One worker per payout. When several processes pick up work from a queue, two of them can grab the same payout at the same moment. Claiming must be atomic: the first process takes it and the second sees it is gone.
- Look at the whole transfer, not the last attempt. A transfer may have three payment attempts: one failed, one cancelled, one captured. The question before any retry is "has any attempt on this transfer already taken money?", not "did the latest one fail?".
For the state model behind this, see why payment state management is critical in remittance software and how to prevent duplicate payments.
When you don't know the outcome, ask before you retry
The unknown outcome is where most double payments come from, because it looks exactly like a failure on your screen. Handle it as its own state with its own procedure.
- Freeze the item. Mark the payment or payout as awaiting confirmation. Do not let the customer, a scheduler or a member of staff create a replacement.
- Find out what was actually sent. Pull the raw request and response from your outbound API log: the time, the status code (if any), the error and the correlation ID. This tells you whether the request left your platform at all.
- Ask the other side. For payments, query the gateway's status for that attempt. For payouts, use the partner's status lookup by your reference, or contact their support with the reference and timestamp.
- Act on the answer. Received and processing: wait. Received and paid: mark it sent and move on. Never received: now it is safe to retry, with the same reference. No answer from the partner either: escalate, and keep the item frozen.
Good alerts do the sorting for you. An alert that says only "payout failed" sends someone to the logs. An alert that says whose side the fault was on, and whether the partner must be asked before retrying because you never learned if they accepted it, tells the person on shift what to do next.
Back off, then hand over to a person
Automatic retries suit temporary refusals and pending payments that are likely to resolve on their own. They need two limits: how often, and when to stop.
- Space retries out. Check often at first, when a change is most likely, then less often. An illustrative schedule for a pending card payment: 1, 2, 5, 10, 20 and 30 minutes after the attempt.
- Set an expiry. A payment that is still pending after the gateway's own expiry window should be closed as expired, and the customer told plainly. Leaving it pending for days is how late captures on abandoned transfers happen.
- Know when the machine gives up. When the poller reaches its limit, the item must land in front of a person, not sit in a pending state nobody watches.
For payouts, retry automatically only temporary refusals the partner clearly did not accept. For anything else, a person looks first. If doubt arises about a payout the partner already holds, agree a hold with the partner and record it with a written reason while someone decides; cancelling or reversing are harder to undo.
Fix payouts without editing them
A common failure is a partner rejecting a payout for bad recipient details: a wrong account number, or a name that does not match the account. The tempting fix is to correct the details on the payout and press retry. Don't.
If details can change after approval, the approval covered something other than what was paid, and a retry becomes a quiet way to redirect money. An approved payout should be locked: what goes out is exactly what was approved. How you fix it depends on why it did not go through.
- The partner refused it. This is a definite answer, and the only case in which the customer should be told the payout failed. Leave the refused payout on the record as it is. Confirm the correct details with the customer through a channel you trust, then send the money under a fresh approval, by someone other than the person who took the new details, and treat those details as new: they go through your normal checks.
- A fault on your side stopped it. A crashed job or a missing setting is not a failure the customer needs to hear about. The payout should sit in an error state for your team to fix the cause and resend it exactly as approved; the customer is not told it failed, because from their side nothing has gone wrong yet.
- The partner may already hold it. If the request may have reached the partner, nothing is resent until an operator has confirmed with the partner that it was never received. This is the unknown outcome from section 03, and it is where duplicate payouts come from.
- It needs stopping while the partner holds it. Most partner connections offer no way to stop a payout once it has been handed over. If doubt arises, phone the partner, agree a hold, and record that hold on the payout by hand with a written reason, so the next person on shift sees why it is waiting.
Decide in advance who may retry what
Retry decisions made in the moment, under customer pressure, are the ones that go wrong. Write the rules down first, and adapt this table to your own partners and team.
| Failure type | Safe to retry? | Precondition | Who |
|---|---|---|---|
| Payment declined by bank or card issuer | Yes, as a new attempt | No other attempt on the transfer is pending, authorised or captured | Customer, from the app |
| Payment timed out, no answer from gateway | Not yet | Gateway status checked and the attempt confirmed as not taken | System (polling); operations if polling gives up |
| Payment marked failed, then success arrives | No | Reconcile the late success to the transfer; check for a second payment | Operations, then finance |
| Second payment captured on one transfer | No; refund one | Confirm which payment the transfer uses; refund the other with a reason | Finance, approved by a second person |
| Payout rejected for bad recipient details | Not as-is | Refused payout left on the record unedited; correct details confirmed with customer; money sent again only under a fresh approval | Operations creates, a different person approves |
| Payout: temporary error from partner | Yes, with backoff | Partner clearly did not accept; same reference used | System, then operations after the retry limit |
| Payout: fault on our side, request never sent | Yes | Cause fixed; log shows the request never left the platform | Operations or technology |
| Payout: fault on our side, outcome unknown | Not until confirmed | Partner asked and confirms it never received the instruction | Operations lead |
| Payout accepted by partner but overdue | No | Chase the partner by reference; if it must be stopped, agree a hold with the partner and record it with a reason | Operations |
| Incoming partner message failed to process | Yes, replay it | Message saved; check its effect was not already applied | Technology |
Two principles sit behind the table. First, the further money has travelled, the more senior the decision: a customer can retry a declined card, but only an operations lead releases a payout whose outcome was unknown. Second, retries never bypass controls. A retried transfer is still screened, still within limits and still approved as before.
Catch the duplicates that get through anyway
Some duplicates will get through. The goal is to know within minutes, not at month end.
- Duplicate payment captured. Two payments taken for one transfer. Refund one, record the reason, and check the ledger shows both the payment and the refund.
- Payment received on a closed attempt. A provider reports money for an attempt you marked failed or cancelled. Do not ignore it because your record says closed. The money is real; decide whether it completes the transfer or is refunded.
Refunds of duplicates should not be automatic. A second capture may coincide with a pending chargeback or a partial refund, and an automatic refund can leave you paying back money twice. A person reviews the context, then refunds with a recorded reason. For the reconciliation side, see payment reconciliation for cross-border money transfers.
Tell the customer the truth about the state
Most duplicate payments start with a message that said "failed" when the truth was "we're checking". Match the message to the state you are actually in.
- Definite decline: "Your bank declined this payment. You can try again with another card or by bank transfer."
- Unknown or pending: "We're confirming your payment with your bank. Please don't pay again; we'll update you shortly." Hide the retry button until the state is resolved.
- Payout rejected for details: "The recipient's bank couldn't accept these details. Please check the account number." Ask for corrected details; never invite the customer to send a new transfer while the first is unresolved.
- Duplicate refunded: "You were charged twice. We've refunded one payment; it may take a few days to appear." Say it before they notice.
A worked scenario: one transfer, three retry decisions
The figures below are illustrative. A customer sends £400 by card to a recipient's bank account on a Saturday morning.
- 09:02, payment timeout. The gateway does not answer within 30 seconds. The app shows "We're confirming your payment" and hides the retry option. The poller checks at 1 and 2 minutes: pending.
- 09:05, a second payment. Impatient, the customer opens the web app on a laptop and pays £400 again, as a new attempt on the same transfer. Your platform should have refused this while the first was unresolved; this operator's web flow did not.
- 09:07, both captured. The poller's 5-minute check finds the first payment captured. The gateway confirms the second as well. A "Duplicate payment captured" alert reaches finance. The transfer proceeds on the first payment.
- 09:08, payout unknown. The payout to the partner is sent; the connection drops before the reply. The alert "Payout not sent because of a fault on our side" says the fault was yours and that the partner must be asked before retrying, because you never learned whether they accepted it.
- 09:20, ask first. The operations lead checks the outbound API log: the request left, no response came back. They query the partner by reference. The partner has no record of it.
- 09:25, safe retry. The payout is retried exactly as approved, with the same reference. The partner accepts it.
- 10:15, refund. Finance reviews the second £400, confirms no chargeback is open, and refunds it with the reason "duplicate payment". The customer gets a message before they contact support.
What the scenario shows: the dangerous moments were the two "unknowns", not the outright failures. The payout was retried only after the partner confirmed it had nothing, and the duplicate was caught in minutes because an alert named it. The fix for next time is upstream: block a new payment attempt while an earlier one is unresolved.
Doing it with RemitSo
RemitSo's admin panel gives your team the records, alerts and safeguards that make retry decisions safe. See the admin features.
- Plain-language payout alerts: "Payout not sent because of a fault on our side" names whose side the fault was on and whether the partner must be asked before retrying, so the person on shift knows the next step.
- Payouts locked once approved: what goes out is exactly what was approved and an approved payout is never edited, so a retry cannot redirect money.
- Errors sorted by who is at fault: customers are told a payout failed only when the partner refused it. A fault on the platform's side or a missing setting leaves the payout in Error for your team to resend, without telling the customer it failed, and a payout the partner may already hold is never resent without an operator confirming.
- Atomic claiming of payouts (August 2026 release): one payout is picked up by one process, so a busy queue cannot send it twice.
- "Duplicate payment captured" and "Payment received on closed attempt" alerts, sent to the subscribers you choose: duplicates surface in minutes, not at month end.
- Rebuilt payment polling with reconciliation and expiry handling: pending payments are checked with the gateway and closed properly when they expire.
- Holds recorded on the payout: no partner connection carries a stop request yet, so there is no stop button in the console; a hold agreed with the partner by phone is recorded on the payout by hand, with a required reason that is kept.
- Every payout chased on a schedule that fits it, so a payout nobody answers about reaches an operator instead of waiting in a pending state.
- Outbound API and webhook logs: every call to a payment, payout or identity provider is on the record, with its raw request, response, status and error, keys masked; every incoming message saved before processing, so a failed one can be replayed in one click.
- Failed background jobs, listed in system utilities for review and retry, so a fault on your side does not stay hidden.
- Scout, every 5 minutes: payouts needing action and payments needing action (provider not answered, poller gave up, refunds that failed) in one place.
Customers can also retry a failed payment in the app without starting the transfer again (customer app features). Your team still writes the retry rules, contacts partners when an outcome is unknown, and approves refunds and re-created payouts.
Read the release notes, or book a demo to walk through a failed payout from alert to resolution. For the partner side, see handling payout partner failures with API and webhook logs.
Frequently asked questions
Is it ever safe to retry a payout automatically?
Yes, when the partner clearly refused the instruction for a temporary reason, such as a rate limit or maintenance, and you resend with the same reference. If the outcome is unknown, a person should confirm with the partner first.
What is the difference between a retry and a new attempt?
A retry resends the same action with the same reference, so the other side can recognise it. A new attempt is a fresh action, such as paying with a different card, and is only safe once you know no earlier attempt on the transfer has taken money.
Should duplicate payments be refunded automatically?
No. A duplicate may overlap with a chargeback or partial refund. Have a person review the context, refund with a recorded reason, and check the accounts show both the payment and the refund.
How long should we keep polling a pending payment?
Until the gateway's own expiry for that payment method, with checks spaced further apart over time. After that, close the attempt as expired and tell the customer. If polling gives up early, the item should land in a person's queue.