Atharva Khewle

ReviewOct 2026 · TypeScript, Node.js

Double charges and lost receipts in x402 payments

TL;DR x402 lets apps and AI agents pay for an API call over HTTP. The dangerous moment is when the payment goes through but the response is lost. I reported one double-charge risk and sent two fixes upstream.

Why this matters

In normal web code, "request failed, try again" is safe. With payments, it isn't. If the money already moved and the client is told to retry, it pays twice. If the server hides that settlement is still pending, the client loses the receipt it needs to prove it paid.

The contributions

WhereWhatStatus
Dexter MCP #130 Double-charge risk. x402_pay and x402_fetch report a paid call as a plain, retryable error when the merchant's response is lost. Proposed a payment_unconfirmed, retryable: false result, with 3 offline tests. Open
PayAI x402-solana #61 Lost receipt. Keep settlement_pending and the transaction hash when /settle returns a non-2xx status. Fixes #60. Open. The reporter checked it with the x402 conformance suite.
x402 Foundation #3957 Locked-down runtimes. Extract bazaar discovery info where code generation is disabled (Cloudflare Workers, --disallow-code-generation-from-strings). Closes #3446. Open

Takeaway

Payment clients need a third outcome besides success and failure: "you may have paid, don't retry, here's the proof". Most retry logic was written for a world where requests were free.

← All field notes