X402 Facilitator Integration

The Facilitator is the server-side settlement component in the X402 link. The client is responsible for signing, while the Gateway or your server is responsible for calling the Facilitator's /verify and /settle.

The production Facilitator address for Ace Data Cloud is:

https://facilitator.acedata.cloud

Source code repository: https://github.com/AceDataCloud/FacilitatorX402

Core Interfaces

GET /supported

View supported networks and schemes:

curl https://facilitator.acedata.cloud/supported

Example response:

{
  "kinds": [
    { "x402Version": 2, "scheme": "exact", "network": "base" },
    { "x402Version": 2, "scheme": "upto", "network": "base", "extra": { "facilitatorAddress": "0x..." } },
    { "x402Version": 2, "scheme": "exact", "network": "skale" },
    { "x402Version": 2, "scheme": "upto", "network": "skale", "extra": { "facilitatorAddress": "0x..." } },
    { "x402Version": 2, "scheme": "exact", "network": "solana" },
    { "x402Version": 2, "scheme": "exact", "network": "solana-devnet" }
  ]
}

Production result of /supported:

kinds ['base/exact', 'base/upto', 'skale/exact', 'skale/upto', 'solana/exact', 'solana-devnet/exact']
upto_extra [
  ('base', {'facilitatorAddress': '0xd019...5708'}),
  ('skale', {'facilitatorAddress': '0xd047...CC1C'})
]

Result explanation:

  • /supported indicates that the Facilitator has corresponding verification and settlement capabilities.
  • Both exact and upto support Base and SKALE; Solana is currently exact.
  • Whether a specific API allows these options still depends on the API's 402 accepts.

POST /verify

Verify whether the X-Payment sent by the client meets a certain payment requirement.

Request body:

{
  "paymentPayload": {
    "x402Version": 2,
    "scheme": "exact",
    "network": "base",
    "payload": { "...": "..." }
  },
  "paymentRequirements": {
    "scheme": "exact",
    "network": "base",
    "maxAmountRequired": "95215",
    "resource": "/openai/chat/completions",
    "payTo": "0x...",
    "asset": "0x...",
    "extra": { "...": "..." }
  }
}

Successful response:

{
  "isValid": true,
  "invalidReason": null,
  "payer": "0x..."
}

The decoded X-PAYMENT-RESPONSE response header for production order payment contains the settlement result. The program result for Base order payment:

settle_header {'success': True, 'network': 'base', 'transaction': '0xfec08cc00a159ea1ec692b32faa9bf3d17595a986301169e689d94f58bc44151', 'errorReason': None}
order 78481793-304e-47f7-bc0c-8231aec9cc1e state Finished pay_way X402 price 1.2
explorer https://basescan.org/tx/0xfec08cc00a159ea1ec692b32faa9bf3d17595a986301169e689d94f58bc44151
transfer value 1200000 atomic USDC

Result explanation:

  • success=True indicates that the Facilitator settlement was successful.
  • transaction is the on-chain transaction hash, and the order's pay_id is also written with the same value.
  • The explorer shows a transfer of 1200000 atomic USDC of Base USDC.
  • errorReason=None indicates that there were no business errors returned for this settlement.

Verification failures typically also return HTTP 200, but isValid is false. The business side should read invalidReason, rather than just looking at the HTTP status code.

POST /settle

Settle the already verified authorization on-chain.

The request body is basically the same as /verify. The difference for upto is: paymentRequirements.amount indicates the actual settlement amount, while maxAmountRequired still retains the signature limit.

Successful response:

{
  "success": true,
  "errorReason": null,
  "transaction": "0x...",
  "network": "base",
  "payer": "0x...",
  "amount": "151"
}

If the actual amount for upto is 0, transaction may be an empty string, indicating that no on-chain transaction is needed.

How Ace Data Cloud Gateway Uses Facilitator

The link for Ace Data Cloud API Gateway is as follows:

  1. The client first requests the API without Authorization and X-Payment.
  2. The Gateway calculates the estimated price for the request and returns 402 and accepts.
  3. The client retries with X-Payment after signing.
  4. The Gateway decodes X-Payment and selects the matching payment requirement.
  5. The Gateway calls the Facilitator /verify.
  6. After /verify is successful, the Gateway forwards the request to the upstream API.
  7. After the upstream API returns, the Gateway calls the Facilitator /settle during the /record phase.
  8. The Gateway writes the on-chain transaction hash into the usage record metadata.

exact settles the signed amount in step 7; upto writes the actual amount based on real usage in step 7, and then settles the actual amount.

How to Integrate Your Own API

If you want your own API to support X402, you can implement it according to this structure:

  1. Prepare paymentRequirements for each paid interface, including network, amount, payee address, asset address, and signature domain.
  2. If the request does not have X-Payment, return HTTP 402 and accepts.
  3. If the request has X-Payment, Base64 decode to obtain paymentPayload.
  4. Call the Facilitator /verify.
  5. Execute business logic after successful verification.
  6. Call the Facilitator /settle after business success.
  7. Save payer, transaction, amount, and network for reconciliation.

The server must use its own generated paymentRequirements to call /verify and /settle, and should not trust the amounts, payee addresses, or asset addresses returned by the client.

Replay Protection

The Facilitator will record the nonce. Authorizations with the same nonce cannot be verified and settled repeatedly.

This means:

  • The client should sign a new envelope for each request;
  • If /settle has submitted a transaction but has not yet been confirmed, it can retry /settle with the same nonce for idempotent reconciliation;
  • Do not cache the same X-Payment for multiple API calls.

Common Errors

Error Common Causes
Authorization nonce already processed The same X-Payment has been reused.
Authorization destination mismatch The to in the client signature does not match the payTo in the payment requirement.
invalid_upto_evm_payload_invalid_signature The chainId, facilitator, Permit2 domain, or signature address of the upto typed data do not match.
PERMIT2_ALLOWANCE_REQUIRED The wallet has not approved a sufficient USDC allowance for Permit2.
Payer has insufficient USDC balance The payment wallet has insufficient USDC.
Solana signer private key not configured The facilitator needs to sign as the fee payer, but the server lacks Solana signer configuration.