x402 Merchant & Facilitator
x402 Merchant & Facilitator API
Base URL: https://ai.cryptoapis.io/x402/merchant. POST /verify and POST /settle are authenticated with a Crypto APIs key that has the X402_FACILITATOR feature; GET /supported and GET /discovery/resources are public (no API key) so a merchant can check we serve their chain before signing up. The facilitator verifies a buyer's signed payment and settles it on-chain with its own gas wallet — non-custodially: it can never move funds the buyer did not authorize.
The 402 challenge
When an unpaid request hits your paid endpoint, your API answers 402 Payment Required with a PaymentRequired body: { x402Version, resource, accepts[] }. Per x402 v2 §5.1.2 resource is required — a ResourceInfo whose url identifies what is being paid for (the endpoint URL over HTTP; mcp://tool/<name> over MCP) — alongside the accepts[] list of PaymentRequirements (asset, amount, network, pay-to address, and any family-specific extra). The buyer authorizes and signs it (see x402 Buyer), then retries with the signed payment attached.
Endpoints
POST /verify— check a buyer's signed payment against thePaymentRequirementswithout settling. Returns{ isValid, payer, invalidReason?, invalidDetail? }.POST /settle— verify and then broadcast the payment on-chain with the facilitator's gas wallet. Returns{ success, payer, transaction, network, errorReason?, errorDetail?, amount? }. On failuretransactionis an empty string rather than absent, per x402 v2 §5.3.2.GET /supported— public. Returns{ kinds, extensions, signers }: the scheme/network pairs we settle, the protocol extensions we honour, and the facilitator signer addresses.GET /discovery/resources— public. The x402 v2 §8 discovery catalogue of known paid resources:{ x402Version, items, pagination }. Paginate withlimit(1–100, default 20) andoffset.
Reading /supported correctly
signers is keyed by CAIP-2 namespace pattern, not by concrete network — "eip155:*", "solana:*". A client that looks up signers["eip155:8453"] finds nothing; index by the namespace. A namespace mapped to an empty array is normal, not a fault: it means that family settles without a facilitator-held signer (broadcast-only). Use kinds[] — not the signers keys — to decide whether a given scheme/network pair is settleable.
extensions lists the protocol extensions the facilitator honours. It is always present, even when empty, so a client can call .includes() on it unconditionally.
Error codes are the x402 v2 §9 standard set
invalidReason and errorReason carry standard x402 codes (invalid_signature, invalid_valid_before, invalid_payment_requirements, invalid_transaction_state, …), not Crypto APIs-internal ones, so your error handling is portable across facilitators. Refusals the spec does not model — AML screening, travel rule, asset gating — map to the closest standard code plus an invalidDetail / errorDetail naming the precise cause. Branch on the standard code; log the detail.
Idempotent retries — the payment-identifier extension
We honour the payment-identifier extension (advertised in /supported's extensions). A client-supplied id (16–128 chars) on the PaymentPayload becomes the facilitator's idempotency key, so retrying a request whose response was lost settles once rather than twice. This is the only safe way to retry a settlement.
Settlement quota headers
/verify and /settle carry the merchant's per-billing-cycle settlement quota on every reply as X-X402-Settlement-Limit / -Remaining / -Reset, so you can self-throttle before hitting a 429.
Integrating
Use @cryptoapis-io/x402-merchant-sdk (Express / Hono / Next.js) to wire the paywall, the 402 challenge, and the verify/settle round-trip in a few lines. To charge AI agents for an MCP tool rather than an HTTP endpoint, use the SDK's /mcp adapter — see x402 SDKs & Tooling. The SDK is non-custodial and holds no keys.