Safaricom's sandbox STK Query API returns FAILED for successful payments. Here's what's happening.
Running reconciliation against the Daraja sandbox last week, I got this: {"checked":3,"matched":0,"skipped":0,"mismatches":[ {"checkoutRequestId":"ws_CO_26032026133641276708729173", "storedStatus":...

Source: DEV Community
Running reconciliation against the Daraja sandbox last week, I got this: {"checked":3,"matched":0,"skipped":0,"mismatches":[ {"checkoutRequestId":"ws_CO_26032026133641276708729173", "storedStatus":"PENDING","mpesaStatus":"FAILED"}, {"checkoutRequestId":"ws_CO_26032026111016899708729173", "storedStatus":"SUCCESS","mpesaStatus":"FAILED"}, {"checkoutRequestId":"ws_CO_26032026113146397708729173", "storedStatus":"SUCCESS","mpesaStatus":"FAILED"} ]} The last two entries are the problem. Both have confirmed M-Pesa receipts in the database — UCQ5UAQ403 and UCQ5UAPYRY — with confirmed deductions on the test account. The STK callback delivered ResultCode: 0 for both. Money moved. Safaricom's own callback said so. The STK Query API disagrees. It says both payments failed. I searched Stack Overflow, the Safaricom GitHub repos, every community integration I could find. No prior documentation of this. Not a single issue or comment. It appears to be unreported. What's actually happening Safaricom's s