- Facilitator - verifies and broadcasts the payment on-chain
- Resource Server - defines which tokens are accepted and which APIs require payment
- Client(s) - initiates payments and accesses paid endpoints, either through an automated backend wallet representing a machine identity, or a web wallet like MetaMask
Native Integration
In the following sections, we’ll walk through a native integration on peaq, demonstrating how the payment negotiation and verification flow can be implemented directly on-chain.Facilitator
The facilitator is responsible for verifying payment authorization and broadcasting transactions to the peaq blockchain. It acts as the verification layer between the client’s signed request and the resource’s API logic. There are two modes of operation:-
Delegated Verification
The resource server delegates payment verification to an external facilitator running on peaq. The facilitator validates transaction proofs and returns a signed receipt via HTTPS.
This is ideal for smaller resource servers that prefer not to run blockchain nodes. For example, PayAI provides a hosted facilitator supporting peaq at:
https://facilitator.payai.network. Please checkout the x402 Facilitator List for more providers. - Self-Hosted Verification The resource server deploys a facilitator service connected directly to peaq RPC node. This enables local validation of payment proofs and full control over on-chain interactions. While more complex, this reduces reliance on external services and grants full control over signing, verification, and transaction lifecycle management. It’s the preferred configuration for enterprise or high-throughput API systems.
Resource Server
The resource server exposes one or more API endpoints protected by x402. When a client requests a protected resource, the server responds with a402 Payment Required response.
The resource server specifies payment requirements per endpoint, including accepted EIP-3009 tokens using contract address and pricing units. These settings
determine when the HTTP 402 response is triggered.
Once the payment is confirmed via the facilitator, the resource server grants access and returns the API response. This layer bridges the facilitator verification with client authorization.
Client
Clients can be human users interacting through web wallets like MetaMask or Rabby, or autonomous agents using backend wallets linked to peaq machine identities. These clients sign and broadcast payment transactions as specified in thePayment-Request header, then resubmit the original API call with a Payment-Receipt proving settlement.
We’ll demonstrate the full flow with two example clients:
-
Backend Autonomous Agent - a programmatic client (with its own private key/machine identity) signs the authorization automatically, representing a “machine paying a machine” flow.

-
Frontend User (MetaMask) - a human user signs a payment authorization using their wallet to unlock an API feature.

Project setup
The x402-peaq repository contains the complete implementation examples for:- Facilitator
- Resource Server
- Clients (frontend + backend)
Facilitator
Code Snippet:Explanation
verify()- checks if the client’s signed authorization is valid for the given payment terms.settle()- broadcasts the authorized payment on-chain once verified.PaymentRequirementsSchema/PaymentPayloadSchema- ensure incoming data follows the x402 spec.createSigner()- connects the facilitator’s private key to the correct peaq RPC endpoint.
Resource Server
USDC Code Snippet:Explanation
paymentMiddleware(payTo, rules, { url })- protects routes with x402. On first request returns 402 Payment Required with how-to-pay details; after payment + receipt, it lets the request through.payTo- the receiver address on peaq (e.g., your machine or service wallet) that will receive funds.rules map- keys like “METHOD /path” (e.g., “GET /data”) define which endpoints require payment and at what price/network.Human-price format- price: “$0.01” (USDC on peaq); easy to read and configure for standard ERC-3009 tokens.Atomic-price format- price:{ amount, asset }for custom tokens (e.g., stgUSDT). Includeasset.address,asset.decimals, and optionaleip712 { name, version }.network- which chain to use (here: “peaq”). Must align with the client and facilitator.{ url: facilitatorUrl }- points to your Facilitator (delegated or self-hosted) that verifies/settles the payment.app.get("/data", ...)- your protected handler. It only runs after a valid payment receipt is presented on the retried request.Env vars- FACILITATOR_URL, MACHINE_B_ADDRESS, SERVER_PORT; keep the client’s displayed price in sync with the server rule.
Clients
Code Snippet:Explanation
privateKeyToAccount(MACHINE_A_PRIVATE)- loads the machine identity (Machine A) as an EOA used to sign x402 authorizations on peaq.createWalletClient({ account, transport: http(), chain: peaq })- creates a viem wallet client bound to peaq for signing the EIP-3009 style payment authorization.wrapFetchWithPayment(fetch, client, 200000)- decorates fetch so that when a 402 Payment Required is returned, it:- reads the x402 payment requirements from the response
- signs an authorization with client
- sends it to the facilitator for verification/settlement
- retries the original request with a Payment-Receipt. The 3rd argument caps the max value you’re willing to authorize (here, “$0.20 USDC” represented in atomic units set by your integration).
await fetchWithPay(url, { method: "GET" })- performs the request; if payment is needed, the wrapper handles the pay-then-retry flow automatically.response.headers.get("X-PAYMENT-RESPONSE")- base64-encoded JSON “settlement receipt” returned by your server after successful payment; decode to inspect tx details.await response.json()- the actual protected resource payload (e.g., machine data) you wanted after settlement.

