Facilitator
The service that verifies and settles x402 payment payloads on behalf of merchants.
The facilitator is a stateless HTTP service that does two things on behalf of merchants: it verifies payment payloads and it submits them to the chain. Merchants delegate to it so they can accept paid traffic without writing chain-specific code.
The HTTP surface
Three endpoints, plus a health check.
GET /supported— advertises the schemes and assets the facilitator handles.POST /verify— checks that a payload binds to a merchant'sPaymentRequirements. Returns{isValid: true, payer}or{isValid: false, invalidReason, details?}.POST /settle— re-verifies, then submits the operation to the chain. ReturnsSettleResult(success or error).
/verify is read-only; /settle is not. Merchants commonly verify before invoking the protected handler and settle after the handler returns 2xx, so they don't pay for settlement when their handler fails.
What /verify checks
For an aa-native payload, the verifier:
- Decodes the V2 envelope.
- Decodes the inner
userOpandsettlementCallSpec. - ABI-decodes
userOp.callDatato aSettlementContract.settle(merchant, token, amount, requestHash)invocation. BothSimpleAccount.execute(...)andSimpleAccount.executeBatch(...)are accepted; forexecuteBatchthe verifier finds the entry whose data decodes tosettle. - Asserts that the decoded
settlearguments equalsettlementCallSpecfield-for-field. - Asserts that
settlementCallSpecmatches the merchant'sPaymentRequirements(merchant address, token, amount). - Checks the off-chain replay registry for
requestHashcollisions.
The full validation rules and the error codes are in the whitepaper §2.4. The error code list is on the Errors reference page.
What /settle does
/settle is idempotent on requestHash. The flow:
- Claim the
requestHashin the off-chain registry asin_flight. If it is alreadysettled, return the originaltxHashimmediately. If it is alreadyin_flight, returnerrorCode: "in_flight". - Re-verify with the same checks as
/verify. Releases the in-flight claim on failure. - Submit the UserOp via
eth_sendUserOperationon the bundler. Captures the returneduserOpHash. - Wait for the bundler to return a receipt via
eth_getUserOperationReceipt. The settlement contract emitsReceiptLogon success. - Complete the registry entry with the bundler-returned
transactionHash.
A second /settle call with the same requestHash returns the original tx hash without re-submitting. In production tests this short-circuit completes in single-digit milliseconds versus several seconds for the original bundler round-trip.
Auth
Merchants authenticate to the facilitator with an HMAC-signed bearer token in Authorization: Bearer <hmac>. This authentication scheme is a facilitator-implementation detail and is not specified by x402.
The reference public Playground shares one rate-limited token across its public endpoints. Per-merchant tokens are issued out-of-band for production merchants.
Scheme support
The reference NERO 402 facilitator handles both aa-native and exact. /supported lists both:
{
"x402Version": 2,
"schemes": [
{"scheme":"exact", "networks":["eip155:1689"], "assets":["0x...USDC", "0x...USDT"]},
{"scheme":"aa-native", "networks":["eip155:1689"], "assets":["0x...USDC", "0x...USDT"]}
]
}A merchant that wants to accept both can advertise both in its paymentRequirements array. The client picks whichever it can satisfy.
Self-hosting
The reference facilitator is at apps/facilitator/. It runs on Node 20+, uses Hono, and is small enough to deploy on Vercel Functions, Fly.io, Railway, or any Node host.
A self-hosted facilitator handles its own paymaster relationship and bears the gas cost for aa-native settlements it submits. Where the public NERO 402 facilitator is single-tenant and operated by the project, self-hosted deployments are per-merchant.