Skip to main content
Batch settlement lets a customer fund a reusable on-chain channel once and pay for many requests with signed vouchers, while your server claims and sweeps the accumulated charges in batches. It is built for metered APIs, inference, and any service where the final price of a request is known only after the work is done. On EVM the scheme is implemented by the x402BatchSettlement contract, and PayAI relays every on-chain leg and pays the gas.
PayAI serves batch-settlement on Base mainnet (eip155:8453) and Base Sepolia (eip155:84532) at https://facilitator.payai.network. Access is public: no PayAI account or API key is needed. Add an API key only if you want to pay for settlement legs with credits after the free allowance.

How it works

  1. Deposit. The customer signs a USDC authorization (EIP-3009, or Permit2 for other ERC-20s) that funds a channel identified by its immutable config: payer, receiver, receiver authorizer, token, withdraw delay and a salt. PayAI submits the deposit; the customer pays no gas.
  2. Vouchers. Each request carries a voucher with a cumulative ceiling: everything charged so far plus this request’s maximum. Your server verifies the signature locally in a few milliseconds and charges the actual amount, from zero up to the ceiling. Nothing touches the chain.
  3. Claim. On your schedule, your server sends the latest voucher per channel to PayAI, which submits one claimWithSignature transaction covering up to 25 channels.
  4. Sweep. A settle transaction transfers everything claimed for your receiver and token to your wallet in one transfer.
  5. Refund or withdraw. Your server can cooperatively refund a customer’s unused balance at any time; the customer can always start a timed withdrawal (one to 24 hours under PayAI’s policy) as a unilateral fallback.
Partial charges are first class: the ceiling is authorized by the customer, the charge is decided by your server. Use the HTTP adapter’s settlement override to bill less than the ceiling:

1. Install the upstream SDK

PayAI runs the merged x402 Foundation implementation. Use the published packages; no PayAI-specific build is required:
Use BatchSettlementEvmScheme from @x402/evm/batch-settlement/server on your server and the same-named class from @x402/evm/batch-settlement/client on the customer side. The reference server and client live in the x402 repository under examples/typescript/servers/batch-settlement and examples/typescript/clients/batch-settlement.

2. Bring your own receiver authorizer

The receiver authorizer is the key that signs claims and refunds for your channels. PayAI does not advertise a facilitator-held authorizer, so you must configure your own:
The SDK checks this at startup: without a receiverAuthorizerSigner it refuses to initialize against PayAI. This is upstream’s recommended production mode. Your channels survive a facilitator change, because any facilitator can relay your signed claims and refunds. Keep the key until every channel it authorizes has drained; rotating it means opening new channels.

3. Run the channel manager

Claims and sweeps happen when your server asks for them. Run the exported channel manager against the same durable storage:
Claim well inside the withdraw delay of your channels. Vouchers you have not claimed when a customer’s withdrawal finalizes are lost. Use Redis or Valkey storage for anything beyond a single local process; the file and memory stores are for tests.

4. Policy and limits

Read batchPolicy from GET /supported for the live values; these are the defaults: Top-ups to an existing channel are not bound by the initial-deposit range. The upstream server announces a minDeposit hint of ten times the route price by default, which for a $0.01 route is exactly PayAI’s 0.10 USDC floor; raise the route’s extra.minDeposit if your customers should fund more per channel.

5. What PayAI bills

Every on-chain leg PayAI relays for you is priced at the observed gas plus 30 percent: deposit, claim, sweep and refund. Vouchers are free; they never reach PayAI. Without an API key, legs draw on the public free-tier allowance for your payTo address and are refused when it is exhausted. With a merchant API key they are billed as credits. There are no privileged legs: a refused claim or sweep never strands funds, because claimWithSignature, settle and refundWithSignature are permissionless on the contract and you can relay them yourself. Observed on Base mainnet: a deposit costs about 140,000 gas, a single-channel claim about 77,000, a sweep about 57,000 and a refund about 95,000. At Base fees today that is well under a cent per leg.

Recovery

Retry the exact payload after a timeout, a settlement_pending answer, or a lost response. Deposits, claims and refunds are content-addressed: an identical retry returns the recorded outcome, and if the original transaction is still unconfirmed PayAI reconciles it from its receipt rather than broadcasting again. A claim that is no longer strictly increasing is refused with batch_claim_not_increasing, which means the earlier claim landed; reconcile against the channel’s on-chain totalClaimed. Sweeps are different: a settle request sweeps whatever is owed now, so it has no durable identity. A second sweep while one is in flight returns 409 duplicate_settlement. A sweep with nothing left to move returns nothing_to_settle, and when a recent sweep for that receiver and token is known the response carries extra.lastSweep with its transaction and amount. A settlement_pending sweep answered with an empty transaction hash means PayAI was still waiting for the receipt; retry after a minute.

Test before taking customer traffic

Start on Base Sepolia with USDC from the Circle faucet, using the same facilitator URL. Exercise partial charges, a claim and sweep cycle, a lost response, a process restart, and a cooperative refund, and confirm your receiving wallet’s USDC balance moves by the charged total. Then repeat with a small channel on Base mainnet.