x402 Deep Dive: A Payment Standard for the Internet

x402 is a new payment standard that enables micro payments on the web by leveraging blockchain technology. It leverages the existing 402 Payment Required status code to require payment before serving a response and uses crypto-native payments for speed, privacy, and efficiency, enabling micro payments.
In this article, you will explore how x402 works for programmatic services and how you can integrate it into your existing workflows using a simple Express app as an example.
How Does x402 Work?
Every x402 workflow has three main components:
The buyer or client
The seller or server
The facilitator
The Seller
In an x402 workflow, the seller, or server, refers to the entity that has paywalled a service using the x402 standard. The seller must define the payment requirements for the resource, including the amount, the blockchain network, the payment asset, and the payment destination (a wallet address).
Note that x402 only supports payment assets that implement the EIP-3009 (transferWithAuthorization) method, for example, USDC. This is because x402 sends a signed payment in a request header, so it needs a token that lets a relayer submit that signature on-chain without first setting allowances, and EIP-3009 transferWithAuthorization is the standard that enables exactly this.
The Buyer
In an x402 workflow, the buyer/client refers to the entity trying to access a paywalled service. A client can either be manually operated by a human, programmatically operated on behalf of a user, or autonomously operated using an AI agent.
Regardless of the client type, the flow remains the same. After initiating a request to a 402 Payment Required protected endpoint, they read the payment details provided by the seller, construct a valid payment payload, and retry the request with an X-PAYMENT header containing the signed payment payload.
The Facilitator
Although optional, a facilitator removes a lot of the overhead associated with verifying and settling payments between sellers and buyers.
In a direct peer-to-peer x402 flow, the buyer requests a protected endpoint and receives a 402 Payment Required response with payment details (amount, blockchain network, wallet address). The buyer then creates and submits a blockchain transaction and retries the request with a X-PAYMENT header containing the transaction proof.
The seller must independently verify the payment on the blockchain before granting access. This requires both parties to handle blockchain interactions directly, including transaction submission and on-chain verification.
A facilitator acts as a trusted intermediary for payment verification and settlement. Instead of sellers querying the blockchain directly, the facilitator provides a verification service that handles transaction broadcasting, confirmation monitoring, and issues cryptographically signed payment receipts.
There are several facilitators available today, such as:
CDP’s facilitator on Base mainnet, which offers fee-free USDC settlement on Base mainnet.
PayAI’s facilitator on Solana, Base, Polygon, and more.
Custom facilitators such as x402-sovereign by dhai.eth.
The entire x402 flow is stateless. Clients do not need to manage accounts, credentials, or session tokens beyond their crypto wallet, and servers do not need to manage client identities or maintain session state.
Everything is handled per request, making x402 well-suited for one-time or occasional access patterns, but potentially impractical for flows requiring frequent, continuous access to the protected resource due to per-request payment costs.
How to Use x402 in Your Apps?
This section covers how you can use x402 in your current workflow.
For this tutorial, we are going to use x402-express and x402-fetch to implement the flow for the seller and the buyer, respectively, because they already abstract most implementation details, allowing you to get started immediately. We are also going to x402-sovereign as our facilitator because it doesn't require any setup or API keys like CDP’s or PayAI’s.
Using x402 as Seller
To add an x402 paywall to a resource on an Express server or a similar server, you need to add the following packages to your existing app.
x402-express: Middleware for Express that handles x402 payment verification and responds with 402 Payment Required when payment is missing or invalid.
viem: TypeScript library for Ethereum interactions, used to verify blockchain transactions and interact with smart contracts.
x402-sovereign/core
Install them by running the command below:
npm install @x402-sovereign/core viem x402-express
You also need an EVM private key that will receive payments and pay gas.
.env file that is not tracked by version control!Next, you need to initialize your facilitator using your private key and specifying your supported networks:
import { Facilitator } from "@x402-sovereign/core";
const facilitator = new Facilitator({
evmPrivateKey: process.env.EVM_PRIVATE_KEY as `0x${string}`,
networks: [baseSepolia, sepolia],
});
The code block above initializes a custom facilitator using x402-sovereign supporting base sepolia and sepolia.
x402-sovereign exposes an express adapter that you can register as a middleware to mount the facilitator endpoints your server will call for verification and settlement. Like so:
import { createExpressAdapter } from "@x402-sovereign/core";
createExpressAdapter(facilitator, app, "/facilitator");
This mounts your local facilitator API onto your Express app under the /facilitator path. It registers three routes:
GET /facilitator/supportedPOST /facilitator/verifyPOST /facilitator/settle
It then forwards those requests to facilitator.handleRequest({ method, path, body }): /supported returns the facilitator’s capabilities and the networks you configured, /verify decodes the X-PAYMENT header and validates the EIP-712 signature, amount, asset, payTo, resource URL, chain ID, and time/nonce, and /settle Re-verifies and submits the EIP-3009 transferWithAuthorization on chain using your evmPrivateKey, returning success and a txHash. The adapter adds no business logic or auth; it just relays the status and body from the facilitator, or returns a 500 if an error occurred.
After configuring your facilitator, you can use the paymentMiddleware provided by x402-express to register the routes you want to protect, along with their associated prices.
For example:
app.use(
paymentMiddleware(
PAY_TO,
{
"/add-badge": {
price: "$0.01",
network: "base-sepolia",
config: {
description: "Grant Badge",
},
},
"/premium/*": {
price: "$0.10",
network: "base-sepolia",
config: {
description: "Access to premium content",
},
},
},
{
url: `${BASE_URL}/facilitator` as `${string}://${string}`,
}
)
);
The middleware will return 402 Payment Required with a challenge (image below) when the request is missing/invalid, and will call your handler once a valid X-PAYMENT header is supplied.

