What is x402
x402 is an HTTP-native payment protocol built on the402 Payment Required status code. When a client calls a paid agent endpoint without payment, the server responds with a 402 status and a PaymentRequirement describing what to pay, how much, and where. The client constructs a payment proof and retries the request with an X-PAYMENT header containing the signed transaction or attestation.
This turns every HTTP request into a potential payment channel — no payment SDKs, no checkout flows, no invoices. The agent decides its price, the protocol enforces it on-chain.
How x84 implements x402
Each agent registers aPaymentRequirement PDA that defines pricing for a specific service type. When a request hits the x402 gate:
- The gate loads the
PaymentRequirementfor the target agent and service - If the request includes a valid
X-PAYMENTheader, the gate callsverify_and_settleon-chain - If the request includes an
X-DELEGATIONheader, the gate settles via the delegation’s pre-approved budget - If neither header is present, the gate returns a
402response with the payment details
Settlement modes
x84 supports three settlement modes, each suited to different trust and automation levels.- Atomic
- Attestation
- Delegated
The payer signs the transaction. The program executes SPL token transfers via CPI — first the protocol fee to the treasury, then the remainder to the payee. The compressed receipt is created in the same instruction.Use when: the payer is online and can sign each request.
Settlement mode comparison
| Atomic | Attestation | Delegated | |
|---|---|---|---|
| Token transfer | On-chain CPI | Off-chain (trusted) | On-chain via SPL delegate |
| Payer signs | Yes | No | No |
| Facilitator required | No | Yes | Yes |
| Delegation PDA | Not used | Not used | Required |
| Use case | Standard user payments | External/fiat settlement | Autonomous agent budgets |
Settlement fee
Every settlement deducts a protocol fee before the payee receives payment. The fee is defined in basis points on theProtocolConfig account.
| Parameter | Value |
|---|---|
| Default fee | 300 bps (3%) |
| Maximum cap | 1000 bps (10%) |
| Destination | fee_treasury wallet |
| Adjustable by | Protocol authority (governance) |
fee_amount and payee_amount are recorded on the compressed receipt and emitted in the PaymentSettled event.
Payment follows the NFT
Thepay_to field on PaymentRequirement determines who receives payment. When an agent NFT is transferred and the new owner calls claim_agent, they can update the pay_to address. Whoever holds the NFT controls the revenue stream.
This means agent NFTs are income-producing assets. Transferring the NFT transfers all future payment revenue.
PaymentRequirement PDA
Each agent can define one payment requirement per service type.| Field | Type | Description |
|---|---|---|
nft_mint | Pubkey | Agent identity (NFT mint address) |
service_type | ServiceType | MCP, A2A, API, or Web |
scheme | PaymentScheme | Exact (fixed price) or UpTo (dynamic, up to amount) |
amount | u64 | Price in token’s smallest unit (e.g., 1000000 = 1 USDC) |
token_mint | Pubkey | SPL token mint (USDC, wrapped SOL, etc.) |
pay_to | Pubkey | Destination wallet for payments |
description | String | Human-readable description (max 200 chars) |
resource | String | API endpoint path (max 200 chars) |
active | bool | Whether this requirement is active |
[b"payment_req", nft_mint.as_ref(), service_type.seed()]
The verify_and_settle instruction
verify_and_settle is the single instruction that handles all payment settlement. It verifies the payment, deducts the protocol fee, transfers tokens (in Atomic and Delegated modes), and creates a compressed receipt via Light Protocol.
Validation
The instruction checks that the payments module is not paused, the
PaymentRequirement is active, and the amount meets the requirement (exact match for Exact scheme, at or below for UpTo).Token transfer (mode-dependent)
Atomic: Two SPL CPI transfers — fee to treasury, remainder to payee. Payer signs.Attestation: No transfer. Facilitator attests the payment happened externally.Delegated: Two SPL delegate transfers using the facilitator’s authority on the payer’s ATA. Delegation PDA constraints are verified and updated (
spent_total, uses_remaining).Receipt creation
A
CompressedPaymentReceipt is created via CPI to the Light System Program. The receipt address is derived deterministically from the payment_id.Compressed receipts with Light Protocol
Every settlement creates a payment receipt. At scale, receipts are the highest-volume account type in the protocol. x84 uses Light Protocol (ZK Compression) to store receipts as compressed PDAs instead of regular Solana accounts, eliminating rent costs entirely.Compressed PDAs store account data as hashes in Merkle trees, verified by zero-knowledge proofs. The data is rent-free and permanent.
| Volume | Regular PDA rent | Compressed PDA cost | Savings |
|---|---|---|---|
| 1,000 receipts | ~3 SOL ($450) | ~0.01 SOL | 99.7% |
| 10,000 receipts | ~30 SOL ($4,500) | ~0.1 SOL | 99.7% |
| 100,000 receipts | ~300 SOL ($45,000) | ~1 SOL | 99.7% |
CompressedPaymentReceipt struct
| Field | Type | Hashed | Description |
|---|---|---|---|
payment_id | [u8; 32] | Yes | Unique nonce (client-generated) |
nft_mint | Pubkey | Yes | Agent identity |
payer | Pubkey | Yes | Who paid |
payee | Pubkey | No | Who received payment |
amount | u64 | No | Total amount paid |
fee_amount | u64 | No | Protocol fee deducted |
token_mint | Pubkey | Yes | SPL token used |
resource | String | Yes | API endpoint path |
settlement_mode_raw | u8 | No | 0=Atomic, 1=Attestation, 2=Delegated |
extra_data_hash | [u8; 32] | Yes | SHA-256 of tx_signature (64 bytes) + delegation_key (32 bytes) |
created_at | i64 | No | Unix timestamp |
Why extra_data_hash instead of raw fields
Why extra_data_hash instead of raw fields
Light Protocol’s
LightHasher supports a maximum of 12 fields. To stay within this limit, tx_signature (64 bytes) and delegation key (32 bytes) are consolidated into a single 32-byte SHA-256 hash. The full values are emitted in the PaymentSettled event and available in transaction logs for off-chain access.Address derivation and anti-replay
Receipt addresses are deterministic, derived from thepayment_id:
payment_id is used twice, the creation is rejected, providing the same replay protection as a regular PDA init constraint.
Address Lookup Table (ALT)
Settlement transactions include many accounts. An Address Lookup Table compresses the transaction by referencing 16 static accounts by index instead of including full 32-byte pubkeys.NetworkConfig.lightAlt and created once per deployment via the deploy CLI:
Spending budgets
A budget is an on-chain spending allowance that lets agents or applications make x402 payments without requiring a human signature per request. It combines two Solana primitives:- SPL Token approve — gives the x84 facilitator wallet transfer authority over the payer’s token account
- x84 Delegation PDA — enforces granular constraints (per-tx limit, total budget, allowed tokens, expiry, use count)
Budget setup
Creating a budget requires a single transaction with two instructions.SPL Token approve
Authorize the x84 facilitator wallet as a delegate on the payer’s token account. The approved amount should match the budget’s
max_spend_total.Three payment paths in the x402 gate
When a request reaches a paid agent endpoint, the x402 gate checks for payment authorization in this order:| Header | Mode | Description |
|---|---|---|
X-PAYMENT | Atomic or Attestation | Standard x402 flow. Client provides signed payment proof. |
X-DELEGATION | Delegated | Budget flow. Client provides the delegation PDA address. Gate loads the delegation, verifies constraints, and auto-debits via SPL delegate authority. |
| Neither | 402 response | No payment provided. Gate returns 402 Payment Required with the PaymentRequirement details. |
On-chain constraint enforcement
Whenverify_and_settle is called with SettlementMode::Delegated, the program verifies all constraints before executing the transfer:
| Constraint | Field | Check |
|---|---|---|
| Active | delegation.active | Must be true |
| Owner version | delegation.owner_version | Must match agent_identity.owner_version |
| Expiry | delegation.expires_at | Must be 0 (no expiry) or greater than current timestamp |
| Permission | delegation.can_transact | Must be true |
| Per-tx limit | delegation.max_spend_per_tx | 0 (unlimited) or amount <= max_spend_per_tx |
| Total budget | delegation.max_spend_total | 0 (unlimited) or spent_total + amount <= max_spend_total |
| Allowed tokens | delegation.allowed_tokens | Empty (any token) or contains token_mint |
| Uses remaining | delegation.uses_remaining | 0 (unlimited) or > 0 |
delegation.spent_total += amount and delegation.uses_remaining -= 1 (if not unlimited).
Budget revocation
A budget can be revoked in a single transaction that cancels both the delegation and the SPL Token approval.Budget use cases
Marketplace subscriptions
Marketplace subscriptions
A consumer creates a budget allowing an agent to charge up to 50 USDC/month for ongoing access. The agent’s x402 gate auto-debits each request against the budget. When the budget runs out or expires, the consumer tops it up or creates a new one.
Inter-agent spending
Inter-agent spending
A creator’s primary agent needs to call sub-agents (translation, search, summarization). The creator sets up a budget on their primary agent with
can_transact permissions and spending limits. The primary agent includes the X-DELEGATION header when calling sub-agents, enabling autonomous inter-agent commerce.SDK programmatic access
SDK programmatic access
An application uses a hot wallet to interact with paid agents. The application creates a budget from the hot wallet to the x84 facilitator, then includes the delegation address in all API calls. No human in the loop for each request.
SDK usage
PaymentSettled event
| Field | Type | Description |
|---|---|---|
paymentId | [u8; 32] | Unique payment nonce |
nftMint | Pubkey | Agent identity |
payer | Pubkey | Who paid |
payee | Pubkey | Who received payment |
amount | u64 | Total amount |
feeAmount | u64 | Protocol fee deducted |
tokenMint | Pubkey | SPL token used |
resource | String | API endpoint |
settlementMode | SettlementMode | Atomic, Attestation, or Delegated |
txSignature | [u8; 64] | Full transaction signature |
delegation | Option<Pubkey> | Delegation PDA (if Delegated mode) |