Skip to main content

x402Flex Overview

x402Flex mirrors Coinbase's 402 protocol while anchoring every accept option to X402FlexRouter metadata. Agents, wallets, and humans all see the same deterministic payload, so settlement logic remains identical.

Why X402Flex

Want the short, persuasive positioning? Read Why X402Flex.

HTTP 402 Payload

  1. Client requests a protected resource (POST /api/x402/introspect).
  2. Server responds with 402 Payment Required and JSON body describing acceptable payment paths.
{
"x402Version": 1,
"resourceId": "0xf296...",
"accepts": [
{
"scheme": "exact:evm:permit2",
"network": "bnb",
"asset": "0x55d398326f99059fF775485246999027B3197955",
"amount": "1000000",
"router": {
"address": "0xRouter",
"intent": {
"paymentId": "0x...",
"resourceId": "0x...",
"referenceHash": "0x...",
"nonce": "0x...",
"deadline": 1731763200
},
"referenceData": "api:credits:134"
}
}
],
"metadata": {
"merchant": "Pepay Labs",
"memo": "x402 gating"
}
}
  1. Wallet/agent picks an accept option, executes the router call (payWithPermit2, push, AA, etc.).
  2. Merchant verifies the resulting PaymentSettledV2 via SDK or indexer and retries the original request with authorization headers.
  • referenceHash is computed from the final reference string (session tags included).
  • nonce is mandatory per invoice; it is part of the paymentId binding.

Facilitator Toolkit (@pepaylabs/x402flex)

import express from 'express';
import { createFlexMiddleware, createFlexExpressMiddleware } from '@pepaylabs/x402flex';
import { createFlexIntent, buildFlexResponse } from '@pepaylabs/bnbpay';

const flex = createFlexMiddleware({
merchant: process.env.MERCHANT!,
networks: {
bnb: {
provider: BNB_PROVIDER,
registry: process.env.BNB_REGISTRY!,
router: process.env.BNB_ROUTER!,
chainId: 56,
confirmations: 3,
},
opbnb: {
provider: OPNB_PROVIDER,
registry: process.env.OPBNB_REGISTRY!,
router: process.env.OPBNB_ROUTER!,
chainId: 204,
confirmations: 1,
},
},
});

const app = express();

app.use('/api/generate', createFlexExpressMiddleware(flex, {
'/api/generate': {
buildResponse: async () => {
const intent = createFlexIntent({
merchant: process.env.MERCHANT!,
token: process.env.USDT!,
amount: 1_000_000n,
chainId: 56,
referenceId: 'api.generate',
scheme: 'exact:evm:permit2',
});

return buildFlexResponse({
intent,
network: 'bnb',
router: process.env.BNB_ROUTER!,
metadata: { memo: 'API credit' },
});
},
onAuthorized: async (_req, settlement) => {
console.info('Authorized', settlement.paymentId, settlement.referenceData);
},
},
}));
  • buildResponse is called on every 402 challenge; bake in rate limits or variable pricing.
  • onAuthorized receives the decoded PaymentSettledV2 object once confirmations land.
  • Use referenceData to encode CRM IDs, invoice IDs, or agent handles.

Scheme Catalog

Scheme StringSchemeIdNotes
push:evm:direct0x2914a5ad49430794a41289b127686141b95eb37498f4abd184b28a0b69808b12Native/token push via router helpers.
push:evm:aa43370x38535c5fa3d21dae45dbc4b490c7b97d00903f89c8785b145dd204d4670a4807AA4337 UserOp push payments.
exact:evm:permit20xc07338ac3a63d5933e6a5b2184602e306eb7c25700866301b635132c811546f1Permit2 witness signature transfer.
exact:evm:eip26120x9429a5bd2d856a1fb737472aa76f02e1be1b968a1f4eb757c60cb7f042e6a4d9ERC-2612 permit + transferFrom.
exact:evm:eip30090x7b76f402569ceb571fa538a410383abd8186ad7e6043c5687c2ac19717b3c535USDC-style pull payments.

Retrieve IDs programmatically with getFlexSchemeId('exact:evm:permit2').

EIP-3009 nonce rule: authNonce must be derived from the intent hash + router + chainId: keccak256(abi.encodePacked("X402Flex", intentHash, router, chainId)).

Open Flex Spec Alignment

Pepay Labs publishes the entire x402Flex spec + implementation so builders can audit every assumption. Cross-reference the repo artifacts below when extending flows:

CapabilitySpec ReferenceImplementation
HTTP 402 envelope fields, status codes, and error semanticsdocs/X402_FLEX_SPEC.md §§3-5packages/x402flex (createFlexMiddleware, createFlexExpressMiddleware)
Router-only settlement + PaymentSettledV2 resource IDsdocs/ROUTER_MIGRATION.mdcontracts/payments, packages/sdk-ts/src/x402.ts
Agent-to-agent intents + MCP toolchainsdocs/X402_FLEX_SPEC.md §8, updates.md "MCP Server" entries/mcp-server + docs on this page
Scheme catalog & deterministic hashingdocs/X402_FLEX_SPEC.md Appendix A@pepaylabs/bnbpay helpers (getFlexSchemeId, createFlexIntent)

Because every component above is open source, wallets can fork the middleware, swap signing backends, or extend schemes without waiting on Pepay Labs. Keep updates.md up to date whenever a new scheme ships so partners can diff spec vs. implementation quickly.

Agent-to-Agent x402 Payment

Autonomous agents can both issue and satisfy HTTP 402 challenges—useful for paywalled APIs or when Claude/Codex agents exchange compute.

import { decodePaymentSettledEvent } from '@pepaylabs/bnbpay';

// Agent A (provider) issues a challenge
const response = await issue402Challenge();

// Agent B (payer) uses the MCP tool exposed by /mcp-server
const receipt = await mcpClient.invoke('handle_402_response', {
paymentInfo: response.body,
senderPrivateKey: process.env.AGENT_PRIVATE_KEY!,
preferredChain: 'opbnb',
});

const settlement = decodePaymentSettledEvent(receipt.settlementLog);
await notifyPeer({ paymentId: settlement.paymentId, reference: settlement.referenceData });
  • Embed the agent identifier inside referenceData (e.g., agent:claude:design-review) so both parties reconcile quickly.
  • Agents should persist paymentId + resourceId locally, then pass them back through MCP to prove completion.

Claude/Codex MCP Wiring

  1. Build the MCP server inside /mcp-server (npm install && npm run build).
  2. Add the server to Claude Code or Anthropic Codex configuration:
{
"mcpServers": {
"bnbpay": {
"command": "node",
"args": ["./mcp-server/dist/index.js"],
"env": {
"BNB_RPC_URL": "https://bsc-dataseed.binance.org/",
"BNB_PAYMENT_REGISTRY": "0x1fAa1B7445ed1B3120451cC3F8f2230CB172602f",
"BNB_PAY_ROUTER": "0xRouter",
"DEFAULT_CHAIN": "bnb"
}
}
}
}
  1. Restart Claude Code/Codex so the new MCP server loads. The create_402_payment, handle_402_response, and verify_payment tools become available and mirror the snippets above.

MCP Tie-In

  • create_402_payment → Build HTTP payloads identical to buildFlexResponse.
  • handle_402_response → Executes permit, push, or AA flow and streams the resulting settlement log.
  • get_payment_status → Confirms the PaymentSettledV2 emission and returns scheme + fee data for downstream agents.

Ensure your MCP deployment uses the same contract addresses surfaced on the documentation homepage so agents and humans remain on a single source of truth.