Verifying on-chain proofs
Double-check on-chain payment proof before you ship files, unlock access, or close accounting.
How to belt-and-braces-verify settlement — PAYMENT-RESPONSE header, receipt status, confirmations, recipient and amount checks.
x402 settles after the response is sent. The transaction hash arrives in the PAYMENT-RESPONSEheader on the 200 reply. If you're building anything that needs absolute confirmation — accounting, anti-fraud, post-purchase fulfillment — verify the tx on-chain before treating the order as final.
What you get back
HTTP/1.1 200 OKPAYMENT-RESPONSE: {"txHash":"0xfa3c...e0","network":"base","blockNumber":12345678,"settled":true}The body also includes the same payment record on the order.payment field, so server-side consumers don't need to parse the header.
On-chain check
Verify with any RPC provider for the chosen network.
import { createPublicClient, http } from "viem";import { base } from "viem/chains"; const client = createPublicClient({ chain: base, transport: http() }); const receipt = await client.getTransactionReceipt({ hash: "0xfa3c...e0",}); if (receipt.status !== "success") { throw new Error("Settlement failed — void the order locally.");} // Optionally confirm the transferred amount + recipient.const log = receipt.logs.find( (l) => l.address.toLowerCase() === USDC_BASE.toLowerCase());// Parse the ERC-20 Transfer log: from, to, amount.What to confirm
- Network — the tx is on the chain advertised in
PAYMENT-RESPONSE.network. - Receipt status —
success, not reverted. - Confirmations — enough block depth for your risk tolerance (Base/Polygon: 5+ blocks; Ethereum: 12+).
- Recipient — the
toin the ERC-20 Transfer log matches the merchant'scryptoWalletAddress. - Amount — exactly the
maxAmountRequiredfrom the challenge.
Refund paths
If settlement fails after a 200 response (rare — usually a reorg or an exhausted-balance race), Aly emits order.refunded via webhook and the order moves to refunded. There is no on-chain refund — settlement simply never completed. If settlement succeeded but the buyer requests a refund, the merchant initiates a manual on-chain return from the dashboard.
Tx schema
The order's payment field has the canonical shape:
{ "scheme": "exact", "network": "base", "asset": "USDC", "asset_address": "0x8335...", "amount": "5000000", "pay_from": "0x111...", "pay_to": "0xabc...", "tx_hash": "0xfa3c...", "block_number": 12345678, "confirmed_at": "2026-05-19T08:35:21.000Z"}Webhooks
Subscribe to order.created (fires when the order is persisted, pre-settlement) and order.refunded (fires if settlement fails or is rolled back). See Webhooks.
Was this page helpful?