跳转到主要内容

类型

interface PaymentRequirements {
  scheme: "exact";
  network: string;
  maxAmountRequired: string;
  resource: string;
  description: string;
  mimeType: string;
  payTo: string;
  maxTimeoutSeconds: number;
  asset: string;
  paymentType?: "eip3009" | "permit" | "permit2";
  outputSchema?: Record<string, unknown>;
  extra?: Record<string, unknown>;
}

字段要点

  • scheme:固定 "exact"
  • network:kebab-case 网络名(如 bsc, base-sepolia
  • maxAmountRequired:最大支付额(wei)
  • payTo:商家地址(EIP-7702)
  • asset:Token 合约地址
  • maxTimeoutSeconds:签名有效期(防重放)

示例

{
  "scheme": "exact",
  "network": "bsc",
  "maxAmountRequired": "1000000",
  "resource": "https://api.example.com/premium",
  "description": "Premium API access",
  "mimeType": "application/json",
  "payTo": "0xSeller",
  "maxTimeoutSeconds": 600,
  "asset": "0xUSDC",
  "paymentType": "permit"
}

Zod Schema

import { z } from "zod";

export const PaymentRequirementsSchema = z.object({
  scheme: z.literal("exact"),
  network: z.string(), // 例如 "bsc", "bsc-testnet", "base-sepolia"
  maxAmountRequired: z.string().refine(
    (v) => Number.isInteger(Number(v)) && Number(v) >= 0
  ),
  resource: z.string().url(),
  description: z.string(),
  mimeType: z.string(),
  outputSchema: z.record(z.any()).optional(),
  payTo: z.string(), // EVM 0x... 或 SVM 地址
  maxTimeoutSeconds: z.number().int().positive(),
  asset: z.string(), // Token 地址(EVM/SVM)
  paymentType: z.enum(["eip3009", "permit", "permit2"]).optional(),
  extra: z.record(z.any()).optional(),
});

支持的网络

type Network =
  | "bsc" | "bsc-testnet"
  | "ethereum" | "sepolia"
  | "base" | "base-sepolia"
  | "polygon" | "arbitrum" | "optimism";

验证规则要点

  • scheme 必须为 "exact"
  • network 必须与客户端/链配置一致
  • BigInt(payment.value) <= BigInt(maxAmountRequired)
  • resource 为有效 URL,且与受保护资源一致
  • payTo 与商家收款地址一致(建议 EIP-7702)
  • 超时:deadline/validBefore <= now + maxTimeoutSeconds
  • 若指定 paymentType,客户端必须使用该类型

常见场景

  • 固定价 API:启动时创建并缓存 requirements,复用以降低开销
  • 动态定价:按请求上下文计算 maxAmountRequired/description
  • 多 Token 选项:返回多个 accepts 供客户端选择(见 402)

结合 402 的用法

{
  "x402Version": 1,
  "accepts": [
    { "scheme": "exact", "network": "bsc", "asset": "0xUSDC", "maxAmountRequired": "1000000", "description": "Pay with USDC", "mimeType": "application/json", "payTo": "0xSeller", "maxTimeoutSeconds": 600 },
    { "scheme": "exact", "network": "bsc", "asset": "0xDAI", "maxAmountRequired": "1000000000000000000", "description": "Pay with DAI", "mimeType": "application/json", "payTo": "0xSeller", "maxTimeoutSeconds": 600 }
  ]
}