x402 turns HTTP 402 into a real payment flow: your server answers 402 with payment requirements, the client pays, and a facilitator verifies and settles. The happy path is easy. Money is lost in the unhappy paths. Here are five I test for, and how to check your own server in one CI step.
1. A /settle call that times out. If your middleware treats "no answer" as "probably fine", anyone can get content by making settlement slow. Fix: serve only after a well-formed success: true.
2. A 503 with a success body. Proxies return error pages, and sometimes success-looking bodies with a 5xx status. Fix: check the status code before you read the body, and keep the payment retryable.
3. settlement_pending treated as paid. In x402 V2 (ยง9), settlement_pending is non-terminal: the transaction may still fail. Fix: don't serve until it's final; keep the transaction and reconcile.
4. The same payment presented twice. Fix: the facilitator must answer duplicate_settlement for a payload it already settled, and your check-and-insert must be atomic.
5. A reused memo in a new transaction. On Solana devnet the reference facilitator dedupes by transaction, not by memo: two different transactions with the same memo both settled. If your app maps one memo to one purchase, you must enforce single use yourself. (Devnet transactions and hashes: https://atsp-protocol.github.io/x402-conformance/)
Check your server. x402-conformance is an open-source (Apache-2.0) GitHub Action that puts a facilitator double in front of your server and requests your paid route under each fault:
- uses: atsp-protocol/x402-conformance@v1
id: x402
with:
resource-url: http://127.0.0.1:4020/paid
start: node server.js # your server must use X402_FACILITATOR_URL
fail-on-error: false
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: ${{ steps.x402.outputs.sarif }}
category: x402-conformance
Failures show up in your repo's Security tab, and each one links to a "what failed and how to fix it" entry in the fix guide. There's a JUnit report too. For facilitators, live mode only sends GET /supported. No install needed: pipx run --spec "git+https://github.com/atsp-protocol/x402-conformance@v1" x402conf offline.
It's experimental and Solana-first; issues and check proposals are welcome: https://github.com/atsp-protocol/x402-conformance
Top comments (0)