﻿
> 我之前在 App、小程序或网站经营，现在想让我的商品或服务可以被 Agent 调用，并在用户确认后使用支付宝完成支付。

如果你的服务已经接入了支付宝电脑网站支付，这份指南会带你在原有系统外增加一个“商家下单 Skill”。完成后，Agent 可以帮用户选择商品、创建订单，并在支付环节把流程交给支付宝支付处理 Skill。

这里的“上翻”可以理解为：不重写原来的电脑网站支付链路，只把原本需要用户在网页上完成的下单动作，包装成 Agent 能读懂、能执行的 Skill。

本文对应本仓库示例：

- 传统电脑网站支付服务：`app.js`
- 商家下单 Skill：`SKILL/SKILL.md`
- Skill 上翻适配脚本：`SKILL/references/create-cashier-url.js`

## 示例 Demo

请访问 [支付宝电脑网站支付 Demo - 运势预测（Node.js）](https://github.com/alipay/ai/tree/main/code_example/page-pay-demo-with-agentpay) 获取示例代码和配套商家下单 Skill。

这个 Demo 展示的是最小可理解链路：已有电脑网站支付服务，加一个商家下单 Skill，再通过支付宝支付处理 Skill 完成支付。

## 你会完成什么

接完之后，用户可以这样说：

```text
帮我购买一个今日运势预测服务，用支付宝支付。
```

Agent 会按你的商家下单 Skill 执行：

1. 确认用户要买什么。
2. 展示订单信息，让用户明确确认。
3. 调用 Skill 内的上翻适配脚本。
4. 上翻适配脚本请求你的服务端支付下单入口，例如 `POST http://localhost:3000/pay`。
5. 支付下单入口内部调用 `alipaySdk.pageExec(...)`，返回支付宝电脑网站支付 HTML POST 表单。
6. 上翻适配脚本把 HTML POST 表单转换成 `cashier_url`。
7. 调用 `alipay-bot` 生成 `paymentLink`。
8. 把完整 `paymentLink` 交给支付宝支付处理 Skill。

支付本身由支付宝支付处理 Skill 接管。你的 Skill 只需要把业务下单和支付交接做好。

## 适用场景

你已经接入：

- 支付宝 **电脑网站支付**

并且你的服务已经能做到：

- 展示商品、套餐、规格或服务项
- 在服务端创建订单
- 通过支付宝电脑网站支付返回 HTML POST 表单

如果这些已经具备，通常不用改你的收单产品，也不用重写服务端支付逻辑。你主要新增两样东西：

- 一个商家下单 Skill，告诉 Agent 怎么走你的下单流程
- 一个放在 Skill 里的上翻适配脚本，把下单接口返回的 HTML POST 表单转换成 `cashier_url`

## 先记住两个值

这一步最容易混淆。接入时请把 `cashier_url` 和 `paymentLink` 分清楚：

| 名称 | 它是什么 | 下一步怎么用 |
| --- | --- | --- |
| `cashier_url` | Skill 上翻适配脚本从支付宝 HTML POST 表单转换出的收银台链接 | 传给 `alipay-bot trigger-payment-signal` |
| `paymentLink` | `alipay-bot` 返回的支付接管信息 | 原样传给支付宝支付处理 Skill |

关于 `paymentLink`，只需要校验是否非空，不要校验它的前缀、格式或内部结构，也不要打开、展示、改写、重编码、压缩、截断或转换它。

## 整体流程

```mermaid
sequenceDiagram
    actor User as 用户
    participant Agent as Agent
    participant MerchantSkill as 商家下单 Skill
    participant MerchantServer as 商户服务端
    participant AlipayBot as alipay-bot
    participant PaySkill as 支付宝支付处理 Skill

    User->>Agent: 我要购买商品或服务
    Agent->>MerchantSkill: 加载商家下单 Skill
    MerchantSkill->>MerchantSkill: 收集信息并让用户确认订单
    MerchantSkill->>MerchantServer: 上翻适配脚本请求 POST /pay
    MerchantServer-->>MerchantSkill: 返回支付宝 HTML POST 表单
    MerchantSkill->>MerchantSkill: 将 HTML POST 表单转换成 cashier_url
    MerchantSkill->>AlipayBot: 用 cashier_url 生成 paymentLink
    AlipayBot-->>MerchantSkill: 返回 paymentLink
    MerchantSkill->>PaySkill: 传入完整 paymentLink
    PaySkill-->>Agent: 推进并返回支付处理结果
```

一句话概括：

```text
你的服务端下单接口返回 HTML POST 表单，商家下单 Skill 里的上翻适配脚本把它转换成 `cashier_url`，再用 `cashier_url` 生成 `paymentLink`，最后由支付宝支付处理 Skill 负责后续支付。
```

## 改造步骤

### 第一步：在 Skill 里准备一个表单转链接脚本

这个脚本属于商家下单 Skill，是上翻适配的一部分，建议放在 `references/` 目录。它不是商户服务端的下单接口。

它的作用是：

1. 请求你的服务端下单接口，例如 `POST http://localhost:3000/pay`（内部调用了 `alipaySdk.pageExec(...)` 发起电脑网站支付）。
2. 读取下单接口返回的支付宝电脑网站支付 HTML POST 表单。
3. 从表单中提取 `form action` 和 hidden input 字段。
4. 把这些表单参数转换成完整的 `cashier_url`。

本仓库示例里对应的是：

```bash
node references/create-cashier-url.js \
  --endpoint http://localhost:3000/pay \
  --zodiac 白羊座
```

这里的 `http://localhost:3000/pay` 才是真正的支付下单入口。它在 `app.js` 中对应 `app.post('/pay')`，内部调用 `alipaySdk.pageExec('alipay.trade.page.pay', 'POST', ...)`，并把返回的 HTML POST 表单响应给调用方。

`create-cashier-url.js` 会请求这个接口，拿到 HTML POST 表单，再输出类似结果：

```json
{
  "out_trade_no": "20260713123456789",
  "zodiac_sign": "白羊座",
  "result_endpoint": "http://localhost:3000/fortune-result",
  "cashier_url": "https://openapi.alipay.com/gateway.do?method=..."
}
```

你自己的项目里，脚本不一定要叫 `create-cashier-url.js`，也不一定要用 Node.js。只要它属于 Skill，能请求你的下单接口，并稳定把 HTML POST 表单转换成完整 `cashier_url`，Agent 就能继续下一步。

可以把这个脚本理解成一层很薄的上翻适配：下单接口仍然返回电脑网站支付常见的 POST 表单，脚本只负责把这个表单转换成后续 `alipay-bot` 可以接收的链接。

### 第二步：在 SKILL.md 里写清楚下单流程

商家下单 Skill 要让 Agent 知道：

- 什么时候应该使用这个 Skill
- 需要向用户确认哪些商品、规格、数量或服务参数
- 创建订单前要展示哪些信息
- 怎么调用 Skill 内的上翻适配脚本
- 上翻适配脚本要请求哪个服务端下单接口
- 怎么从 HTML POST 表单转换出 `cashier_url`
- 怎么用 `cashier_url` 生成 `paymentLink`
- `paymentLink` 非空后，怎么交给支付宝支付处理 Skill

推荐把下单前确认写得非常明确。Agent 在创建订单前，应让用户看到商品、规格、数量、金额和支付方式，并等待用户明确回复。

### 第三步：用 alipay-bot 生成 paymentLink

拿到 `cashier_url` 后，在商家下单 Skill 中调用：

```bash
alipay-bot trigger-payment-signal \
  --payment-link "<cashier_url>" \
  --merchant-info "<订单展示信息>" \
  --amount "<订单金额>"
```

这里容易混淆：`--payment-link` 是 `alipay-bot` 的入参名称，传进去的值是上一步生成的 `cashier_url`。命令执行完成后，返回 JSON 里的 `paymentLink` 字段才是后续要交给支付宝支付处理 Skill 的支付接管信息。

命令返回 JSON 后，只判断返回值中的 `paymentLink` 是否非空。

如果返回值中的 `paymentLink` 非空，立即加载支付宝支付处理 Skill，并把这个 `paymentLink` 的完整原始值传过去。

如果返回值中的 `paymentLink` 为空，停止流程，并告诉用户支付接管信息生成失败。

## 可直接改写的 Skill 模板

你可以把下面这段放进自己的 `SKILL.md`，再替换成你的商品和接口信息：

```markdown
## 支付流程

### Step 1：识别购买意图

当用户明确表达购买、下单、支付或订购服务意图时，执行本 Skill。

### Step 2：收集下单参数

根据业务需要获取商品、SKU、数量、服务参数等信息。
如果参数缺失，先向用户询问。
如果参数非法，停止并说明原因。

### Step 3：展示订单信息并等待确认

向用户展示商品名称、规格、数量、金额、支付方式等关键信息。
必须等待用户明确确认后，才可以创建订单。

### Step 4：调用上翻适配脚本生成 cashier_url

调用 Skill 内的上翻适配脚本，并传入商户服务端支付下单入口地址。
上翻适配脚本请求支付下单入口；支付下单入口创建订单，并通过 `alipaySdk.pageExec(...)` 返回支付宝电脑网站支付 HTML POST 表单。
上翻适配脚本从 HTML POST 表单中提取 form action 和 hidden input 字段，生成完整 cashier_url。
如果无法得到 cashier_url，停止并说明原因。

### Step 5：生成 paymentLink

调用 alipay-bot trigger-payment-signal：

alipay-bot trigger-payment-signal \
  --payment-link "<cashier_url>" \
  --merchant-info "<订单展示信息>" \
  --amount "<订单金额>"

解析命令返回的 JSON。
注意：--payment-link 是命令入参名称，传入值是 cashier_url；命令返回 JSON 中的 paymentLink 字段才是后续交给支付宝支付处理 Skill 的值。
只校验返回 JSON 中 paymentLink 是否为非空值。
不要校验 paymentLink 的前缀、格式或内部结构。

### Step 6：加载支付宝支付处理 Skill

如果返回 JSON 中的 paymentLink 非空，立即加载并调用支付宝支付处理 Skill。
必须将返回 JSON 中 paymentLink 的完整原始值传给支付宝支付处理 Skill。
不要打开、展示、改写、重编码、压缩、截断或转换 paymentLink。
不要将 cashier_url 直接传给支付宝支付处理 Skill。

如果返回 JSON 中的 paymentLink 为空，停止并说明支付接管信息生成失败。
```

## 本仓库示例怎么对应

本仓库示例是一个“今日运势预测”商品。它的上翻方式可以按下面理解：

| 你要做的事 | 示例里在哪里 |
| --- | --- |
| 原有电脑网站支付服务 | `app.js` |
| Agent 可执行的商家下单说明 | `SKILL/SKILL.md` |
| 服务端下单接口 | `POST http://localhost:3000/pay` |
| 电脑网站支付表单来源 | `app.js` 中的 `alipaySdk.pageExec('alipay.trade.page.pay', 'POST', ...)` |
| Skill 上翻适配脚本，将 HTML POST 表单转换成收银台链接 | `SKILL/references/create-cashier-url.js` |
| 交给支付宝支付处理 Skill 的值 | `alipay-bot` 返回的 `paymentLink` |

示例 Skill 的关键链路是：

1. 校验用户选择的星座。
2. 调用 `create-cashier-url.js`。
3. `create-cashier-url.js` 请求 `POST http://localhost:3000/pay` 创建订单。
4. `/pay` 内部调用 `alipaySdk.pageExec(...)` 返回 HTML POST 表单。
5. `create-cashier-url.js` 将 HTML POST 表单转换成 `cashier_url`。
6. 调用 `alipay-bot trigger-payment-signal`。
7. 校验 `paymentLink` 非空。
8. 把完整 `paymentLink` 交给支付宝支付处理 Skill。

# 联调环境准备

### 安装支付宝买家侧相关 Skill 与命令

开发和联调前，请安装支付宝相关 Skill 与 `alipay-bot` 命令：

```bash
npx -y @alipay/agent-payment@latest install
```

也可以让 Agent 执行：

```text
帮我装一下支付宝的 Skill，安装命令是 npx -y @alipay/agent-payment@latest install
```

安装后，可以用下面两条命令检查环境：

```bash
npm --version
which alipay-bot
```

如果找不到 `alipay-bot`，先重新执行安装命令，再继续联调。

## 联调建议

建议按从小到大的顺序联调：

1. 先确认商户服务端下单接口能正常创建订单。
2. 再确认下单接口能返回支付宝电脑网站支付 HTML POST 表单。
3. 单独运行你的 `create-cashier-url` 脚本，确认它能请求下单接口，并把 HTML POST 表单转换成非空 `cashier_url`。
4. 使用 `alipay-bot trigger-payment-signal`，确认能返回非空 `paymentLink`。
5. 最后从用户自然语言触发商家下单 Skill，观察是否能进入支付宝支付处理 Skill。

支付宝相关 Skill 有两个：

| Skill | 用途 |
| --- | --- |
| 支付宝支付服务开通和授权 Skill | 开启支付宝支付功能，查询开通状态 |
| 支付宝支付处理 Skill | 根据 `paymentLink` 推进支付，查询刚刚的订单状态 |

联调时，建议先使用支付宝支付服务开通和授权 Skill，按指引开通支付宝支付功能。之后再触发你的商家下单 Skill，检查支付环节是否正确交给支付宝支付处理 Skill。

## 发布前检查

发布前，用这张清单快速过一遍：

- [ ] 用户进入下单环节时，会看到商品、SKU、数量、价格、支付方式等信息
- [ ] 创建订单前，会等待用户明确确认
- [ ] 服务端下单接口可以返回支付宝电脑网站支付 HTML POST 表单
- [ ] Skill 内的上翻适配脚本可以把 HTML POST 表单转换成完整的 `cashier_url`
- [ ] `cashier_url` 只用于调用 `alipay-bot trigger-payment-signal`
- [ ] 非空 `paymentLink` 会逐字符完整传给支付宝支付处理 Skill
- [ ] 不会打开、展示、改写、重编码、压缩、截断或转换 `paymentLink`
- [ ] 不会把 `cashier_url` 直接传给支付宝支付处理 Skill
- [ ] 失败时会停止流程，并给出用户能理解的原因

## 常见问题

| 现象                 | 常见原因                              | 怎么处理                                                        |
| ------------------ | --------------------------------- | ----------------------------------------------------------- |
| 分不清下单接口和上翻脚本       | 把 `create-cashier-url.js` 当成服务端接口 | `POST /pay` 是下单接口，`create-cashier-url.js` 是 Skill 内的表单转链接脚本 |
| 支付宝支付处理 Skill 没有接管 | 直接传了 `cashier_url`                | 先用 `alipay-bot trigger-payment-signal` 生成 `paymentLink`     |
| 支付失败或无法继续          | 支付信息被截断、展示后复制错、或被重新编码             | 全程逐字符保留原始值                                                  |
| 用户还没确认就创建了订单       | Skill 没写清楚确认节点                    | 下单前展示订单信息，并等待用户明确确认                                         |
| 找不到 `alipay-bot`   | 没安装支付宝相关 Skill 与命令                | 执行 `npx -y @alipay/agent-payment@latest install`            |


# 发布方式

本地联调通过，只能说明你的商家下单 Skill 在开发环境里可以跑通。要让真实用户的 Agent 使用它，还需要把这个 Skill 发布或分发出去。

这里发布的不是你的收银服务，也不是支付宝支付处理 Skill，而是你的商家下单 Skill。它通常包含：

- `SKILL.md`：告诉 Agent 什么时候触发、怎么下单、怎么交给支付宝支付处理 Skill
- `references/create-cashier-url.js` 这类上翻适配脚本：负责请求你的支付下单入口，并把 HTML POST 表单转换成 `cashier_url`
- 安装说明和使用示例：让用户知道怎么安装、怎么发起购买

如果 Skill 只存在于你的本地开发目录里，用户的 Agent 无法发现它，也就无法在用户说“帮我购买……”时自动进入你的下单流程。发布之后，用户可以通过 clawhub、GitHub 或你提供的一键安装脚本安装这个 Skill；安装完成后，Agent 才能加载它并完成后续的下单和支付交接。

发布前，建议先准备好三样东西：

- Skill 名称：用户和 Agent 能识别的名称
- 安装入口：clawhub 链接、GitHub 仓库，或一键安装脚本
- 使用示例：告诉用户如何一句话触发购买

### 开源方案

1. 推送你的 Skill 到 clawhub。
2. 在 GitHub 中同步建立仓库，并在文档中增加 clawhub 链接。
3. 在你的官网中增加 clawhub 和 GitHub 地址。

### 闭源方案

在你的官网提供一键安装或更新脚本，例如：

```bash
npx -y your-skill-installer@latest install
```

### 用户使用指令

你的文档中应提供一句话安装指令和一句话使用示例。

安装示例：

```text
从 clawhub 帮我安装 [你的 Skill 名称]
```

或：

```text
帮我安装 [你的 Skill 名称]：[你的一键安装脚本]
```

使用示例：

```text
帮我购买一个今日运势预测服务，用支付宝支付。
```

推荐在发布文档中补一句：

```text
该 Skill 会在用户确认订单后生成支付接管信息，并调用支付宝支付处理 Skill 完成支付流程。
```
