# AI 辅助对接

不用逐页阅读文档：把本站的 **AI 资料包**交给 Claude、ChatGPT、Cursor 等编程助手，再配合下面的提示词，它就能按我们的签名、幂等和 Webhook 规范生成接入代码。

## 三步完成

1. **给 AI 资料。** 任选一种：
   - AI 能联网：把 `https://docs.potabank.com/llms-full.txt` 这个链接发给它。
   - AI 不能联网：下载 [llms-full.txt](https://docs.potabank.com/llms-full.txt)（全部指南与接口参考合并为一个文件），连同需要的 [OpenAPI 规范](https://docs.potabank.com/reference/index.md)一起上传。
2. **发送提示词。** 复制下面的提示词，把【】里的内容改成你自己的情况。
3. **提供凭证，但不要贴给 AI。** 让 AI 生成从环境变量读取凭证的代码，你在本地或部署环境里填写密钥。

## 提示词

```text title="对接提示词（复制后修改【】部分）" wrap
你是资深后端工程师。请帮我把 SeaFintech Gateway API 对接到我的系统。

资料：
- 如果你能访问网络，请先完整阅读 https://docs.potabank.com/llms-full.txt
- 否则使用我随后上传的 llms-full.txt 和 OpenAPI 文件

我的技术栈：【语言 / 框架 / 数据库，例如 Java 21 + Spring Boot + PostgreSQL】
我要对接的功能：【例如：PIX 代收 + 状态查询 + Webhook 入账】

工作方式：
1. 先用你自己的话复述接入方案：要调用哪些服务，各自用什么凭证和 Host，签名与幂等如何实现，Webhook 如何验签去重。同时列出你还缺哪些信息，等我确认后再写代码。
2. 凭证、私钥、Host 一律从环境变量读取。不要让我把它们贴给你，缺少的信息用占位符并向我提问，不要猜测。
3. 先实现签名模块，并写单元测试：用固定输入验证 payload 的 9 行拼接。
4. 再实现 Invoice / Transfer / Query 客户端（各自独立的 Host 和凭证）、幂等重试，以及 Webhook 接收端（原始 body 验签、事件去重、快速返回 2xx、异步处理）。
5. 最后对照文档中的「上线检查清单」逐项自检，输出未满足项。
```

## AI 必须遵守的规则

这些规则已经写在 `llms-full.txt` 的开头，AI 读取资料包时会自动看到；你也可以把它们直接贴进 `AGENTS.md`、`CLAUDE.md` 或 Cursor Rules，让 AI 在整个项目里持续遵守。

1. **先问再写。** 缺少 Host、凭证、`merchant_account_id`、回调域名或要对接的功能时，向用户提问；不要猜测，不要调用 `*.example.com`（它们只是文档占位地址）。
2. **三个服务三套配置。** Invoice（代收写、卡支付、Tokenization）、Transfer（代付写）、Query（只读）各自使用独立的 base URL 和独立凭证，客户端也分开实现；不要配置一个全局 `PSP_BASE_URL` 再动态拼服务路径。Checkout 地址使用 Invoice 响应返回的值，不要自行拼接。
3. **每个请求携带** `X-API-ID`、`X-API-Key`、`X-Timestamp`（Unix 秒，默认允许 ±60 秒偏差）、`X-Signature`（Ed25519 签名后的标准 Base64）；所有写请求另需 `X-Idempotency-Key` 或 `Idempotency-Key`，同时发送时必须相等。
4. **签名 payload** 由以下 9 行用单个 `\n` 连接，末尾不加换行：`v1`、`api_id`、`merchant_account_id`（凭证所属账户 UUID，小写带连字符）、`METHOD`（大写）、`escaped_path`（与实际发送的 path 完全一致，不含 query）、`canonical_query`（URL 解码后，同名参数的值升序、再按参数名升序，按 UTF-8 字节序，拼成 `key=value&…`；重新转义时保留 `A-Za-z0-9-_.~`、空格写 `+`、其余写大写 `%XX`；无值参数写成 `key=`；无 query 则为空串；含非法 `%` 转义或未转义 `;` 的 query 会被服务端以 `400` 拒绝，分号请写成 `%3B`）、`timestamp`、`idempotency_key`（优先取 `X-Idempotency-Key`，只读请求为空串）、`sha256(body)`（对实际发送的原始字节计算，**64 位小写十六进制**；空 body 也要计算，不要省略这一行）。对整个 payload 做 Ed25519 签名并输出标准 Base64。Invoice / Transfer / Query 三个服务使用同一种 payload 格式。**写完签名模块后必须用「认证与签名」页的测试向量验证，签名逐字符一致才算正确。**
5. **幂等。** 超时或连接断开后用相同 body、相同商户订单号、相同幂等键重试，只刷新 timestamp 并重新签名；不要换新订单号。结果仍不确定时用 Query API 确认。`400/401/403/409/422` 不自动重试；`429` 遵循 `Retry-After`；`5xx` 有限重试并加入退避与 jitter。
6. **金额使用最小货币单位的整数**（`10000 BRL` 表示 `R$ 100.00`）。
7. **Webhook。** 读取原始 body 验签，不要对解析后重新序列化的 JSON 验签：待验证消息 = `X-Timestamp` + `.` + 原始 body 字节，`X-Signature` 为标准 Base64 的 Ed25519 签名，用 `X-Webhook-Key-ID` 选择对应的 PSP 公钥（公钥与 key_id 来自账户 Webhook 配置，轮换时新旧两把要并存，不要写死）；同样用文档中的 Webhook 测试向量验证。去重键用 `X-Webhook-Event-ID`（不要用 `X-Timestamp`/`X-Signature`，它们每次重试都变）；先入库再返回 `2xx`，10 秒内返回响应头，耗时处理放到异步任务；验签失败返回 `401`（4xx 不会被自动重试）。投递是至少一次、可能重复、不保证顺序，终态不可回退；金额、币种、商户订单号和账户都与本地订单匹配后才能入账。**自动重试只有 5 次（退避 1/2/4/8/16 秒，约 31 秒窗口），所以必须实现定时 Query API 对账。** 未知的 `event` 记录后返回 `2xx`；各事件的 `data` 字段以「Webhook 事件目录」为准（`merchant_settlement.completed.v1` 的信封与其他事件不同）。回调地址必须是 HTTPS/443 的域名（不能是 IP 或内网地址）。
8. **密钥安全。** 私钥、API Key、签名、完整请求体和敏感付款信息一律不写入源码、日志或对话；只从环境变量或 Secret Manager 读取，分环境、分账户管理。
9. **文档没写明的细节不要猜。** 仍不明确的（例如某个字段的取值范围、具体业务规则）先查 OpenAPI 与文档，再向用户或接入团队确认，并用沙箱验证。
10. **交付前自检。** 对照「上线检查清单」逐项核对，输出未满足项。

## 可交给 AI 的资料

| 资料 | 地址 | 用途 |
|---|---|---|
| 完整资料包 | [/llms-full.txt](https://docs.potabank.com/llms-full.txt) | 全部指南 + 接口参考，推荐优先使用 |
| 资料索引 | [/llms.txt](https://docs.potabank.com/llms.txt) | 按页面列出的索引，适合能自行抓取链接的 AI |
| 单页 Markdown | 任意页面的 URL 后加 `.md`，或点击页面标题旁的「复制 Markdown」 | 只想让 AI 阅读某一页 |
| OpenAPI 规范 | [Invoice](https://docs.potabank.com/openapi/invoice.openapi.yaml) · [Transfer](https://docs.potabank.com/openapi/transfer.openapi.yaml) · [Query](https://docs.potabank.com/openapi/query.openapi.yaml) · [Webhook](https://docs.potabank.com/openapi/merchant-webhook.openapi.yaml) | 生成强类型客户端 |

## 让 AI 验收自己的代码

代码生成后，把下面这段发给 AI，再附上它写的代码：

```text title="自检提示词" wrap
请对照 https://docs.potabank.com/guide/go-live.md 的上线检查清单，逐项检查我的接入代码，
并重点核对：签名 payload 的 9 行顺序、幂等键在重试时是否沿用、Webhook 是否使用原始 body 验签、
日志中是否出现密钥或完整请求体。对每一项给出「通过 / 不通过 / 无法判断」和对应代码位置。
```

> **仍需人工把关**
>
AI 生成的代码必须在测试环境用真实凭证联调，并由你们的工程师评审后再上线。测试 Host 与凭证由接入团队提供，AI 无法替你获取。
