# 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's `PaymentRequirements`. Returns `{isValid: true, payer}` or `{isValid: false, invalidReason, details?}`.
- `POST /settle` — re-verifies, then submits the operation to the chain. Returns `SettleResult` (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:

1. Decodes the V2 envelope.
2. Decodes the inner `userOp` and `settlementCallSpec`.
3. ABI-decodes `userOp.callData` to a `SettlementContract.settle(merchant, token, amount, requestHash)` invocation. Both `SimpleAccount.execute(...)` and `SimpleAccount.executeBatch(...)` are accepted; for `executeBatch` the verifier finds the entry whose data decodes to `settle`.
4. Asserts that the decoded `settle` arguments equal `settlementCallSpec` field-for-field.
5. Asserts that `settlementCallSpec` matches the merchant's `PaymentRequirements` (merchant address, token, amount).
6. Checks the off-chain replay registry for `requestHash` collisions.

The full validation rules and the error codes are in the [whitepaper §2.4](/whitepaper.pdf). The error code list is on the [Errors reference page](/docs/reference/errors).

## What `/settle` does

`/settle` is idempotent on `requestHash`. The flow:

1. **Claim** the `requestHash` in the off-chain registry as `in_flight`. If it is already `settled`, return the original `txHash` immediately. If it is already `in_flight`, return `errorCode: "in_flight"`.
2. **Re-verify** with the same checks as `/verify`. Releases the in-flight claim on failure.
3. **Submit** the UserOp via `eth_sendUserOperation` on the bundler. Captures the returned `userOpHash`.
4. **Wait** for the bundler to return a receipt via `eth_getUserOperationReceipt`. The settlement contract emits `ReceiptLog` on success.
5. **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:

```json
{
  "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/`](https://github.com/nerochain/nero-x402/tree/main/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.
