Double charge after deploy: symptoms, cause, and the test that catches it
A customer is charged twice for one purchase after a release changes retry or idempotency behaviour.
Double charge after deploy is documented by 2 accepted public reports from 2 organisations, 1 of them published in the last 5 years.
- Likelihood: not published (1 public report in 5 years)
- Impact: high (2 of 2 reports: money)
Symptoms
User-visible
- Customers using the payment platform's Ruby client library saw errors on transactions that had in fact been run.[2]
- Some customers of the payment platform reported duplicate charges and multiple failed transactions.[2]
- Some payment gateways showed duplicate payments for the same transaction after a scheduled deployment.[1]
Monitoring-visible
- Processing errors rose, and the rise was isolated to the Ruby client library.[2]
- Certain transactions appeared duplicated in the payment submissions sent to downstream gateways.[1]
- A customer contacted the payment platform about duplicate charges and failed transactions about an hour after the deploy.[2]
Root causes
- stage: code A deploy removed the eligible_for_card_updater field from the response body of some API calls, and the Ruby client library raised exceptions when the field was absent.[2]
- stage: code Customer records of transaction results then differed from the actual results, so customer retries of errored transactions produced duplicated transactions.[2]
- stage: code An update meant to improve transaction timestamp accuracy changed the transaction workflow logic, so certain payment requests re-executed under specific timing conditions.[1]
Public examples
- [1]AuthVia, 2025-10-15. On 14 October 2025 a scheduled AuthVia deployment changed logic in the transaction workflow so that some payment requests re-executed under specific timing conditions, sending duplicate payment submissions to downstream gateways until a fix was deployed. primary Duplicate payments are possible
- [2]Spreedly, 2017-02-10. On 8 February 2017 Spreedly deployed code that removed a field from some API responses; the Spreedly Ruby gem raised exceptions when parsing those responses, and customers who retried the affected transactions created duplicate charges until the change was reverted about 2.5 hours later. primary Issues processing transactions with Ruby Gem
Test classes that catch it
| Test class | Stage | Limitation | Basis |
|---|---|---|---|
| Contract tests | pre-merge | A contract test flags the removed eligible_for_card_updater response field, but the timing-dependent re-execution in the transaction workflow changed no request or response shape, so a contract test passes on it. | by design analysis |
| Integration tests | pre-deploy | An integration test that sends one payment request and counts gateway submissions finds the re-execution only if it reproduces the specific timing conditions that triggered it in the transaction workflow. | by design analysis |
| Canary and progressive delivery checks | post-deploy | The processing errors were isolated to customers on the Ruby client library, so a canary whose traffic share holds no such customers never sees the error rise. | by design analysis |
Risk
- Likelihood: not published (1 public report in 5 years)
- Impact: high (2 of 2 reports: money)
| Accepted public reports | 2 |
|---|---|
| Published in the last 5 years | 1 |
| Impact stated: money | 2 |
Pre-release checklist
- PR-01
- PR-02
- PR-03
- PR-04
- PR-05
- PR-06
- PR-07
- PR-08
First 30 minutes
- FM-01
- FM-02
- FM-03
- FM-04
- FM-05
- FM-06
- FM-07
Download the checklist
What catches this: catalogue entries
Listed because their own documentation or site names contract tests, integration tests, canary and progressive delivery checks on the verification date. Alphabetical. Not a recommendation.
Tools whose documentation names these test classes
- Argo Rollouts canary source verified 2026-10-21
- Flagger canary source verified 2026-10-21
- GrowthBook canary source verified 2026-10-21
- Hoverfly integration source verified 2026-10-21
- Kayenta canary source verified 2026-10-21
- LaunchDarkly canary source verified 2026-10-21
- Pact contract source verified 2026-10-21
- Postman integration source verified 2026-10-21
- Schemathesis contract source verified 2026-10-21
- Serenity BDD integration source verified 2026-10-21
- Specmatic contract source verified 2026-10-21
- Spinnaker canary source verified 2026-10-21
- Testcontainers integration source verified 2026-10-21
- TestNG integration source verified 2026-10-21
- Unleash canary source verified 2026-10-21
Providers whose site names these test classes
- andagon people GmbH integration source verified 2026-10-21
- Appmatics integration source verified 2026-10-21
- AQA Masters integration source verified 2026-10-21
- Cleverix integration source verified 2026-10-21
- Crestech Software Systems integration source verified 2026-10-21
- DeviQA integration source verified 2026-10-21
- Full Scale contract source verified 2026-10-21
- Invensis Technologies integration source verified 2026-10-21
- Outpost QA integration source verified 2026-10-21
- Q-Centric GmbH integration source verified 2026-10-21
- QA Madness contract source verified 2026-10-21 integration source verified 2026-10-21
- QA Mentor integration source verified 2026-10-21
- QASource contract source verified 2026-10-21
- QAwerk integration source verified 2026-10-21
- Quality Island contract source verified 2026-10-21 integration source verified 2026-10-21
- Soflab Technology integration source verified 2026-10-21
- SQA - Software Quality Assurance S.A. integration source verified 2026-10-21
- SunTec India integration source verified 2026-10-21
- TestFort integration source verified 2026-10-21
- Testhouse integration source verified 2026-10-21
- Testing IT integration source verified 2026-10-21
- TestMatick integration source verified 2026-10-21
- Testscenario integration source verified 2026-10-21
- Zoonou integration source verified 2026-10-21
Only on this page
Double charge after deploy in report [2] took 57 minutes to detect. The deploy went out at 16:33 EST [2]. A customer contacted the payment platform about duplicate charges at 17:30 EST [2]. Other customers reported similar issues by 18:39 EST [2]. The field removal was reverted at 19:11 EST, about 2.5 hours after the deploy [2].
Throughout that window, the Ruby client library reported errors on transactions that had in fact run [2]. Customers who retried those transactions created duplicate charges [2]. The report lists better correlation of reports from independent channels as a follow-up [2].
Related incidents
- Connection pool exhausted A new code path leaks or holds connections and the pool runs out under load.
- Background job queue backlog A job change slows processing and the queue grows faster than it drains.
- Subscription renewal skipped Scheduled renewals do not run or run with stale plan data after a billing job change.
- Tax calculation regression Tax or VAT is computed with the wrong rate or jurisdiction after a rules or data update.
- Checkout blocked for segment A checkout step fails for one customer segment, country or card type after a release.
Questions
What causes double charge after deploy?
Both reports name a code-stage cause. In report [2], a deploy removed a field from some API responses, and customers retried transactions their client library had wrongly reported as errors. In report [1], a workflow logic change re-executed certain payment requests under specific timing conditions.
What are the symptoms of double charge after deploy?
Some gateways showed duplicate payments for the same transaction [1]. Customers on the affected client library saw errors on transactions that had in fact been run [2].
How long did it take to detect double charge after deploy in the public reports?
Report [2] took 57 minutes from the 16:33 EST deploy to the first customer contact. Report [1] does not state the deployment time, so it has no time to detect.
Which test class catches double charge after deploy, and what does it miss?
Contract tests, integration tests and canary checks are listed, all with the by-design label. A contract test passes on the timing-dependent re-execution in report [1], because no request or response shape changed.
Which public reports document double charge after deploy?
Two primary reports from two organisations document it. They were published on 2017-02-10 [2] and 2025-10-15 [1].
Should a team roll back or fix forward when double charge after deploy happens?
Report [2] reverted the field removal at 19:11 EST. Report [1] deployed a fix and worked with partners and merchants to reverse duplicate charges. FM-03 reverts the deploy while duplicate submissions still appear.
Release Incident Playbook (2026). Double charge after deploy: symptoms, cause, and the test that catches it, content version 1.0.0. https://releasefailures.com/incidents/double-charge-after-deploy/. Accessed 2026-10-21.