duplicate_transaction: Stripe Subscription Fix
Root cause
Stripe returns duplicate_transaction when retry logic, missing idempotency protection, or overlapping billing jobs cause a second near-identical subscription charge attempt against the same card in the same time window.
Symptoms
- • A customer reports two attempted charges for one billing cycle
- • Stripe declines the second payment with duplicate_transaction
- • Webhook or cron logs show overlapping retries for the same subscription invoice
- • The problem clusters around timeouts or workers that restart mid-charge
How to fix it
Trace the first successful or pending attempt
Open the Stripe event timeline and identify the original invoice, PaymentIntent, or charge that the duplicate request matched. Determine whether the first attempt actually succeeded, is still processing, or failed after the duplicate was submitted. This tells you whether customers faced a real double-charge risk or only a duplicate authorization attempt.
Open in admin →Add idempotency to billing requests
Ensure every subscription billing write uses a deterministic idempotency key based on the subscription ID and billing cycle date. That prevents restarts, queue retries, or webhook replays from creating a second charge attempt for the same cycle. Apply the same keying discipline across manual retry tools if your team has internal admin actions.
Block overlapping retry workers
Audit your scheduler, webhook consumer, and dunning process so only one actor can charge a given subscription cycle at a time. Introduce a short-lived lock or database state transition before charging. Without concurrency control, even a correct Stripe integration can still generate duplicate_transaction declines under load or timeout recovery.
Frequently asked questions
Does duplicate_transaction mean the customer was charged twice?
Not always. It usually means Stripe or the issuer recognized a second highly similar attempt and blocked it before settlement. You still need to inspect the first transaction carefully to confirm whether one charge succeeded, whether it is still pending, or whether both attempts failed. The key issue is duplicated billing logic, not necessarily duplicated captured revenue.
What is the best prevention for duplicate_transaction in subscription systems?
Deterministic idempotency plus single-writer billing orchestration. Use one idempotency key per subscription cycle, persist billing state before retries, and prevent webhook handlers, manual retries, and cron workers from acting on the same invoice simultaneously. Most duplicate_transaction cases trace back to concurrency bugs or timeout recovery that starts a second charge too soon.
Detect this error automatically
Free cross-stack scan finds all billing errors in 60 seconds.
Run Free Scan →