Industry
The 200 OK that meant the payment had failed
Sergey Shinder Dev.to (EN Zone)
2 views
Over one weekend we marked one thousand four hundred orders as paid that had not been paid. Nothing in our logs looked wrong. The gateway responded quickly, our error rate was zero, and the first anyone knew was on Monday when finance reconciled the settlement report against our order table and found a gap with five figures in it.
The gateway returns HTTP 200 for a declined card. The body says so, in a field called result with the value REJECTED and a response code of 51 for insufficient funds. Our shared HTTP client treated any 2xx as success and only parsed the body on non-2xx. That client had been written for a different integration, where the transport status and the business outcome genuinely did line up, and then reused everywhere because it was the one that existed. For most of our partners it was fine. For this one it meant a decline and an approval were the same event.
I do not think the gateway is wrong, either. The request was received, understood and processed correctly. That is what 200 means. Whether the money moved is a different question and a different layer, and expecting a transport code to answer it is our mistake, not theirs.
Every integration now has its own response decoder that must classify a reply into success, retryable or terminal by looking at the body. The default branch throws: an unrecognised result string is an incident, not an assumed success. We wrote contract tests from real recorded responses including the ugly ones, declines, partial captures and the one where the partner returns 200 with an empty body during their maintenance window.
The part that matters most is that it is checked twice. A daily reconciliation job pulls the partner's settlement file and compares it line by line with what our system believes. Any order we call paid that they do not is an alert the next morning. Money integrations get reconciliation because agreement between two systems is something you verify, not something you assume from a status code.
Transport success and business success are two different facts. Do not let one library answer for both.
– Sergey Shinder
Read original: https://dev.to/sergey_shinder_ab2d943365/the-200-ok-that-meant-the-payment-had-failed-5a63
← Previous
We Replaced MMAP with Io_uring in Our Rust Query Engine. It Got Slower
Next →
A Spreadsheet Was Running a Process We Called Automated
Related
We Replaced MMAP with Io_uring in Our Rust Query Engine. It Got Slower
Industry
0
Hacker News
Model IoT Data Before You Store It: Device, Measurement, Timestamp
Industry
1
Dev.to (EN Zone)
Mexican student creates an acoustic fire extinguisher to put out fire in seconds
Industry
0
Hacker News
Nine coding harnesses vs. your laptop
Industry
0
Hacker News
Comments0
No comments yet — be the first