You can find the full implementation for this section in this GitHub repository.
Using x402 as Buyer
To programmatically access routes protected by x402, you need the x402-fetch package, which provides utilities to wrap standard fetch with automatic x402 payment handling, including signature creation and payment proof construction.
You also need an EVM private key to sign and submit payments.
.env file that is not tracked by version control!To make requests to x402-protected endpoints, you need to create a signer for your target network and wrap the standard fetch function with payment capabilities:
import {
wrapFetchWithPayment,
createSigner,
type Hex
} from "x402-fetch";
const privateKey = process.env.PRIVATE_KEY as Hex | string;
const signer = await createSigner("base-sepolia", privateKey);
const fetchWithPayment = wrapFetchWithPayment(fetch, signer);
The createSigner function initializes a signer for the specified network using your private key. The wrapFetchWithPayment function returns an enhanced fetch that automatically handles the x402 payment flow.
Now you can use fetchWithPayment just like the standard fetch function:
const response = await fetchWithPayment(`${endpointBaseUrl}/add-badge`, {
method: "GET",
});
const body = await response.json();
console.log(body);
When you request a protected endpoint, fetchWithPayment automatically detects the 402 Payment Required response, reads the payment requirements from the challenge, constructs and signs the payment proof, and retries the request with the X-PAYMENT header. From your perspective, it works seamlessly like a regular fetch call.
Optionally, you can access payment details from the response headers:
import { decodeXPaymentResponse } from "x402-fetch";
const paymentResHeader = response.headers.get("x-payment-response");
if (paymentResHeader) {
const paymentResponse = decodeXPaymentResponse(paymentResHeader);
console.log(paymentResponse);
}
The x-payment-response header contains information about the payment transaction, including the transaction hash and settlement status.
You can find the full implementation for this section in this GitHub repository.
Conclusion
The x402 standard provides practical developer tools for implementing ERC-8004, the protocol specification for blockchain-based HTTP payments. By abstracting the complexity of EIP-712 signatures and EIP-3009 settlements, x402 enables truly stateless, pay-per-use APIs without traditional authentication.
To learn more about the underlying protocol, visit the ERC-8004 proposal. To explore the x402 ecosystem, check out x402.org.





