x402 end-to-end integration checklist

All unit tests pass, but integration tests still fail. Most x402 pitfalls occur at boundaries: 402 response headers sent but unreadable by the browser (missing CORS exposed headers), signatures computed correctly but rejected by the facilitator (nonce reuse / incorrect amount unit), funds received but reconciliation fails (wrong reconciliation source). This tool follows the five-step flow “free discovery → 402 → signature payment → data retrieval → on-chain reconciliation”, generating both a runnable integration testing script and a checklist for each step listing “expected outcome + common failure causes”.

Free · No Login Required Locally Generated · Content Is Not Uploaded Corresponding Incident · 402 headers are sent but not readable by the browser

1Your Endpoint

2Pricing and Settlement

ResultIntegration Overview

OutputEnd-to-end integration script

0 lines
—
All five steps run sequentially; stops immediately and reports reason if any step yields an unexpected value |

OutputStep-by-step checklist (can be handed to colleagues for execution)

0 lines
—

Quick ReferenceCommon failures during integration

PhenomenonRoot CauseHow to Fix
Packet capture shows 402, but JS cannot read the headerNot Set Access-Control-Expose-HeadersAdd custom headers such as payment-required to the exposed list
facilitator reports invalid nonceNonce reuse, or mismatch between signature domain and chain ID |Generate a fresh random nonce each time; verify the domain's chainId.
facilitator reports amount mismatchIncorrect amount unit (USDC uses 6 decimal places)0.01 USDC = 10000, not 1e16 |
Buyer can pay even without gas (this is correct)EIP-3009 transferWithAuthorization Gas paid by facilitator |Buyers only need to hold USDC
Funds arrived but reconciliation failedReconcile using the platform’s own records, not on-chain eventsOnly on-chain Transfer events are accepted; tolerance ±$0.02 |
Funds Never ArriveBelow minimum settlement threshold / Settlement date not yet reachedAggregated by calendar month; settled on the 10th of the following month; minimum $50 per settlement |
Health check marked endpoint as deadMCP endpoint returns SSE, client fails to parse as JSONJudged solely by HTTP status code: both 200 and 402 are considered alive
We’ve fallen into this pitfall

1 · 402 sent, but browser cannot read itCustom response headers are visible in packet captures but inaccessible in JS—must be explicitly added to the exposed list. Access-Control-Expose-Headers, otherwise the browser blocks it directly per security policies.

2 · Health check false negative.Using a JSON client to probe an MCP endpoint returning SSE always results in “dead”; correct behavior is to inspect only the status code—both 200 and 402 indicate liveness.

3 · Amount unit.USDC has 6 decimal places; 0.01 must be written as 10000; writing it as 1e16 will cause immediate rejection by the facilitator, and the error message won’t indicate the unit mismatch.

4 · Reconciliation only recognizes on-chain data.The platform’s own records may be inaccurate due to process restarts or overwritten stale in-memory values; reconciliation must rely on on-chain Transfer events.