AI Agent 支付:连接买方安全付款与卖方稳定币收款
用买方策略、预算、审批和客户自持签名构建 AI Agent 支付,再以卖方支付订单、最终性、Webhook 与对账完成稳定币收款闭环。
AI Agent 能回答一次 HTTP 402 挑战,并不代表这笔 Agent 支付已经足够安全。买方仍要防止自主程序超出授权范围花钱;卖方仍要知道究竟是哪张业务订单收到了钱、转账是否已经最终确认,以及故障恢复时会不会重复履约。
所以,同一笔支付前后其实存在两个独立的控制问题:
- 在买方一侧,Agent 应该能够申请购买资源,但不能因此获得不受限制的钱包控制权。
- 在卖方一侧,成功的协议交互必须落成一张持久化订单、一笔最终确认的链上支付和一个可审计的业务结果。
StableOps 用两套边界清晰的产品覆盖这两个方向。Agent Payments 控制 Agent 如何付款;现有收款产品控制商户如何接收、确认并对账稳定币转账。x402 把 HTTP 请求和付款要求连接起来,但不会把买卖双方压进同一套共享状态机。
一笔支付,两条不同的信任边界
买方和卖方信任的系统不同,持有的凭据不同,需要回答的运营问题也不同。把各自职责分开,反而更容易准确理解整笔交易。
| 一方 | 必须决定什么 | StableOps 能力 | 绝不能获得什么 |
|---|---|---|---|
| 买方运营者 | 允许哪些来源和收款方、单个 Agent 可以花多少钱、何时必须人工审批 | 付款 Agent、不可变策略版本、组织与 Agent 两级预算、审批、执行授权 | 卖方 API Key 或收款地址管理权限 |
| 买方 Agent 运行时 | 请求哪个付费资源、如何恢复同一笔已批准付款 | 受限 Agent Key、Agent SDK、任务级幂等键 | 管理凭据或原始私钥 |
| 买方签名器 | 网络、资产、收款方、金额、Nonce 和有效期是否与授权完全一致 | 客户自托管签名器、本地授权存储、本地密钥或 AWS KMS | 来自模型的任意签名请求 |
| 卖方应用 | 转账属于哪张业务订单、何时可以安全执行下游动作 | 支付订单、收款地址、确认生命周期、签名 Webhook、投递审计 | 买方策略、预算或签名材料 |
这并不是买卖双方共用的一个账户。即使付款人使用其他 x402 客户端,卖方也可以单独使用 StableOps 收款;Agent Payments 客户也可以向使用其他商户系统的 x402 卖方购买资源。当双方都使用 StableOps 时,交易两端会获得一致的控制能力,但各自仍然拥有独立的凭据与记录。
AI Agent 支付的完整流程
当一项 x402 资源由 StableOps 支付订单承载时,完整路径如下:
卖方创建或复用支付订单
-> 卖方把分配的地址、链、资产和金额绑定到 x402 的 payTo
-> Agent 请求资源并收到 402 / PAYMENT-REQUIRED
-> Agent Payments 校验来源、收款方、金额、策略与两级预算
-> 请求超出自动放行范围时由管理员审批
-> StableOps 签发短时、单次执行授权
-> 客户自托管签名器验证授权并签署精确的付款数据
-> Agent SDK 携带 PAYMENT-SIGNATURE 重试 GET 请求
-> x402 资源服务器调用结算服务验证并结算,然后返回资源
-> 卖方支付订单检测并确认完全匹配的链上转账
-> payment.finalized Webhook 驱动持久化记账与卖方履约这条流程有两个关键交接点。
第一,卖方必须显式把 StableOps 付款指令绑定到 x402 付款要求。仅仅创建一张支付订单,并不会让它自动关联一笔无关结算。资源服务器给出的 payTo 地址、网络、资产合约与金额,必须描述订单期待的同一笔转账。
第二,协议结算与商户最终确认回答的是两个问题。付费 HTTP 响应告诉买方资源请求得到什么结果;响应中的 PAYMENT-RESPONSE 在存在时还会报告协议结算结果。卖方的 payment.finalized 事件告诉商户应用:完全匹配的转账已经到达平台配置的不可逆边界。如果 HTTP 响应还会启动长期任务、发放持久配额或修改外部系统,这些下游动作仍要支持安全重放,并与商户订单对账。
已有的 x402 支付与稳定币详细解释了这条协议边界。本文关注的是 StableOps 当前买方与卖方产品如何在边界两端衔接。
在公开 payTo 前,先为卖方建立持久化订单
卖方应该在 Agent 可以付款前确定业务身份。同一次收费使用稳定的商户订单标识和幂等键,分配精确收款地址,并在元数据中保留足够的请求上下文,便于后续排查。
import { StableOps } from '@stableops/api-sdk'
import { parseUnits } from 'viem'
const BASE_SEPOLIA_USDC = '0x036CbD53842c5426634e7929541eC2318f3dCF7e'
const X402_MAX_TIMEOUT_SECONDS = 300
const collection = new StableOps({
apiKey: process.env.STABLEOPS_API_KEY!,
})
export async function createAgentCharge(input: {
requestId: string
amount: string
resource: string
}) {
const order = await collection.paymentOrders.create(
{
merchantOrderId: `agent-request:${input.requestId}`,
amount: input.amount,
acceptedAssets: [{ chain: 'base-sepolia', asset: 'USDC' }],
expiresAt: new Date(Date.now() + 30 * 60 * 1000).toISOString(),
metadata: { rail: 'x402', resource: input.resource },
},
{ idempotencyKey: `agent-request:${input.requestId}` },
)
const instruction = order.paymentInstructions.find(
(item) => item.chain === 'base-sepolia' && item.asset === 'USDC',
)
if (!instruction) throw new Error('未分配 Base Sepolia USDC 付款指令')
return {
paymentOrderId: order.id,
payTo: instruction.address,
network: 'eip155:84532' as const,
asset: BASE_SEPOLIA_USDC,
amount: order.amount,
amountAtomic: parseUnits(order.amount, 6).toString(),
maxTimeoutSeconds: X402_MAX_TIMEOUT_SECONDS,
expiresAt: order.expiresAt,
}
}StableOps 支付订单的 amount 是资产单位的十进制字符串,x402 PaymentRequirements.amount 则是最小单位整数字符串。卖方构建付款要求时必须使用上面返回的 amountAtomic,不能直接使用 order.amount。同时把 payTo、network、asset 和 maxTimeoutSeconds 原样绑定进去,不要接受调用方提供的收款地址,也不要悄悄换成另一条链。
订单有效期也必须纳入付款要求的发布条件。资源服务器在首次返回和每次刷新 402 前,都要重新读取支付订单:只有状态仍为 created,并且剩余有效期足以覆盖 maxTimeoutSeconds 和必要的结算缓冲时,才能继续公开原付款要求。订单过期或剩余时间不足时应停止接受旧要求;如需重新收费,应使用新的商户订单标识和幂等键开启新的收费尝试,买方也不能拿旧审批授权新的付款。这样,即使人工审批晚于卖方订单过期,也不会把资金转入一张已经无法匹配的订单。
订单标识和幂等键解决的是两类重放问题。merchantOrderId 保持与业务请求的关联;幂等键让同一次创建调用在重试时返回原结果,而不是再次分配一笔收费。支付订单说明详细介绍了地址分配与匹配行为。
让 Agent 申请付款,而不是控制钱包
在买方一侧,运营者要在模型运行前准备好付款轨道:
- 登记并验证付款钱包。
- 创建付款 Agent,并为目标网络绑定钱包。
- 激活一份不可变策略版本,明确允许的来源、收款方、资产、单笔上限与自动付款阈值。
- 设置组织与 Agent 两级日预算。
- 签发受限 Agent Key,并把管理 API Key 留在运行时之外。
- 在客户自己的环境运行签名器,并使用独立的授权存储。
之后,运行时通过 Agent SDK 发起付费请求:
import {
AgentPaymentsControlClient,
HttpAgentSignerSidecar,
SafeHttpsRequester,
SettlementUnknownError,
StableOpsAgent,
} from '@stableops/agent-sdk'
const payments = new StableOpsAgent({
control: new AgentPaymentsControlClient({
agentKey: process.env.STABLEOPS_AGENT_KEY!,
}),
sidecar: new HttpAgentSignerSidecar({
url: 'http://127.0.0.1:8789',
authToken: process.env.STABLEOPS_SIDECAR_TOKEN,
}),
requester: new SafeHttpsRequester(),
})
let result: Awaited<ReturnType<typeof payments.x402Fetch>>
try {
result = await payments.x402Fetch('https://api.example.com/paid-report', {
idempotencyKey: 'research-task-284:paid-report:v1',
})
} catch (error) {
if (error instanceof SettlementUnknownError) {
const payment = await payments.getPayment(error.intentId)
console.error({
message: '结算结果未知,不得创建新的付款授权',
intentId: error.intentId,
authorizationId: error.authorizationId,
paymentStatus: payment.status,
})
}
throw error
}
if (result.status === 'paid' || result.status === 'not_required') {
if (!result.response.ok) {
const body = await result.response.text()
throw new Error(`资源请求失败:HTTP ${result.response.status} ${body}`)
}
const contentType = result.response.headers.get('content-type') ?? ''
const report = contentType.includes('application/json')
? await result.response.json()
: await result.response.text()
if (result.status === 'paid') {
const payment = await payments.getPayment(result.intentId)
console.log({
report,
intentId: result.intentId,
paymentStatus: payment.status,
protocolSettlement: result.paymentResponse,
resultReported: result.resultReported,
})
} else {
console.log(report)
}
} else if (result.status === 'awaiting_approval') {
// 保存 result.intentId,审批后恢复同一个 Intent。
console.log(`等待审批:${result.intentId}`)
}Agent Key 可以创建并查看属于自己的付款尝试,但不能修改钱包、策略、预算或审批。签名器也不信任 Agent 运行时:它会把每个字段与短时执行授权逐一比对,并拒绝任意消息或交易签名。钱包密钥始终留在客户进程或 KMS 的信任边界内。
当前产品范围刻意比“让模型使用钱包”更窄。Agent Payments 支持服务端 Node.js、HTTPS 上的 x402 v2 exact 资源、GET 请求和已配置的 USDC 网络;不开放直接转账、任意代币消费、POST、浏览器运行或原始签名接口。当前网络表以 Agent Payments 支持范围为准,完整配置步骤见快速开始。
由策略决定什么程度的自主权可以接受
仅有预算并不等于拥有完整的支付策略。即使 Agent 没有突破每日总额,它仍可能向错误的收款方付款、接受被篡改的报价,或者把错误任务重复执行很多次。
StableOps 会先校验来源、payTo、网络、资产和金额,再同时预留组织与 Agent 两级预算。一次请求随后会进入三条路径之一:
| 结果 | 含义 | 运营者如何处理 |
|---|---|---|
| 拒绝 | 付款突破了硬性策略或平台上限 | 修改任务或发布新策略版本,不能换一把 Key 绕过决定 |
| 等待审批 | 金额仍在硬上限内,但收款方、来源或自动付款阈值要求人工判断 | 检查已锁定的付款详情,只批准或驳回一次,然后恢复同一个 Intent |
| 自动批准 | 允许列表、金额与预算条件全部通过 | 继续领取短时授权,并交给客户签名器 |
新建付款 Agent 默认采用保守策略:自动付款阈值为零,运营者明确激活更宽的规则前,每笔付款都需要审批。审批也不是让 Agent 修改收费内容的入口。如果刷新后的 x402 要求改变了收款方、网络、资产,或者提高了金额,旧审批不能授权新的付款。
按不确定性设计重试,不要按乐观假设重试
AI 系统会积极重试,而支付系统必须假设:超时可能发生在价值已经转移之后。因此,买卖双方都需要稳定的身份标识。
- 买方对同一购买意图复用一个任务级幂等键。
- 需要审批时,保存返回的 Intent ID,并恢复该 Intent,而不是创建另一笔付款。
- 已签名请求发生超时后,查询现有付款并让对账流程判断结果;不能因为没有收到响应就创建替代 Intent。
- 卖方对同一次收费复用商户订单标识和创建调用幂等键。
- 卖方按事件标识去重已验签 Webhook,并让履约幂等性独立于投递次数。
这些规则分别约束交易两端的故障。买方避免重复扣款,卖方避免重复履约,任何一方的保证都不能替代另一方。稳定币 Webhook 指南给出了卖方事件收件箱与安全重放模式。
让两个控制层都远离资金托管
“非托管”在交易两端有不同的实际含义。
对买方来说,StableOps 不接收钱包私钥。客户签名器在本地验证精确绑定的执行授权,x402 结算服务提交受支持的付款。Agent 运行时拿到的是可吊销的 Agent Key,而不是通用钱包权限。
对卖方来说,StableOps 从私钥由商户控制的地址中分配收款地址。StableOps 检测并确认匹配的转账,但不持有收到的资金;资金归集与退款仍由商户执行。
这种拆分限制了每一种凭据的影响范围。Agent Key 泄露时可以直接吊销,无需迁移钱包;卖方 API Key 不能替买方钱包签名;模型提示也不能修改不可变策略,或迫使客户签名器接受任意数据。
生产检查清单
- 每个付费任务使用一个稳定的买方幂等键,每次卖方收费使用一个稳定的商户订单标识。
- 把卖方订单的准确地址、网络、资产和最小单位金额绑定进 x402 付款要求。
- 每次返回或刷新
402前检查卖方订单状态与剩余有效期,不向已过期订单继续收款。 - 把 Agent Payments 管理凭据留在 Agent 运行时之外,运行时只持有自己的 Agent Key。
- 从一个来源、一个收款方、很小的单笔上限、很小的日预算和人工审批开始。
- 在客户信任边界内运行签名器,并让授权状态能够跨进程重启持久保存。
- 付款获批后恢复同一个 Intent,不要另开一笔。
- 把已签名请求超时视为结算状态未知,而不是再次付款的许可。
- 按事件标识去重卖方 Webhook,并确保下游履约可以安全重放。
- 如果买卖双方由同一业务运营,同时记录买方任务标识、Agent Payment Intent ID、卖方支付订单标识和交易引用。
- 提高额度前,测试审批、驳回、重复调用、签名后超时、Webhook 投递失败和卖方对账。
常见问题
AI Agent 支付一定要使用 x402 吗?
从一般概念上说不一定,Agent 也可以参与其他支付流程。当前 StableOps Agent Payments 刻意只支持 x402 v2 exact GET 资源,而不是不受限制的转账。StableOps 收款产品不依赖 x402,也可以通过支付订单与托管收银台接收普通钱包付款。
AI Agent 需要接触钱包私钥吗?
不需要。Agent 运行时持有的是受限、可吊销的 Agent Key。客户自托管签名器把钱包密钥或 KMS 权限留在模型进程之外,只签署与有效短时执行授权完全一致的付款数据。
x402 已经结算,是否意味着卖方可以执行所有不可逆动作?
x402 资源服务器可以按协议层规则交付当前资源,但这不会自动完成卖方更广泛的业务流程。当收费由 StableOps 支付订单承载时,持久化记账与不可逆的下游工作应以已验证的 payment.finalized Webhook 为准,并保证这些操作幂等。
从一笔受控交易开始
先选择一个付费 GET 资源、一张 Base Sepolia USDC 卖方订单、一个买方 Agent,并设置刻意偏小的额度。按照 Agent Payments 快速开始配置买方,再用支付订单把卖方收款地址绑定到 x402 要求。确认付费响应、Agent Payment 记录、链上转账、卖方最终事件和业务账本全部一致后,再开启自动付款。
这个窄范围试点验证的正是 AI Agent 支付栈的价值:机器能够完成购买,即使交易偏离正常路径,买卖双方也不会失去必要的控制能力。
相关文章
把 x402 用在 HTTP 原生的智能体支付上,但商户侧的订单状态、策略、最终性、事件通知和审计仍要单独保留。
稳定币支付对账需要连接业务订单、支付事件与链上转账。本文讲解如何设计稳定外键、发现 Webhook 缺口,并执行日对账与月对账。
稳定币少付、多付、发错网络或过期后到账,都不应让订单被悄悄完成。本文说明如何发现、处理与预防各类支付不匹配。
稳定币支付没有唯一的最佳链:比较付款人侧费用、最终性与钱包分布,接受一组链,并把每笔转账精确匹配到订单。