@alipay/alipay-aipay 1.2.2 → 1.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +13 -12
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +17 -9
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +5 -5
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/utils/config.d.ts +5 -3
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +34 -12
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/file.d.ts +8 -0
- package/dist/utils/file.d.ts.map +1 -1
- package/dist/utils/file.js +161 -9
- package/dist/utils/file.js.map +1 -1
- package/dist/utils/jq.d.ts.map +1 -1
- package/dist/utils/jq.js +8 -0
- package/dist/utils/jq.js.map +1 -1
- package/package.json +6 -5
- package/skill/SKILL.md +15 -169
- package/skill/VERSION +1 -1
- package/skill/references/integration/flow.md +321 -292
- package/skill/references/integration/modules/alipay-sdk-reminder.md +5 -3
- package/skill/references/integration/modules/checklist.md +41 -27
- package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +199 -0
- package/skill/references/integration/modules/code-examples/csharp/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +8 -4
- package/skill/references/integration/modules/code-examples/csharp/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +6 -2
- package/skill/references/integration/modules/code-examples/csharp/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.cs +3 -1
- package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +184 -0
- package/skill/references/integration/modules/code-examples/java/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +4 -1
- package/skill/references/integration/modules/code-examples/java/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +5 -2
- package/skill/references/integration/modules/code-examples/java/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemoController.java +3 -1
- package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +135 -0
- package/skill/references/integration/modules/code-examples/nodejs/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +16 -10
- package/skill/references/integration/modules/code-examples/nodejs/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +10 -4
- package/skill/references/integration/modules/code-examples/nodejs/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.js +2 -1
- package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +157 -0
- package/skill/references/integration/modules/code-examples/php/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +4 -1
- package/skill/references/integration/modules/code-examples/php/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +5 -2
- package/skill/references/integration/modules/code-examples/php/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.php +2 -1
- package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +128 -0
- package/skill/references/integration/modules/code-examples/python/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +4 -1
- package/skill/references/integration/modules/code-examples/python/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +5 -1
- package/skill/references/integration/modules/code-examples/python/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.py +4 -2
- package/skill/references/integration/modules/interface-contract/aipay-interface-contract.md +53 -0
- package/skill/references/integration/modules/interface-contract/apppay-interface-contract.md +45 -0
- package/skill/references/integration/modules/interface-contract/common-trade-contract.md +42 -0
- package/skill/references/integration/modules/interface-contract/notify-url-contract.md +68 -0
- package/skill/references/integration/modules/interface-contract/webpay-interface-contract.md +44 -0
- package/skill/references/integration/modules/interface-guide.md +37 -72
- package/skill/references/integration/modules/product-decision.md +10 -27
- package/skill/references/integration/modules/sandbox/a2m-sandbox-test.md +62 -94
- package/skill/references/integration/modules/sandbox/alipay-sandbox-tool.md +43 -40
- package/skill/references/integration/modules/sandbox/sandbox-setup-guide.md +93 -114
- package/skill/references/integration/modules/scripts/local_402_sandbox_pay.py +357 -147
- package/skill/references/integration/modules/scripts/sandbox_config.sh +299 -0
- package/skill/references/integration/modules/troubleshooting-flow.md +28 -0
- package/skill/references/normal/alipay-cli-env.md +15 -5
- package/skill/references/normal/full-process-routing.md +80 -0
- package/skill/references/normal/json/customer-messages.json +937 -0
- package/skill/references/normal/json/policy-rules.json +179 -0
- package/skill/references/normal/rejection-guide.md +11 -6
- package/skill/references/normal/scripts/alipay_cli_env.mjs +29 -0
- package/skill/references/normal/scripts/alipay_cli_env.sh +21 -0
- package/skill/references/normal/scripts/common.sh +87 -0
- package/skill/references/normal/scripts/detect_dev_tool.sh +5 -1
- package/skill/references/normal/scripts/integration_message_runner.mjs +801 -0
- package/skill/references/normal/scripts/onboarding_message_runner.mjs +436 -0
- package/skill/references/normal/scripts/open_official_url.sh +82 -0
- package/skill/references/normal/scripts/platform_compat.mjs +39 -0
- package/skill/references/normal/scripts/project_route_inspector.sh +132 -0
- package/skill/references/normal/scripts/python_script_runner.mjs +56 -0
- package/skill/references/normal/scripts/render_customer_message.mjs +1263 -0
- package/skill/references/normal/scripts/self_update.mjs +160 -0
- package/skill/references/normal/scripts/telemetry.mjs +1278 -0
- package/skill/references/normal/self-update.md +18 -51
- package/skill/references/onboarding/flow.md +381 -283
- package/skill/references/onboarding/modules/app-release.md +132 -179
- package/skill/references/onboarding/modules/authorization.md +53 -64
- package/skill/references/onboarding/modules/error-handling.md +31 -34
- package/skill/references/onboarding/modules/product-sign.md +62 -66
- package/skill/references/onboarding/modules/scripts/app.sh +397 -158
- package/skill/references/onboarding/modules/scripts/ar_sign_apply.sh +38 -22
- package/skill/references/onboarding/modules/scripts/auth.sh +479 -167
- package/skill/references/onboarding/modules/scripts/download_key_tool.sh +157 -0
- package/skill/references/onboarding/modules/scripts/error_handler.sh +100 -130
- package/skill/references/onboarding/modules/scripts/network_retry.sh +96 -0
- package/skill/references/onboarding/modules/scripts/query_sign_status.sh +17 -70
- package/skill/references/onboarding/modules/scripts/service.sh +153 -89
- package/skill/references/onboarding/modules/scripts/sign_status_parser.sh +58 -0
- package/skill/references/onboarding/modules/scripts/upload_screenshots.sh +16 -14
- package/skill/references/onboarding/modules/service-registration.md +67 -72
- package/skill/references/runtime-entry.md +62 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 按量付费沙箱测试
|
|
2
2
|
|
|
3
|
-
> ⚠️ **仅当产品为「按量付费」时执行本文档定义的联调**。网站支付不执行本文档,但仍必须按 `sandbox-setup-guide.md` 第 5.
|
|
3
|
+
> ⚠️ **仅当产品为「按量付费」时执行本文档定义的联调**。网站支付不执行本文档,但仍必须按 `sandbox-setup-guide.md` 第 5.5 节完成网站支付沙箱付款提示;APP 支付按集成主流程跳过步骤 6。
|
|
4
4
|
|
|
5
5
|
本文档定义按量付费 402 协议的沙箱端到端服务端联调流程。测试脚本位于 `../scripts/local_402_sandbox_pay.py`。
|
|
6
6
|
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
|
|
13
13
|
在执行此步骤前,必须满足:
|
|
14
14
|
|
|
15
|
-
1. **已完成步骤
|
|
15
|
+
1. **已完成步骤 5 代码生成**:按量付费集成代码已生成并整合进用户项目
|
|
16
16
|
2. **用户本地服务已启动**:服务端已运行在可访问的地址上(如 `http://localhost:5000/demo/a2m/resource`)
|
|
17
|
-
3. **已知沙箱买家 2088 账号**:从步骤
|
|
17
|
+
3. **已知沙箱买家 2088 账号**:从步骤 3 沙箱配置中获取实际 `userId`(例如 `<SANDBOX_BUYER_USER_ID>`)
|
|
18
18
|
4. **Python 3 可用**:测试脚本依赖 Python 3 运行
|
|
19
19
|
5. **已使用沙箱服务 ID**:用户服务的沙箱运行配置中 `serviceId` 固定为 `api_mock_service_id`,不要向用户索要正式 `serviceId`
|
|
20
20
|
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
## 测试前预检
|
|
24
24
|
|
|
25
|
-
执行沙箱测试脚本前,先解码服务返回的 `Payment-Needed`,确认关键字段存在。`SERVICE_URL` 使用用户实际服务地址。
|
|
25
|
+
执行沙箱测试脚本前,先解码服务返回的 `Payment-Needed`,确认关键字段存在。`SERVICE_URL` 使用用户实际服务地址。Unix/macOS/Linux 继续执行既有命令:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
curl -s -D - -o /dev/null "$SERVICE_URL" \
|
|
@@ -55,6 +55,13 @@ print("已校验字段: " + ", ".join(f"{path[0]}.{path[1]}" for path in require
|
|
|
55
55
|
|
|
56
56
|
POST 服务将首行 curl 替换为 `curl -s -D - -o /dev/null -X POST -H "Content-Type: ${CONTENT_TYPE:-application/json}" -d "$BODY" "$SERVICE_URL"`。`seller_signature` 由代码示例中的 `generateSellerSignature` / `generate_seller_signature` 生成,签名入参中的 `service_id` 与 `method.service_id` 都必须使用 `api_mock_service_id`;禁止使用空值、其他占位符或要求用户提供正式 `serviceId`。预检输出只打印校验结论和字段名,不打印字段值。
|
|
57
57
|
|
|
58
|
+
Windows 不使用管道或固定的 `python3` 命令名,从本文件所在目录按实际方法执行对应单行命令;`precheck` 只请求本地服务和校验 HTTP 402/字段,不调用沙箱收银:
|
|
59
|
+
|
|
60
|
+
```powershell
|
|
61
|
+
node ../../../normal/scripts/python_script_runner.mjs ../scripts/local_402_sandbox_pay.py precheck --url "$SERVICE_URL" --method GET
|
|
62
|
+
node ../../../normal/scripts/python_script_runner.mjs ../scripts/local_402_sandbox_pay.py precheck --url "$SERVICE_URL" --method POST --body "@$POST_BODY_FILE"
|
|
63
|
+
```
|
|
64
|
+
|
|
58
65
|
---
|
|
59
66
|
|
|
60
67
|
## 测试脚本路径
|
|
@@ -63,19 +70,19 @@ POST 服务将首行 curl 替换为 `curl -s -D - -o /dev/null -X POST -H "Conte
|
|
|
63
70
|
python3 ../scripts/local_402_sandbox_pay.py
|
|
64
71
|
```
|
|
65
72
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
Windows 使用 `node ../../../normal/scripts/python_script_runner.mjs ../scripts/local_402_sandbox_pay.py`;启动器只允许该内置脚本,并按系统选择可用的 Python 3 命令。
|
|
74
|
+
|
|
75
|
+
脚本只提供 `run` 子命令,并要求使用 `--auto-complete` 在同一次命令内获取 Payment-Needed、调用沙箱收银和携带 Payment-Proof 重试原始服务。不存在跨轮 `complete` 或恢复命令。
|
|
69
76
|
|
|
70
77
|
---
|
|
71
78
|
|
|
72
79
|
## 完成条件
|
|
73
80
|
|
|
74
|
-
- [
|
|
75
|
-
- [
|
|
76
|
-
- [
|
|
77
|
-
- [
|
|
78
|
-
- [
|
|
81
|
+
- [INT.A2M.SERVICE_READY] 已确认用户本地按量付费服务已启动可访问
|
|
82
|
+
- [INT.A2M.PRECHECK_PASSED] 已完成 Payment-Needed 预检,确认 HTTP 402 和关键字段存在
|
|
83
|
+
- [INT.A2M.AUTO_COMPLETE_RUN] 已执行沙箱支付测试脚本 `run --auto-complete`,成功获取 Payment-Needed、生成付款链接并连续执行服务端联调
|
|
84
|
+
- [INT.A2M.DELIVERY_EVIDENCE] 已携带 Payment-Proof 重试原服务并取得 HTTP 200、非空可归属资源、无明确业务失败和有效 Payment-Validation 证据
|
|
85
|
+
- [INT.A2M.TEST_PASSED] 已确认 402 沙箱服务端联调流程通过
|
|
79
86
|
|
|
80
87
|
---
|
|
81
88
|
|
|
@@ -91,7 +98,7 @@ python3 ../scripts/local_402_sandbox_pay.py
|
|
|
91
98
|
**确定测试参数**:
|
|
92
99
|
- `SERVICE_URL`:本地服务请求地址(含 GET 参数,如 `http://localhost:5000/demo/a2m/resource?gift=demo`)
|
|
93
100
|
- `HTTP_METHOD`:`GET` 或 `POST`
|
|
94
|
-
- `BUYER_2088`:沙箱买家 2088
|
|
101
|
+
- `BUYER_2088`:沙箱买家 2088 账号(实际 `userId`,例如 `<SANDBOX_BUYER_USER_ID>`)
|
|
95
102
|
|
|
96
103
|
> ⚠️ 只有缺少无法从当前上下文取得的真实值时,才询问用户对应信息。不要编造买家账号,也不得将补齐参数变成“是否执行测试”的确认。参数和服务就绪后,向用户输出测试说明并直接进入第二步。
|
|
97
104
|
|
|
@@ -99,13 +106,13 @@ python3 ../scripts/local_402_sandbox_pay.py
|
|
|
99
106
|
|
|
100
107
|
**⚠️ 脚本的收银接口地址和付款链接前缀已硬编码在脚本中(`PAY_ENDPOINT`、`PAY_URL_PREFIX`),执行时无需额外指定。**
|
|
101
108
|
|
|
102
|
-
|
|
109
|
+
使用 `../../../normal/json/customer-messages.json` 的 `a2m.test.start` 渲染固定联调说明,然后立即运行脚本,不等待用户确认。服务地址和 HTTP 方法只用于实际联调命令,不在本消息中展示。必须执行:
|
|
103
110
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
111
|
+
```bash
|
|
112
|
+
node ../../../normal/scripts/integration_message_runner.mjs a2m-test-start
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
不得在模块或 Agent 回复中维护第二份近似开始话术。
|
|
109
116
|
|
|
110
117
|
GET 请求:
|
|
111
118
|
|
|
@@ -114,7 +121,8 @@ python3 ../scripts/local_402_sandbox_pay.py run \
|
|
|
114
121
|
--url "$SERVICE_URL" \
|
|
115
122
|
--method GET \
|
|
116
123
|
--buyer-id "$BUYER_2088" \
|
|
117
|
-
--auto-complete
|
|
124
|
+
--auto-complete \
|
|
125
|
+
--require-payment-validation
|
|
118
126
|
```
|
|
119
127
|
|
|
120
128
|
POST 请求:
|
|
@@ -125,7 +133,15 @@ python3 ../scripts/local_402_sandbox_pay.py run \
|
|
|
125
133
|
--method POST \
|
|
126
134
|
--body "$BODY" \
|
|
127
135
|
--buyer-id "$BUYER_2088" \
|
|
128
|
-
--auto-complete
|
|
136
|
+
--auto-complete \
|
|
137
|
+
--require-payment-validation
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Windows 从本文件所在目录按实际 HTTP 方法执行对应单行命令:
|
|
141
|
+
|
|
142
|
+
```powershell
|
|
143
|
+
node ../../../normal/scripts/python_script_runner.mjs ../scripts/local_402_sandbox_pay.py run --url "$SERVICE_URL" --method GET --buyer-id "$BUYER_2088" --auto-complete --require-payment-validation
|
|
144
|
+
node ../../../normal/scripts/python_script_runner.mjs ../scripts/local_402_sandbox_pay.py run --url "$SERVICE_URL" --method POST --body "@$POST_BODY_FILE" --buyer-id "$BUYER_2088" --auto-complete --require-payment-validation
|
|
129
145
|
```
|
|
130
146
|
|
|
131
147
|
**脚本执行步骤**:
|
|
@@ -138,71 +154,60 @@ python3 ../scripts/local_402_sandbox_pay.py run \
|
|
|
138
154
|
7. POST 到沙箱收银接口 `http://aicashier.dl.alipaydev.com/openclawpay/agent/v1/pay`
|
|
139
155
|
8. 生成浏览器付款链接
|
|
140
156
|
9. 使用同一过程产物构建 Payment-Proof 并重试原始服务
|
|
141
|
-
10.
|
|
157
|
+
10. 仅在 HTTP 200、非空且可归属的资源、无明确业务失败,并且当前示例要求的 `Payment-Validation` 校验通过时输出服务端联调成功
|
|
158
|
+
11. 命令结束前清理敏感过程产物;失败后重新执行完整联调,不保存跨轮恢复状态
|
|
142
159
|
|
|
143
160
|
**脚本输出**:
|
|
144
|
-
- Payment-Needed
|
|
161
|
+
- Payment-Needed 获取结果(终端不输出原始值)
|
|
145
162
|
- 脱敏后的账单 JSON
|
|
146
163
|
- 脱敏后的收银接口请求体
|
|
147
164
|
- 收银接口返回
|
|
148
165
|
- **浏览器付款链接**(格式:`https://render.alipay.com/p/yuyan/180020010001290755/pay.html?schema=...`)
|
|
149
|
-
-
|
|
150
|
-
- Payment-Proof 重试后的服务响应与测试结论
|
|
166
|
+
- Payment-Proof 重试后的服务响应与测试结论;`Payment-Validation` 原始值不在终端输出
|
|
151
167
|
|
|
152
168
|
**错误处理**:
|
|
153
169
|
- 沙箱化 Agent 环境执行本脚本时,首次执行即申请可联网权限;如果已因网络受限失败,复用同一条命令申请可联网权限重试
|
|
154
170
|
- 如果未找到 `Payment-Needed` 响应头,确认服务端是否实现了 402 协议
|
|
155
171
|
- 如果收银接口返回 `PARAM_INVALID: protocol.sellerSignature不能为空`,回到预检步骤检查 `protocol.seller_signature` 是否为空、缺失或仍是占位符
|
|
156
172
|
- 如果 `pay_before` 相关参数报错,检查是否使用 ISO 8601 带时区格式
|
|
157
|
-
- 如果收银接口返回 `PAY_SUBMIT_FAILED`、`系统繁忙`
|
|
158
|
-
```bash
|
|
159
|
-
python3 ../scripts/local_402_sandbox_pay.py run \
|
|
160
|
-
--reuse-artifact "$ARTIFACT_DIR" \
|
|
161
|
-
--auto-complete
|
|
162
|
-
```
|
|
163
|
-
`--reuse-artifact` 会复用上一轮产物中的 `Payment-Needed`、服务 URL、HTTP 方法、POST 请求体和 Content-Type。脚本不会重新请求用户服务生成新订单。这样可以避免本地内存订单堆积,导致后续 `ORDER_NOT_FOUND` 或多订单兜底匹配失败。
|
|
164
|
-
- `run` 命令支持 `--pay-retries` 和 `--pay-retry-delay`,用于调大沙箱收银接口临时失败时的重试次数与间隔。
|
|
173
|
+
- 如果收银接口返回 `PAY_SUBMIT_FAILED`、`系统繁忙` 等已识别临时错误,脚本只在同一次命令内按既有预算自动重试;仍失败时清理本轮敏感产物并停止。除联网权限恢复后重试同一完整命令外,Agent 不得通过重复执行 `run --auto-complete`、追加 `--pay-retries`/`--pay-retry-delay` 或手工复用上轮 Payment-Needed 来扩大远程写动作重试范围;必须先修复服务实现、等待沙箱服务恢复,或按实际错误给出恢复动作后再重新发起完整联调。
|
|
165
174
|
|
|
166
175
|
### 第三步:连续验证 Payment-Proof 重试
|
|
167
176
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
如果标准命令在生成付款链接后因进程中断而未完成最终重试,使用同一过程产物恢复:
|
|
171
|
-
|
|
172
|
-
```bash
|
|
173
|
-
python3 ../scripts/local_402_sandbox_pay.py complete \
|
|
174
|
-
--artifact-dir "$ARTIFACT_DIR"
|
|
175
|
-
```
|
|
177
|
+
标准流程只使用第二步命令中的 `--auto-complete`。脚本生成付款链接后,在同一次进程内继续构建 Payment-Proof、重试原始服务并输出结果;进程中断后重新执行完整联调。
|
|
176
178
|
|
|
177
179
|
**脚本执行步骤**:
|
|
178
180
|
1. 读取过程产物目录中的 `state.json`
|
|
179
181
|
2. 使用前面沙箱收银接口下单返回的 `trade_no` 构建 `Payment-Proof` 请求头(含 `payment_proof`、`trade_no`、`client_session`)
|
|
180
182
|
3. 携带 `Payment-Proof` 请求头重试原始服务地址
|
|
181
|
-
4.
|
|
183
|
+
4. 校验最终服务响应并打印脱敏结论;不打印 `Payment-Validation` 原始值
|
|
184
|
+
5. 成功后安全清理敏感过程产物
|
|
182
185
|
|
|
183
186
|
**Payment-Proof 处理约束**:
|
|
184
187
|
- `trade_no` 必须使用前面沙箱收银接口返回并写入 `state.json` 的交易号;不得改用商户侧 `out_trade_no` 或重新生成。
|
|
185
188
|
- `payment_proof`、`client_session` 和最终请求头由脚本按沙箱联调约定自动处理;Agent 不得手工拼接、改写或向用户展开其原始值和内部处理规则。
|
|
186
|
-
-
|
|
189
|
+
- 进程中断后只能在确认上次命令未取得可用过程产物时重新执行完整 `run --auto-complete` 联调,不复用旧过程产物;明确业务失败、服务实现失败或脚本已输出失败结论时,禁止立即重复执行同一联调命令刷远程动作,必须先处理失败原因。
|
|
187
190
|
|
|
188
191
|
Payment-Proof 参考结构:
|
|
189
192
|
|
|
190
193
|
```json
|
|
191
194
|
{
|
|
192
195
|
"protocol": {
|
|
193
|
-
"payment_proof": "
|
|
194
|
-
"trade_no": "
|
|
196
|
+
"payment_proof": "<脚本生成并保存到受限权限过程产物,禁止对客展示>",
|
|
197
|
+
"trade_no": "<沙箱收银接口实际返回的交易号>"
|
|
195
198
|
},
|
|
196
199
|
"method": {
|
|
197
|
-
"client_session": "
|
|
200
|
+
"client_session": "<脚本生成并保存到受限权限过程产物,禁止对客展示>"
|
|
198
201
|
}
|
|
199
202
|
}
|
|
200
203
|
```
|
|
201
204
|
|
|
202
205
|
**验证要点**:
|
|
203
|
-
-
|
|
204
|
-
-
|
|
205
|
-
-
|
|
206
|
+
- 服务必须返回 HTTP 200;任意其他状态(包括 204)均失败
|
|
207
|
+
- JSON 响应体必须同时包含非空 `resource_id` / `resourceId` 和非空 `content`;非 JSON 资源必须有可验证的 `Payment-Validation` 证明归属
|
|
208
|
+
- 响应中不得存在当前五语言示例已经定义的明确验付、资源或履约失败,如 `VERIFY_FAILED`、`RESOURCE_ID_MISMATCH`、`FULFILLMENT_CONFIRM_FAILED`
|
|
209
|
+
- 当前五语言示例实现了 `Payment-Validation`,标准命令必须传 `--require-payment-validation`;响应头必须能解码为 JSON,且包含 `validated=true`、非空 `trade_no` / `tradeNo` 和 `resource_id` / `resourceId`,资源 ID 必须与响应体一致
|
|
210
|
+
- 只有以上证据同时成立,脚本退出码才为 0,才能输出“沙箱服务端联调通过”
|
|
206
211
|
|
|
207
212
|
**常见失败与排查**:
|
|
208
213
|
- `ORDER_NOT_FOUND`:`alipay.aipay.agent.payment.verify` 成功只代表支付宝凭证有效,不代表商户本地订单已匹配成功。检查服务端是否在返回 `Payment-Needed` 前持久化了 `out_trade_no`、`resource_id`、金额和订单状态;验证成功后应优先用验付返回的 `outTradeNo` 查询订单。沙箱响应字段可能为空字符串,排查时先判断字段是否非空;如果本地服务重启导致内存订单丢失,已付款旧链接不能继续用于重启后的服务。
|
|
@@ -211,38 +216,16 @@ Payment-Proof 参考结构:
|
|
|
211
216
|
|
|
212
217
|
### 第四步:测试结论与可选付款体验
|
|
213
218
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
```
|
|
217
|
-
✅ 按量付费沙箱服务端联调通过
|
|
218
|
-
|
|
219
|
-
| 测试项 | 状态 |
|
|
220
|
-
|--------|------|
|
|
221
|
-
| 402 Payment-Needed 返回 | ✅ |
|
|
222
|
-
| 沙箱收银链路 | ✅ |
|
|
223
|
-
| Payment-Proof 重试 | ✅ |
|
|
224
|
-
| 资源交付 | ✅ |
|
|
225
|
-
```
|
|
219
|
+
测试结束后使用 `a2m.test.result`:只有脚本退出码和本模块要求的组合证据都成立时选择 `PASSED`;其他情况选择 `FAILED` 并传入实际证据与确定恢复动作。不得把用户付款体验、沙箱配置落盘或任意 2xx 响应替代通过证据。
|
|
226
220
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
> 如需体验沙箱付款页面,可在浏览器打开以下链接,并使用沙箱买家账号操作:
|
|
230
|
-
> - 买家账号:`{email}`(如有)
|
|
231
|
-
> - 登录密码:`{logonPassword}`(如有)
|
|
232
|
-
> - 支付密码:`{payPassword}`(如有)
|
|
233
|
-
>
|
|
234
|
-
> {付款链接}
|
|
235
|
-
|
|
236
|
-
同时提供安卓客户端体验说明:
|
|
237
|
-
|
|
238
|
-
> 沙箱支付宝当前仅支持安卓系统。如需安装沙箱版支付宝,请复制以下链接到网页浏览器打开,并使用支付宝客户端扫码下载:
|
|
239
|
-
>
|
|
240
|
-
> https://mdn.alipayobjects.com/sandboxsys/afts/img/_itHRrdOD9oAAAAAAAAAAAAADgSLAQBr/original
|
|
221
|
+
输出测试结论后,使用 `a2m.payment.experience/FULL` 展示付款链接和已经通过快速沙箱字段校验的实际买家账号。缺少任一账号字段时,当前沙箱配置必须已经在前置校验进入待配置状态,不得执行本联调或输出付款体验,也不得编造缺失凭据。随后使用 `sandbox.android.client` 统一输出 Android-only 官方下载与失败兜底。两条消息都不增加阻塞点,也不反向改变服务端联调结论。
|
|
241
222
|
|
|
242
223
|
最后必须提醒用户:
|
|
243
224
|
|
|
244
225
|
> 当前 `serviceId=api_mock_service_id` 仅用于沙箱联调。正式上线前,必须替换为支付宝服务市场注册或复用服务后实际返回的真实 `serviceId`。
|
|
245
226
|
|
|
227
|
+
脚本使用权限不宽于 `0700/0600` 的临时目录传递敏感中间值,并在命令退出前清理。该目录不用于用户进度或后续恢复,Agent 不向用户索要、展示或复用其中的 Payment-Proof。
|
|
228
|
+
|
|
246
229
|
**沙箱支付宝下载红线(Agent 内部约束,不要作为用户提示逐字输出):**
|
|
247
230
|
- 默认只提供上方沙箱支付宝安装直链,复制到网页浏览器打开,并使用支付宝客户端扫码下载。
|
|
248
231
|
- 严禁声称 iOS 也有沙箱版支付宝或可在 iOS 完成沙箱支付宝安装。
|
|
@@ -252,28 +235,11 @@ Payment-Proof 参考结构:
|
|
|
252
235
|
|
|
253
236
|
---
|
|
254
237
|
|
|
255
|
-
## 已有 Payment-Needed 值(可选)
|
|
256
|
-
|
|
257
|
-
如果用户已经提供了 `Payment-Needed` 响应头值(如之前已从其他渠道获取),可以通过 `--payment-needed` 参数直接传入,跳过对用户服务的首次请求:
|
|
258
|
-
|
|
259
|
-
```bash
|
|
260
|
-
python3 ../scripts/local_402_sandbox_pay.py run \
|
|
261
|
-
--url "$SERVICE_URL" \
|
|
262
|
-
--method GET \
|
|
263
|
-
--buyer-id "$BUYER_2088" \
|
|
264
|
-
--payment-needed "$PAYMENT_NEEDED_VALUE" \
|
|
265
|
-
--auto-complete
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
脚本将直接解码该值并继续后续流程,不再发起 curl 请求。
|
|
269
|
-
|
|
270
|
-
---
|
|
271
|
-
|
|
272
238
|
## 注意事项
|
|
273
239
|
|
|
274
240
|
1. **沙箱收银接口**:脚本默认使用 `http://aicashier.dl.alipaydev.com/openclawpay/agent/v1/pay`,此地址已硬编码在脚本中
|
|
275
241
|
2. **付款链接**:前缀为 `https://render.alipay.com/p/yuyan/180020010001290755/pay.html?schema=`,通过 URL 编码的 `payScheme` 拼接
|
|
276
|
-
3.
|
|
242
|
+
3. **过程产物**:只在当前命令的系统临时专用目录中短时存在,目录/文件权限为 `0700/0600`;命令成功、失败或异常退出都执行清理,不提供自定义目录和跨轮恢复
|
|
277
243
|
4. **买家签名**:默认占位值 `-`,无需修改
|
|
278
244
|
5. **沙箱化 Agent 网络权限**:脚本内 `fetch_payment_needed` 使用 curl,且收银测试会访问沙箱接口;沙箱化 Agent 环境首次执行即申请可联网权限
|
|
279
245
|
6. **沙箱支付宝安装包**:沙箱支付宝当前仅支持安卓系统;默认引导用户复制 `https://mdn.alipayobjects.com/sandboxsys/afts/img/_itHRrdOD9oAAAAAAAAAAAAADgSLAQBr/original` 到网页浏览器打开,并使用支付宝客户端扫码下载。若用户明确反馈该直链、页面二维码无法打开或无法下载,只能引导用户前往支付宝开放平台沙箱工具页 `https://open.alipay.com/develop/sandbox/tool`,按页面指引安装沙箱版支付宝。严禁引导用户使用 iOS 沙箱支付宝、应用市场搜索、`https://sandbox.alipay.com` 或其他自编下载 URL。
|
|
@@ -294,6 +260,8 @@ python3 ../scripts/local_402_sandbox_pay.py run \
|
|
|
294
260
|
脚本连续构建 Payment-Proof
|
|
295
261
|
↓ base64(protocol + method)
|
|
296
262
|
重试用户服务
|
|
297
|
-
↓ HTTP 200 +
|
|
263
|
+
↓ HTTP 200 + 非空可归属资源 + 无明确失败
|
|
264
|
+
校验 Payment-Validation(当前五语言示例要求)
|
|
265
|
+
↓ 成功后清理敏感过程产物
|
|
298
266
|
验证通过 ✅
|
|
299
267
|
```
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
提供沙箱能力:**创建快速沙箱**。
|
|
4
4
|
|
|
5
|
+
本文件记录 `sandbox_config.sh` 内部使用的冻结 MCP 命令、响应结构和维护规则。运行时 Agent 不直接执行本文件的原始 MCP 命令;只执行 integration flow 登记的 `sandbox_config.sh ensure|reverify|verify|summary`,命中登记终态后立即转移,不追加临时 jq 或其他诊断。
|
|
6
|
+
|
|
5
7
|
## 1. 环境检测
|
|
6
8
|
|
|
7
9
|
> ⚠️ **前置要求**:在调用沙箱工具前,必须先按 `../../../normal/alipay-cli-env.md` 完成 alipay-cli 检测与安装
|
|
@@ -14,38 +16,37 @@ which alipay-cli 2>/dev/null && alipay-cli version
|
|
|
14
16
|
|
|
15
17
|
## 2. 创建快速沙箱
|
|
16
18
|
|
|
17
|
-
**重要:工具返回的 `data` 只是候选沙箱配置;必须先按 `sandbox-setup-guide.md`
|
|
19
|
+
**重要:工具返回的 `data` 只是候选沙箱配置;必须先按 `sandbox-setup-guide.md` 完成字段完整性校验,校验通过后再写入正式本地配置文件。创建阶段不对客输出字段核对表、独立校验结论或沙箱环境摘要表;代码开发完成并通过配置后置校验后,才按该指南输出一张沙箱环境摘要表。该结果不代表沙箱支付测试通过。privateKey、publicKey 等密钥字段不得展开。**
|
|
18
20
|
|
|
19
|
-
`createAnonymousSandbox` 的 MCP 请求体只有业务入参 `request.appType`。`PLATFORM
|
|
21
|
+
`createAnonymousSandbox` 的 MCP 请求体只有业务入参 `request.appType`,当前固定为 `PUBLICAPP`。`PLATFORM` 和 `PLATFORM_ID` 是 alipay-cli 上下文环境变量,禁止写入 `--data` 的 JSON。匿名沙箱创建不依赖本轮最终选择的支付产品,因此不得为了创建沙箱先编造或强行确认 `PRODUCT`。
|
|
20
22
|
|
|
21
23
|
```bash
|
|
22
24
|
PLATFORM="<PLATFORM>" \
|
|
23
|
-
|
|
25
|
+
PLATFORM_ID="<run_id>" \
|
|
24
26
|
alipay-cli mcp call alipay-anonymous-sandbox.createAnonymousSandbox \
|
|
25
|
-
--data '{"request":{"appType":"
|
|
27
|
+
--data '{"request":{"appType":"PUBLICAPP"}}' \
|
|
26
28
|
--json
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
|
|
31
|
+
**固定参数:**
|
|
30
32
|
|
|
31
|
-
|
|
|
32
|
-
|
|
33
|
-
|
|
|
33
|
+
| 字段 | 固定值 | 说明 |
|
|
34
|
+
|------|------|------|
|
|
35
|
+
| `request.appType` | `PUBLICAPP` | 不随用户最终选择的按量付费、网站支付或 APP 支付变化 |
|
|
34
36
|
|
|
35
37
|
**上下文变量:**
|
|
36
38
|
|
|
37
39
|
| 变量 | 来源 | 取值规则 |
|
|
38
40
|
|------|------|----------|
|
|
39
41
|
| `PLATFORM` | AI 编程工具识别结果 | 参考通用脚本 `../../../normal/scripts/detect_dev_tool.sh` 识别当前工具后使用其输出值;缺失时使用 `unknown`。例如 Codex 环境检测结果为 `codex` |
|
|
40
|
-
| `
|
|
41
|
-
|
|
42
|
-
> `PRODUCT` 不是 `createAnonymousSandbox` 的 MCP 请求体字段,仅作为 alipay-cli 上下文变量传入。Skill 内按产品决策结果归一为上表中的产品名。
|
|
42
|
+
| `PLATFORM_ID` | 当前流程 `run_id` | 由 `sandbox_config.sh` 通过 `common.sh` 从当前 telemetry run 读取;若宿主提供 `COZE_PROJECT_ID`、`MEOO_PROJECT_ID`,或 `MIAODA` 环境下的 `VITE_APP_ID`/`PLATFORM_ID`,新建 run 时 `run_id` 与该项目 ID 一致;缺失时不阻断沙箱创建 |
|
|
43
|
+
| `PRODUCT` | 不再传入 | 该 MCP 方法当前不需要产品上下文;不得把产品名写入 `--data` 或 CLI 环境变量 |
|
|
43
44
|
|
|
44
45
|
**Codex 环境示例:**
|
|
45
46
|
|
|
46
47
|
```bash
|
|
47
48
|
PLATFORM=codex \
|
|
48
|
-
|
|
49
|
+
PLATFORM_ID=<run_id> \
|
|
49
50
|
alipay-cli mcp call alipay-anonymous-sandbox.createAnonymousSandbox \
|
|
50
51
|
--data '{"request":{"appType":"PUBLICAPP"}}' \
|
|
51
52
|
--json
|
|
@@ -55,8 +56,9 @@ alipay-cli mcp call alipay-anonymous-sandbox.createAnonymousSandbox \
|
|
|
55
56
|
|
|
56
57
|
1. 取 `result.content[0].text`,去转义还原 JSON
|
|
57
58
|
2. `success === true` → 提取 `data` 字段作为候选沙箱配置,先按 [沙箱环境初始化](sandbox-setup-guide.md) 的必含字段清单做完整性校验
|
|
58
|
-
3. 字段完整性校验通过 → 将 `data`
|
|
59
|
-
4.
|
|
59
|
+
3. 字段完整性校验通过 → 将 `data` 字段完整写入正式本地配置文件;创建阶段只输出受控机器标记和实际配置路径,不输出沙箱环境摘要表、字段核对表、独立校验结论或“沙箱测试通过”等表述
|
|
60
|
+
4. 代码开发完成并通过配置后置校验后 → 按 `sandbox-setup-guide.md` 使用 `sandbox_config.sh summary` 复核并只输出一张沙箱环境摘要表,保持本地文件中的原始字段值不变,不在对话中复述密钥等长字段
|
|
61
|
+
5. `success !== true` 或 `data` 字段缺失/字段不完整 → 不得写入正式 `.alipay-sandbox.json`;按错误处理完成既定重试,耗尽后返回待配置终态并继续代码实现
|
|
60
62
|
|
|
61
63
|
## 3. 错误处理
|
|
62
64
|
|
|
@@ -64,33 +66,34 @@ CLI 输出不暴露 HTTP 状态码,统一按响应体中的 `success` 字段
|
|
|
64
66
|
|
|
65
67
|
| 条件 | 策略 |
|
|
66
68
|
|------|------|
|
|
67
|
-
| `success === false` 且 `msg` 含"证书密钥"
|
|
68
|
-
| `success === false` 且 `msg` 含"版本过旧"
|
|
69
|
-
| CLI
|
|
69
|
+
| `success === false` 且 `msg` 含"证书密钥"等当前已识别临时错误 | 固定 runner 静默等待 2 秒后自动重试 1 次;仍失败则进入待配置终态 |
|
|
70
|
+
| `success === false` 且 `msg` 含"版本过旧",或 CLI 退出码非 0 且不是已识别网络错误 | 不重试,保留实际失败类别和可执行恢复动作 |
|
|
71
|
+
| CLI 执行超时或已识别网络/服务错误 | 同一参数最多自动重试 2 次,每次间隔 3 秒 |
|
|
72
|
+
| 候选 `data` 或已有配置缺少必含字段 | 同一流程动作最多自动重试 2 次,每次间隔 3 秒;仍失败则进入 `CREATE_PENDING|VERIFY_PENDING` |
|
|
70
73
|
|
|
71
|
-
|
|
74
|
+
`ensure|reverify` 的重试耗尽后由 `sandbox_config.sh` 内部固定渲染 `sandbox.configuration.pending/CREATE|VERIFY`,并返回对应 `FLOW:SANDBOX_CONFIG_PENDING_*`;Agent 不得二次渲染、直接转述原始响应、临场拼装错误话术或自行增加重试确认。`SANDBOX_ERROR`、`errorCode` 和实际返回的 `traceId` 只属于严格 `create|verify` 子动作的受控诊断,待配置终态不对客展开原因。待配置不得产生沙箱 PASS 条件,只允许继续不依赖沙箱字段的代码实现。
|
|
72
75
|
|
|
73
76
|
## 4. 注意事项
|
|
74
77
|
|
|
75
|
-
-
|
|
76
|
-
-
|
|
78
|
+
- 本文件的原始命令只用于维护 `sandbox_config.sh` 的冻结契约,不对客展示,也不作为运行时二次调用入口。
|
|
79
|
+
- `request.appType` 与 CLI 上下文均由脚本固定。参数或返回结构无法按当前契约确认时停止并交由维护者核对,不向用户增加参数确认,不临场改写命令。
|
|
77
80
|
|
|
78
81
|
## 返回结构示例
|
|
79
82
|
|
|
80
83
|
### 成功结构示例
|
|
81
84
|
|
|
82
|
-
>
|
|
85
|
+
> 下例仅用于说明字段结构;真实执行时创建阶段不输出字段摘要或账号密码。只有代码开发完成且配置后置校验通过后,才按 `sandbox-setup-guide.md` 输出受控沙箱摘要;完整私钥、公钥等密钥字段只写入本地配置文件。
|
|
83
86
|
|
|
84
87
|
```json
|
|
85
88
|
{
|
|
86
89
|
"appIds": [
|
|
87
90
|
{
|
|
88
|
-
"alipayPublicKey": "
|
|
89
|
-
"appId": "
|
|
90
|
-
"appPrivateKey": "
|
|
91
|
-
"appPrivatePkcsKey": "
|
|
92
|
-
"appPublicKey": "
|
|
93
|
-
"pid": "
|
|
91
|
+
"alipayPublicKey": "<ALIPAY_PUBLIC_KEY_BASE64>",
|
|
92
|
+
"appId": "<SANDBOX_APP_ID>",
|
|
93
|
+
"appPrivateKey": "<APP_PRIVATE_KEY_PKCS8_BASE64>",
|
|
94
|
+
"appPrivatePkcsKey": "<APP_PRIVATE_KEY_PKCS1_BASE64>",
|
|
95
|
+
"appPublicKey": "<APP_PUBLIC_KEY_BASE64>",
|
|
96
|
+
"pid": "<SANDBOX_SELLER_USER_ID>",
|
|
94
97
|
"type": null,
|
|
95
98
|
"uid": null
|
|
96
99
|
}
|
|
@@ -99,25 +102,25 @@ CLI 输出不暴露 HTTP 状态码,统一按响应体中的 `success` 字段
|
|
|
99
102
|
"sandboxAccounts": {
|
|
100
103
|
"partner": {
|
|
101
104
|
"accountDesc": "商家账号",
|
|
102
|
-
"acctrans": "
|
|
103
|
-
"email": "
|
|
104
|
-
"merchantId": "
|
|
105
|
-
"userId": "
|
|
105
|
+
"acctrans": "<SANDBOX_SELLER_BALANCE>",
|
|
106
|
+
"email": "<SANDBOX_SELLER_EMAIL>",
|
|
107
|
+
"merchantId": "<SANDBOX_MERCHANT_ID>",
|
|
108
|
+
"userId": "<SANDBOX_SELLER_USER_ID>"
|
|
106
109
|
},
|
|
107
110
|
"user": {
|
|
108
111
|
"accountDesc": "买家账号",
|
|
109
|
-
"acctrans": "
|
|
110
|
-
"email": "
|
|
111
|
-
"userName": "
|
|
112
|
-
"userId": "
|
|
113
|
-
"logonPassword": "
|
|
114
|
-
"payPassword": "
|
|
115
|
-
"certNo": "
|
|
112
|
+
"acctrans": "<SANDBOX_BUYER_BALANCE>",
|
|
113
|
+
"email": "<SANDBOX_BUYER_EMAIL>",
|
|
114
|
+
"userName": "<SANDBOX_BUYER_NAME>",
|
|
115
|
+
"userId": "<SANDBOX_BUYER_USER_ID>",
|
|
116
|
+
"logonPassword": "<SANDBOX_BUYER_LOGIN_PASSWORD>",
|
|
117
|
+
"payPassword": "<SANDBOX_BUYER_PAY_PASSWORD>",
|
|
118
|
+
"certNo": "<SANDBOX_BUYER_CERT_NO>",
|
|
116
119
|
"certType": "IDENTITY_CARD"
|
|
117
120
|
}
|
|
118
121
|
},
|
|
119
|
-
"sandboxId": "
|
|
120
|
-
"sandboxName": "
|
|
122
|
+
"sandboxId": "<SANDBOX_ID>",
|
|
123
|
+
"sandboxName": "<SANDBOX_NAME>"
|
|
121
124
|
}
|
|
122
125
|
```
|
|
123
126
|
|