Stripe Decline Code · Glossary
duplicate_transaction fires when Stripe or the issuing bank detects that an identical charge — same card, same amount, same merchant — has already been successfully processed within a short time window, and blocks the second attempt as a protective measure against accidental double-billing.
What It Means
What It Means
duplicate_transaction fires when Stripe or the issuing bank detects that an identical charge — same card, same amount, same merchant — has already been successfully processed within a short time window, and blocks the second attempt as a protective measure against accidental double-billing. Unlike almost every other decline code which signals a payment problem, duplicate_transaction is a safeguard, not a failure — it means the original payment very likely went through, and the second attempt was correctly stopped.
Not sure if this code is recoverable for your specific situation? Use the Stripe Failure Lookup →
Why It Happens
Why It Happens
What NOT to Do
What NOT to Do
✕ Don't treat it as a payment failure and trigger dunning
duplicate_transaction almost always means the original charge succeeded — firing a "your payment failed" dunning email to a customer whose card was correctly charged creates confusion, destroys trust, and drives unnecessary support tickets and refund requests. Always verify the original charge status in your Stripe dashboard before any customer-facing action.
✕ Don't immediately retry the blocked duplicate
The duplicate detection window at most issuers runs 10–30 minutes. Retrying within that window produces the same duplicate_transaction block. More critically, if you retry without first checking whether the original charge succeeded, you risk actually double-charging a customer — an error that generates chargebacks, refund requests, and irreparable trust damage.
✕ Don't ignore it as a harmless false alarm
While duplicate_transaction is a protective block, its frequency in your Stripe logs is a code health signal — consistent occurrences indicate your billing architecture has a race condition, missing idempotency key implementation, or a broken webhook handler that needs engineering attention. Normalizing it as background noise leads to compounding billing integrity issues.
Retry Timing
Retry Timing
duplicate_transaction has no retry timing in the traditional sense — the recovery path is entirely a diagnostic and engineering response, not a payment retry schedule.
Recovery Benchmark
Recovery Benchmark
| Metric | Result |
|---|---|
| Original charge already succeeded (most common) | ~70–80% of all occurrences |
| Both charges failed — genuine billing error | ~15–20% of occurrences |
| Customer actually double-charged | ~5–10% of occurrences |
| Recovery with idempotency key implementation | Eliminates ~80% of future occurrences |
| Engineering fix time to resolution | Typically 1–3 days once identified |
| Chargeback risk if double-charge not proactively refunded | 40–60% escalation rate |
Zero duplicate_transaction occurrences in your Stripe logs. This is the one decline code where the recovery rate benchmark is irrelevant — the only meaningful KPI is occurrence rate reduction through engineering. A properly implemented idempotency key system reduces occurrences to near-zero. If you're seeing this code more than once per billing cycle, it's a billing architecture issue, not a payment problem.
At Scale
At Scale
Automated
Manual Escalation
FAQs
FAQs
What does the Stripe duplicate_transaction decline code mean?
duplicate_transaction means Stripe or the issuing bank detected that an identical charge — same card, same amount, same merchant — was already processed or attempted within a short time window, and blocked the second attempt as a protective measure. In most cases, the original charge succeeded and no customer action is needed. Always verify the original charge status before taking any action.
What are the most common causes of a duplicate_transaction error in Stripe?
Common causes include a webhook retry loop firing a second charge without checking whether the original succeeded, a customer double-clicking the pay button at checkout, a race condition between concurrent billing processes, a manual retry fired too quickly after an automatic attempt, and missing or incorrectly reused idempotency keys in Stripe API charge calls.
Does duplicate_transaction mean my customer's payment failed?
Not necessarily. In 70–80% of cases, the original charge succeeded and the duplicate_transaction code is blocking a second, redundant attempt. Always query the original charge status in the Stripe API before triggering any customer notification or retry logic. Sending a payment failure email to a customer whose original payment succeeded is damaging to trust and drives unnecessary refund requests.
How do I prevent duplicate_transaction errors in Stripe?
Implement unique idempotency keys on every Stripe charge API call — tied to the specific invoice ID and billing cycle date. Add webhook event deduplication using Stripe event IDs to prevent reprocessing. Disable checkout pay buttons on first click to prevent double submissions. Implement a race condition guard in your billing code so concurrent processes cannot fire simultaneous charge attempts for the same invoice.
What should I do if a customer was double-charged due to a duplicate_transaction error?
Issue a proactive refund and send a personal apology email within 2 hours — before the customer notices on their bank statement. Proactive refunds have near-zero chargeback escalation rates. Waiting for the customer to complain results in 40–60% chargeback escalation rates, plus dispute fees and damage to your Stripe dispute ratio.
What to do next
You are here
duplicate_transaction
Decline code reference
Check recoverability
Stripe Failure Lookup
See what's recoverable — and what isn't →
Then
Sign up for Recurflux
Automate recovery for every decline code →
Before you retry
Before you retry
Most duplicate_transaction failures are retried on the wrong schedule — which recovers the payment about 30% of the time. The other 70% leaves permanently. See what this code is actually costing at your MRR before deciding how to handle it.
Stop leaving revenue on the table
Recurflux handles code-specific retry scheduling, adaptive dunning, and dispute intelligence across all 30 Stripe decline codes. Connect in under 5 minutes.