Guide
duplicate_transaction on Stripe: check your records before you do anything
Last updated 13 August 2026 · written by Bruce McGinley, who builds RecoverFlow
The same charge may already exist. Stripe's decline codes reference documents duplicate_transaction as a transaction with identical amount and credit card information submitted very recently.
It is the rare decline code whose documented next step points at you rather than the customer: check to see if a recent payment already exists.
That makes the first move unambiguous. Before retrying anything and before emailing anyone, look at your own recent payments for this customer.
On this page
The first move is a lookup, not an email
Most decline codes route you toward the customer or their issuer. This one routes you to your own Dashboard, because the two possible situations call for opposite responses.
If a recent identical payment exists and succeeded, there is nothing to recover. The customer has paid. A dunning email here is worse than useless: you would be asking someone to fix a payment that went through, and if they follow your link and pay again you have created the double charge the decline was flagging.
If no successful payment exists, then the duplicate the issuer saw did not settle into anything, and the charge still needs to happen. The documented description says the collision is with something submitted very recently, so the next attempt is not fighting the same condition.
How you end up here
The documented description is a transaction with identical amount and credit card information submitted very recently. The common routes to that situation are mundane: a double click on a pay button, a client that retried a request after a timeout while the first attempt was still in flight, or an integration that retries failures faster than the earlier attempt clears.
Those are our observations rather than Stripe's, but they follow directly from what the code describes. If you see this code with any regularity, the place to look is wherever your integration can submit the same charge twice in quick succession, including idempotency handling on your payment calls.
Where retries fit
duplicate_transaction is not one of the nine codes that stop Stripe executing retries, so a scheduled retry will run. The description is explicitly about the very recent past, a collision in a moment, rather than a property of the card, which is a shape that a retry days later does not collide with.
The caution is entirely on the other side: confirm no successful payment exists before any deliberate reattempt, manual or scheduled. That check, per the documentation, is the whole point of the code.
Questions people actually ask
Is duplicate_transaction a hard decline?
No. It is not on Stripe's list of nine codes that stop retry execution. The documented condition is a collision with an identical transaction submitted very recently, which is about that moment rather than the card.
Did my customer get charged twice?
The decline itself means this attempt was declined, so this attempt did not charge them. What Stripe's documented next step asks you to check is the other side: whether a recent identical payment already exists and succeeded. If it did, the customer has paid once, and nothing further is owed.
Should I email the customer about a duplicate_transaction decline?
Not before checking your records. If a recent identical payment succeeded, an email asking them to update or retry risks producing a genuine double charge. If nothing succeeded, handle it like a normal failed payment.
How do I stop duplicate_transaction declines from happening?
The code describes identical charges submitted in quick succession, so review wherever your integration can send the same charge twice: double submissions at checkout and automatic request retries are the usual suspects, and idempotency keys on payment requests are the standard guard.
Where this came from
Checked against primary sources on 13 August 2026. If Stripe changes something and this page has not caught up, tell us and it gets fixed.
- Stripe: Decline codes reference — the documented meaning and next steps for every code on this page.
- Stripe: Smart Retries — the source for the nine hard decline codes and what happens to scheduled retries after one.
If you would rather not build this yourself
RecoverFlow watches your Stripe account for failed subscription payments, stops retrying the ones that cannot succeed, and emails the customers whose card simply needs replacing. It charges 25% of what it can attribute to a specific action it took, with a $29 monthly floor and a $299 monthly ceiling, and the floor is waived for the first 30 days.
It is early. It is run by one person. If Stripe's own free retry settings are enough for you, use those instead, and there is a page on this site that says exactly when that is the right call.
See how the pricing works
Recover