Skip to main content

General structure

interface PaymentPayload {
  x402Version: 1;
  scheme: "exact";
  network: string;
  payload: {
    authorizationType: "eip3009" | "permit" | "permit2";
    signature: `0x${string}`;
    authorization: Record<string, unknown>; // varies by type
  };
}

Authorization type structures

EIP-3009 (transferWithAuthorization)

interface Eip3009PaymentPayload {
  x402Version: 1;
  scheme: "exact";
  network: string;
  payload: {
    authorizationType: "eip3009";
    signature: `0x${string}`; // EIP-712
    authorization: {
      from: `0x${string}`;
      to: `0x${string}`;
      value: string;        // wei
      validAfter: string;   // unix seconds
      validBefore: string;  // unix seconds
      nonce: `0x${string}`; // 32 bytes
    };
  };
}

EIP-2612 Permit

interface PermitPaymentPayload {
  x402Version: 1;
  scheme: "exact";
  network: string;
  payload: {
    authorizationType: "permit";
    signature: `0x${string}`; // EIP-712
    authorization: {
      owner: `0x${string}`;
      spender: `0x${string}`;
      value: string;      // wei
      deadline: string;   // unix seconds
      nonce: string;      // on-chain nonce
    };
  };
}

Permit2 (optional Witness)

interface Permit2PaymentPayload {
  x402Version: 1;
  scheme: "exact";
  network: string;
  payload: {
    authorizationType: "permit2";
    signature: `0x${string}`; // EIP-712
    authorization: {
      owner: `0x${string}`;
      spender: `0x${string}`;
      token: `0x${string}`;
      amount: string;     // wei
      deadline: string;   // unix seconds
      nonce: string;      // uint256
      to?: `0x${string}`; // Witness (bind recipient)
    };
  };
}

EIP-712 key fields

  • domain: name/version/chainId/verifyingContract
  • types: varies by authorization type (TransferWithAuthorization/Permit/Permit2)
  • message: authorization payload (amount/nonce/deadline, etc.)

Example (EIP-3009)

{
  "x402Version": 1,
  "scheme": "exact",
  "network": "bsc",
  "payload": {
    "authorizationType": "eip3009",
    "signature": "0x...",
    "authorization": {
      "from": "0xBuyer",
      "to": "0xSeller",
      "value": "1000000",
      "validAfter": "0",
      "validBefore": "1735689600",
      "nonce": "0x7c7c..."
    }
  }
}

Example (Permit2 with Witness)

{
  "x402Version": 1,
  "scheme": "exact",
  "network": "bsc",
  "payload": {
    "authorizationType": "permit2",
    "signature": "0x...",
    "authorization": {
      "owner": "0xBuyer",
      "spender": "0xSpender",
      "token": "0xUSDC",
      "amount": "1000000",
      "deadline": "1735689600",
      "nonce": "123456789",
      "to": "0xSeller"
    }
  }
}

Server-side validation checklist

  • Version/scheme/network match the requirements
  • Authorization signature is valid; signer matches owner/from
  • Token/recipient match: token === asset, to/spender === payTo
  • Amount and validity: meet maxAmountRequired and not expired
  • Nonce/balance: unused and sufficient balance (type-specific checks)

Key validations

  • Version/scheme/network match the requirements
  • Amount ≥ maxAmountRequired
  • Deadline has not expired
  • spender === payTo (EIP-7702 enforces minimal trust)

Example (Permit)

{
  "x402Version": 1,
  "scheme": "exact",
  "network": "bsc",
  "payload": {
    "authorizationType": "permit",
    "signature": "0x...",
    "authorization": {
      "owner": "0xBuyer",
      "spender": "0xSeller",
      "value": "1000000",
      "deadline": "1735689600",
      "nonce": "0"
    }
  }
}