跳到主要内容

支付宝收款 (Payments)

当 Agent 需要向用户收款时,它会在对话里放出一张支付宝 (Alipay) 收款卡片;SDK 负责帮你把这张卡片渲染出来、并在用户付款后让它自动结算。 你不用对接支付宝网关、不用管签名与回调——收款单由平台按 Agent 所有者配置的连接器发起,SDK 只处理"展示卡片 + 感知付款结果"这两件事。

前提:Agent 的所有者需先在「应用」里配置好支付宝连接器。是否走真实交易还是沙箱由服务端的连接器决定(alipayalipay_sandbox),SDK 侧没有环境参数,同一段代码对两者都适用。

收款是怎么发生的

  1. 你像平常一样用 SDK 发消息(见 对话 (Chat))。
  2. Agent 在需要收款时调用内置的 create_payment 工具,平台向对话流里推一条 payment_gate 事件,里面带着这张卡片的数据(金额、事由、二维码或收银台链接)。
  3. 你把卡片渲染给用户:扫码付,或点按钮跳支付宝收银台。
  4. 用户付款后,平台推一条 payment_gate_resolution 事件——卡片即时翻成"已支付"。若回调延迟,你还可以用 client.payments.status(orderId) 主动查询兜底。

收款卡片的数据结构

payment_gate 事件里的 PaymentGatePayload:

字段类型说明
orderIdstring订单号——结算事件与状态查询的关联键
amountCnynumber金额(人民币元)
reasonstring?收款事由,展示在卡片上
mode'qr' | 'redirect' | 'auto'卡片呈现方式:扫码 / 跳收银台 / 自适应(宽屏扫码、窄屏按钮)
qrCodestring?当面付二维码字符串(qr / auto),渲染成二维码
payUrlstring?收银台 URL(redirect / auto),在新标签打开
status'pending' | 'paid' | 'expired' | 'canceled'推送时的状态,随结算事件或状态查询更新

⚠️ 不要在渲染时判断"真实还是沙箱"——环境由服务端连接器固定,卡片对两者完全一致。正是这一点,保证了真实商户永远不会被错误地走进沙箱代码路径。

在原生 JS / TS 里处理

用事件工具从流里识别收款卡片与结算信号:

import {
OpenhexClient,
extractPaymentGate,
extractPaymentResolution,
} from '@openhex-ai/agent-sdk';

const client = new OpenhexClient({ apiKey, agentId });

for await (const record of client.runTurn('帮我买一份 VIP 会员')) {
// 1. 收款卡片
const gate = extractPaymentGate(record);
if (gate) {
renderPayCard(gate); // 你的渲染:gate.mode === 'qr' 用 gate.qrCode,否则用 gate.payUrl
continue;
}
// 2. 付款结算(即时翻牌)
const settled = extractPaymentResolution(record);
if (settled && settled.status === 'paid') {
markPaid(settled.orderId);
}
}

也可以用 isPaymentGate(record) 只做布尔判断。

主动查询兜底

当支付宝回调延迟、或没配公网回调地址时,payment_gate_resolution 可能来得晚。用状态查询兜底:

const { status, amountCny } = await client.payments.status(orderId);
// status: 'pending' | 'paid' | 'expired' | 'canceled'

一个订单只用 orderId 定位,不需要传环境——真实/沙箱由服务端决定。

在 React 里处理

React 集成把上面这套都封装好了:hook 会把收款卡片挂到对应消息上、并自动轮询未结算的订单;PaymentGateCard 负责渲染扫码 / 按钮。

import { useOpenhexChat, PaymentGateCard } from '@openhex-ai/agent-sdk/react';

function Chat() {
const chat = useOpenhexChat({ connection: { apiKey, agentId } });

return (
<>
{chat.messages.map(m => (
<div key={m.id}>
{m.text}
{m.paymentGate && <PaymentGateCard gate={m.paymentGate} />}
</div>
))}
</>
);
}

卡片文案可用 labels 覆盖(默认取 DEFAULT_PAYMENT_LABELS):

<PaymentGateCard gate={m.paymentGate} labels={{ payNow: '立即支付', paid: '已到账' }} />

下一步