@alipay/alipay-aipay 1.1.0 → 1.2.2

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.
Files changed (41) hide show
  1. package/dist/commands/install.js +1 -1
  2. package/dist/commands/install.js.map +1 -1
  3. package/dist/commands/update.js +1 -1
  4. package/dist/commands/update.js.map +1 -1
  5. package/dist/utils/alipay-cli.js +4 -4
  6. package/dist/utils/alipay-cli.js.map +1 -1
  7. package/package.json +3 -4
  8. package/skill/SKILL.md +75 -12
  9. package/skill/VERSION +1 -1
  10. package/skill/references/integration/flow.md +150 -108
  11. package/skill/references/integration/modules/alipay-sdk-reminder.md +29 -13
  12. package/skill/references/integration/modules/checklist.md +49 -19
  13. 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 +3 -3
  14. package/skill/references/integration/modules/code-examples/csharp/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.cs +27 -13
  15. 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 +3 -3
  16. package/skill/references/integration/modules/code-examples/java/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemoController.java +31 -12
  17. 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 +5 -4
  18. package/skill/references/integration/modules/code-examples/nodejs/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.js +69 -37
  19. 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 +3 -3
  20. package/skill/references/integration/modules/code-examples/php/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.php +38 -17
  21. 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 +3 -3
  22. package/skill/references/integration/modules/code-examples/python/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.py +31 -18
  23. package/skill/references/integration/modules/interface-guide.md +7 -3
  24. package/skill/references/integration/modules/sandbox/a2m-sandbox-test.md +76 -54
  25. package/skill/references/integration/modules/sandbox/alipay-sandbox-tool.md +3 -3
  26. package/skill/references/integration/modules/sandbox/sandbox-setup-guide.md +80 -24
  27. package/skill/references/integration/modules/scripts/local_402_sandbox_pay.py +35 -4
  28. package/skill/references/normal/alipay-cli-env.md +2 -2
  29. package/skill/references/normal/self-update.md +2 -2
  30. package/skill/references/onboarding/flow.md +193 -297
  31. package/skill/references/onboarding/modules/app-release.md +91 -35
  32. package/skill/references/onboarding/modules/authorization.md +19 -13
  33. package/skill/references/onboarding/modules/error-handling.md +19 -14
  34. package/skill/references/onboarding/modules/product-sign.md +22 -21
  35. package/skill/references/onboarding/modules/scripts/app.sh +139 -40
  36. package/skill/references/onboarding/modules/scripts/auth.sh +168 -99
  37. package/skill/references/onboarding/modules/scripts/error_handler.sh +148 -18
  38. package/skill/references/onboarding/modules/scripts/query_sign_status.sh +17 -11
  39. package/skill/references/onboarding/modules/scripts/service.sh +208 -37
  40. package/skill/references/onboarding/modules/scripts/upload_screenshots.sh +1 -1
  41. package/skill/references/onboarding/modules/service-registration.md +72 -29
@@ -1,7 +1,7 @@
1
1
  # 应用发布模块
2
2
 
3
3
  > 本文档定义应用发布的完整流程、MCP调用规范和关键处理逻辑。
4
- > 被引用文档:`SKILL.md` → Step 5 入驻推进 - 应用发布部分
4
+ > 被引用文档:`onboarding/flow.md` → Step 3.1 应用查询 + Step 5.3 应用发布
5
5
  > 本文档位于 `references/onboarding/modules/`,文中的 `scripts/...` 路径相对本目录;从技能包根目录执行时对应 `references/onboarding/modules/scripts/...`。
6
6
 
7
7
  ---
@@ -12,7 +12,7 @@
12
12
 
13
13
  **触发条件:**
14
14
  - 用户说"发布应用"、"创建应用"
15
- - 签约完成后自动触发
15
+ - onboarding 登录授权完成后触发应用列表查询;需要签约时,应用复用/创建等后续操作仍在签约提交成功后执行
16
16
 
17
17
  > APP支付对应移动应用发布:应用列表查询和应用创建使用 `MOBILEAPP`;网站支付和按量付费继续使用 `WEBAPP`。
18
18
 
@@ -25,19 +25,25 @@
25
25
  ↓
26
26
  前置阶段 1: 检查 CLI 登录态
27
27
  ↓
28
- 阶段 2: 查询已有应用 (queryApplicationList)
28
+ 阶段 2: 登录后查询已有应用 (queryApplicationList)
29
29
  ↓
30
- 阶段 3: 用户选择
31
- ├─ 【复用】选择已有上线应用 → 查询安全密钥 → 导出 alipayPublicKey → 完成
30
+ 阶段 3: 与签约状态/其他资源合并展示,用户一次选择并提供条件资料
31
+ ↓
32
+ onboarding 且当前未签约: 先返回主流程完成 Step 5.1 签约提交
33
+ ↓
34
+ 签约提交成功,或已签约/已提交签约: 执行应用分支
35
+ ├─ 【复用】选择已有上线应用 → 查询安全密钥
36
+ │ ├─ RSA2 应用公钥已生效 → 导出 alipayPublicKey → 完成
37
+ │ └─ RSA2 应用公钥未生效 → 停止复用成功结论,由用户选择设钥或返回应用决策
32
38
  └─ 【新建】创建新应用 → 进入阶段 3.2
33
39
  ↓
34
40
  阶段 3.2: 创建应用 (createApplication) — 仅新建路径
35
41
  ↓
36
- 阶段 4: 设置应用公钥 (createKeyConfirmPage) — 仅新建路径
37
- ↓
38
- 阶段 4.1: 确认应用公钥已生效 (queryApplicationSecurityKey) — 仅新建路径
42
+ 阶段 4: 设置应用公钥 (createKeyConfirmPage) — 新建路径或复用缺公钥恢复路径
39
43
  ↓
40
- 阶段 5: 提交应用审核 (submitApplicationAudit) — 仅新建路径
44
+ 阶段 4.1: 确认应用公钥已生效 (queryApplicationSecurityKey) — 新建路径或复用缺公钥恢复路径
45
+ ├─ 复用缺公钥恢复路径 → 重新执行复用分支,重新校验应用状态并导出支付宝公钥
46
+ └─ 新建路径 → 阶段 5: 提交应用审核 (submitApplicationAudit)
41
47
  ```
42
48
 
43
49
  ---
@@ -167,27 +173,32 @@ export PLATFORM=${DEV_TOOL_NAME} && alipay-cli mcp call apprelease.queryApplicat
167
173
 
168
174
  **⚠️ 重要:在创建应用前必须先查询当前主体下是否已有可复用的应用。** 执行 `scripts/app.sh list --product-type "$PRODUCT_TYPE" --sales-code "$SALES_CODE"`。
169
175
 
176
+ 在 onboarding 中,本查询必须在登录授权成功后与签约状态查询连续执行,不等待签约提交。查询结果与签约状态合并展示,新建分支的条件资料也与未签约材料一次性收集。只读查询前置不代表可以提前创建应用;需要签约时仍先提交签约。
177
+
178
+ `productType` / `salesCode` 在此只用于校验上下文并选择 `WEBAPP` 或 `MOBILEAPP`。`queryApplicationList` 请求只按应用类型查询,因此返回项只能表述为“与当前产品所需应用类型匹配的候选应用”,不得表述为已绑定当前支付产品。
179
+
170
180
  ### 返回结果处理
171
181
 
172
- `scripts/app.sh list --product-type "$PRODUCT_TYPE" --sales-code "$SALES_CODE"` 自动完成以下处理,输出应用列表并引导用户选择。返回 `FLOW:CREATE_NEW` 表示需新建,`FLOW:SELECT` 表示需用户选择:
182
+ `scripts/app.sh list --product-type "$PRODUCT_TYPE" --sales-code "$SALES_CODE"` 自动完成以下处理,输出应用列表并引导用户选择。`FLOW:CREATE_NEW` 只表示当前类型应用列表确实为空;`FLOW:SELECT` 表示存在可复用上线应用;`FLOW:PENDING_APPLICATIONS` 表示只存在不可复用的非上线应用,需要用户明确等待或新建:
173
183
 
174
- ### 查询结果处理
184
+ 保留本次查询的候选 `appId` 和实际状态,供用户序号选择和新建前重查比对。不保存与决策无关的完整接口响应。
175
185
 
176
186
  | 结果 | 处理方式 |
177
187
  |------|----------|
178
- | 查询失败 | 直接返回错误,停止后续流程 |
188
+ | 查询失败 | 直接返回错误并停止应用分支;仅当前会话仍有效的独立业务/服务/结构错误可继续其他只读查询、候选展示和独立资料采集。认证失败或授权不匹配按 `../flow.md` Step 3.1 立即停止查询组并重新授权;应用查询恢复前禁止应用复用或创建 |
179
189
  | 命中 ON_LINE 应用 | 返回已有上线应用列表,让用户选择"复用上线应用"或"新建应用" |
180
- | 无同类型应用 | 直接进入"创建应用"阶段 |
190
+ | 无同类型应用 | 记录新建分支并一次性收集条件资料;onboarding 未签约时等待签约提交成功后再创建 |
191
+ | 存在同类型应用但均非 ON_LINE | 展示应用 ID、名称和实际状态,说明当前不可复用;等待用户选择暂不新建或明确新建,禁止自动进入创建 |
181
192
 
182
193
  ### ⛔ 应用复用强制原则
183
194
 
184
195
  <important>
185
- 只有状态为 `ON_LINE` 的应用才允许复用,也只有 `ON_LINE` 应用允许被列出给用户选择。
196
+ 只有状态为 `ON_LINE` 的应用才允许作为可复用候选。非 `ON_LINE` 应用可以作为不可复用的状态提示展示,用于防止重复创建,但禁止出现在复用序号中。
186
197
 
187
- - 查询结果只允许列出 `ON_LINE` 状态的应用
198
+ - 可复用候选和复用序号只允许包含 `ON_LINE` 状态的应用
188
199
  - 用户指定某个 `appId` 要复用时,必须先查询该应用状态
189
200
  - 状态不是 `ON_LINE` 时,禁止复用
190
- - 用户坚持要求复用非 `ON_LINE` 应用时,直接拒绝该复用请求,并继续按"新建应用"路径处理
201
+ - 用户坚持要求复用非 `ON_LINE` 应用时,直接拒绝该复用请求;是否新建必须由用户在看到现有非上线应用后明确选择,不得自动进入新建
191
202
  - 复用已有 `MOBILEAPP` 时不采集、不传入 `mobilePlatform`、`bundleId`、`appPackage`、`appSign`;平台字段只属于新建 `MOBILEAPP` 的 `createApplication` 入参
192
203
  </important>
193
204
 
@@ -211,6 +222,8 @@ export PLATFORM=${DEV_TOOL_NAME} && alipay-cli mcp call apprelease.queryApplicat
211
222
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
212
223
  ```
213
224
 
225
+ 展示候选应用时同步说明:选择“新建”后需要应用公钥;如果是 APP支付,还需要一次性提供平台及对应字段。用户可以在选择“新建”的同一条回复中提前提供这些字段,Agent 不得在每个字段之间逐轮询问。
226
+
214
227
  ### 复用成功后流程
215
228
 
216
229
  ```
@@ -231,7 +244,20 @@ export PLATFORM=${DEV_TOOL_NAME} && alipay-cli mcp call apprelease.queryApplicat
231
244
 
232
245
  ### queryApplicationSecurityKey 返回结果处理
233
246
 
234
- > 复用应用的完整处理(查询密钥 + 提取 RSA2 公钥 + 写入文件)已封装在 `scripts/app.sh reuse <appId>` 中。直接调用即可完成复用全流程。
247
+ 同一次查询只针对传入的一个 `appId`,但返回中的两类列表职责不同,禁止要求应用公钥和支付宝公钥出现在同一条记录中:
248
+
249
+ - 应用公钥配置状态:检查 `securityConfigList` 中 `signType="RSA2"` 的项,`partnerPublicKey` 非空即表示已配置;兼容旧返回中 RSA2 项的 `certInfoDTO.publicKey`。
250
+ - 支付宝公钥导出:检查 `alipayKeyList` 中 `signType="RSA2"` 的项并读取非空 `alipayPublicKey`。
251
+ - `securityKeys` 仅作为旧返回结构兼容来源。不得因为 `alipayKeyList[].certInfoDTO` 为空,就忽略 `securityConfigList[].partnerPublicKey` 并误判应用未配置公钥。
252
+
253
+ > 复用应用的完整处理(查询密钥 + 确认 RSA2 应用公钥 + 导出支付宝公钥)已封装在 `scripts/app.sh reuse <appId>` 中。应用公钥未确认时输出 `FLOW:REUSE_NO_KEY`;RSA2 项未返回 `alipayPublicKey` 时输出 `FLOW:ERROR`;已取得支付宝公钥但未能写入本地时,仍输出 `FLOW:REUSE_SUCCESS` 和 `ALIPAY_PUBLIC_KEY_EXPORT_STATUS=MANUAL_CONFIGURATION_REQUIRED`。
254
+
255
+ `FLOW:REUSE_NO_KEY` 是阻断结果,脚本返回非零退出码,禁止输出复用成功或把该 `appId` 记为可用于集成的完成产物。向用户合并说明当前所选 `ON_LINE` 应用尚未确认 RSA2 应用公钥,并让用户选择:
256
+
257
+ 1. 为当前 `appId` 设置应用公钥:按“阶段 4: 设置应用公钥”的标准引导和确认规则执行 `scripts/app.sh key`,用户完成页面确认后自动执行 `scripts/app.sh verify-key`;确认成功后重新执行 `scripts/app.sh reuse <appId>`,由脚本再次校验应用状态并导出支付宝公钥。
258
+ 2. 返回应用决策:重新选择其他 `ON_LINE` 应用、新建应用或暂不继续。
259
+
260
+ 不得自动生成、补全或持久化用户公钥,不得在用户未选择设钥且未提供完整 `publicKey` 时调用 `createKeyConfirmPage`。重新执行 `reuse` 前不得推定应用仍为 `ON_LINE`;由脚本重新查询实际状态。
235
261
 
236
262
  ### 复用成功输出格式
237
263
 
@@ -242,7 +268,7 @@ export PLATFORM=${DEV_TOOL_NAME} && alipay-cli mcp call apprelease.queryApplicat
242
268
  |------|------|
243
269
  | AppId | <appId> |
244
270
  | 应用状态 | ON_LINE(已上线) |
245
- | 支付宝公钥保存路径 | ~/.config/<appId>-alipayPublicKey.keytext |
271
+ | 支付宝公钥本地配置 | <导出成功:~/.config/<appId>-alipayPublicKey.keytext;本地写入失败:待手动配置> |
246
272
  ```
247
273
 
248
274
  ### 按量付费集成产物
@@ -252,7 +278,7 @@ export PLATFORM=${DEV_TOOL_NAME} && alipay-cli mcp call apprelease.queryApplicat
252
278
  | 字段 | 用途 |
253
279
  |------|------|
254
280
  | `appId` | SDK 配置中的应用 ID,也是 `Payment-Needed.method.seller_app_id` |
255
- | 支付宝公钥文件路径 | SDK 验签配置使用,复用应用时由 `scripts/app.sh reuse` 导出 |
281
+ | 支付宝公钥本地配置状态 | SDK 验签配置使用;导出成功时记录文件路径,已取得公钥但本地写入失败时记录“待手动配置” |
256
282
  | 应用状态 | 只有 `ON_LINE` 应用允许复用;新建应用需按审核结果判断正式可用性 |
257
283
 
258
284
  按量付费还需要服务市场注册产物 `serviceId`。如果只有 `appId` 而没有 `serviceId`,不能进入正式按量付费集成收口。
@@ -263,6 +289,16 @@ export PLATFORM=${DEV_TOOL_NAME} && alipay-cli mcp call apprelease.queryApplicat
263
289
 
264
290
  **⚠️ 仅在用户选择"新建应用"或无可复用应用时执行此阶段。**
265
291
 
292
+ ### 创建前列表重查
293
+
294
+ 在展示最终“创建应用”外部写操作摘要前,自动重新执行 `scripts/app.sh list --product-type "$PRODUCT_TYPE" --sales-code "$SALES_CODE"`:
295
+
296
+ - 候选 appId 和状态与 Step 3.1 一致:不重复询问用户,继续展示创建摘要。
297
+ - 出现新的 `ON_LINE` 或非 `ON_LINE` 应用,或原候选状态变化:展示最新候选,清除旧的应用决策,等待用户基于新状态选择复用、新建或暂不新建。
298
+ - 重查失败:禁止调用 `createApplication`,仅将应用分支标记为待恢复。
299
+
300
+ 该重查只在 `CREATE` 分支执行,不增加正常复用分支的工具成本,也不替代外部写操作确认。
301
+
266
302
  执行规则:
267
303
 
268
304
  - 按量付费/网站支付:执行 `scripts/app.sh create --product-type "$PRODUCT_TYPE" --sales-code "$SALES_CODE"`。
@@ -272,9 +308,21 @@ export PLATFORM=${DEV_TOOL_NAME} && alipay-cli mcp call apprelease.queryApplicat
272
308
 
273
309
  APP支付缺少平台或对应字段时,先向用户补问,禁止调用 `createApplication`。
274
310
 
311
+ **一次性新建资料包**:在 onboarding 中优先使用 Step 4 已收集并校验的字段,不重复询问:
312
+
313
+ - iOS:`mobilePlatform=IOS`、`bundleId`、应用公钥(如已准备)。
314
+ - Android:`mobilePlatform=ANDROID`、`appPackage`、`appSign`、应用公钥(如已准备)。
315
+ - iOS + Android:`mobilePlatform=ALL`、`bundleId`、`appPackage`、`appSign`、应用公钥(如已准备)。
316
+ - 按量付费/网站支付:应用公钥(如已准备)。
317
+
318
+ 应用公钥仍必须由用户明确提供,且所有公钥私钥红线继续生效。用户尚未准备公钥时不得阻止应用创建,但创建成功后必须停在阶段 4;禁止在没有完整 `publicKey` 时调用 `createKeyConfirmPage`。
319
+
320
+ Agent 在当前任务中记录应用操作和对应平台字段;用户改变应用类型或移动平台时,清除不再适用的旧平台字段并只补问新条件下的缺失项。应用公钥原文不得写入资料清单,只记录是否已经准备。`scripts/app.sh create` 会先在本地校验应用类型和平台条件字段,校验通过后才调用 MCP。
321
+
275
322
  | 结果 | 处理方式 |
276
323
  |------|----------|
277
- | 创建成功 | 获取 appId,进入阶段 4 设置应用公钥 |
324
+ | 创建成功且解析到非空 appId | 获取 appId,进入阶段 4 设置应用公钥 |
325
+ | 返回成功但未解析到 appId | 按返回结构异常阻断,禁止进入公钥设置流程 |
278
326
  | 创建失败 | 返回错误,停止后续流程 |
279
327
 
280
328
  如果 `createApplication` 返回 `APP_MAX_ERROR` / `应用数量达到上限`,不要继续调整 `appSign`、`bundleId`、`mobilePlatform` 等创建参数,也不要重复新建。应明确告知用户当前主体应用数量已达到上限,优先返回阶段 2 复用已有 `ON_LINE` 应用;如必须新建,引导用户前往支付宝开放平台处理应用配额或联系支付宝技术支持。
@@ -314,8 +362,10 @@ APP支付缺少平台或对应字段时,先向用户补问,禁止调用 `cre
314
362
  2. **接收用户公钥**:只接受用户明确输入的完整 `publicKey`
315
363
  3. **创建密钥确认页**:执行 `bash scripts/app.sh key <appId> <用户提供的公钥>`。
316
364
  4. **用户扫码确认**:输出扫码链接时,**必须同步告知用户"有效期10分钟"**
317
- 5. **查询确认结果**:用户确认后执行 `bash scripts/app.sh verify-key <appId> <用户提供的公钥>` 确认设置成功;该脚本会短轮询 `queryApplicationSecurityKey`,避免支付宝侧短暂延迟导致误判
318
- 6. **写入 alipayPublicKey 文件**:
365
+ 5. **查询确认结果**:用户确认后自动执行 `bash scripts/app.sh verify-key <appId> <用户提供的公钥>` 确认设置成功;该脚本会短轮询 `queryApplicationSecurityKey`,避免支付宝侧短暂延迟导致误判
366
+ 6. **按来源分支恢复**:
367
+ - 新建应用:公钥校验成功后,按 `../flow.md` Step 5 展示当前有效登录会话、可用的脱敏主体标识、产品、`appId` 和提审动作摘要;CLI 未返回主体标识时同时要求用户确认当前登录账号就是操作目标。用户明确确认该摘要后执行 `bash scripts/app.sh audit <appId>`。不再询问是否校验,但公钥校验失败时禁止进入提审确认;`audit` 在提交前尝试导出支付宝公钥,本地文件写入失败不阻塞已确认的提审,但必须提示后续集成需要手动配置支付宝公钥。
368
+ - 复用缺公钥恢复:公钥校验成功后重新执行 `bash scripts/app.sh reuse <appId>`,重新校验应用状态并导出支付宝公钥;不进入新建应用的提审分支。
319
369
 
320
370
  ### ⛔ createKeyConfirmPage 返回结果处理规范(最高优先级)
321
371
 
@@ -328,6 +378,7 @@ APP支付缺少平台或对应字段时,先向用户补问,禁止调用 `cre
328
378
 
329
379
  ✅ 必须:将 confirmPageUrl 以 markdown 链接格式输出给用户
330
380
  ✅ 必须:告知用户请点击链接或扫码确认公钥设置
381
+ ✅ 必须:“无法跳链”提示放在确认链接前,确认链接独占一行
331
382
  ✅ 必须:等待用户确认后再继续后续步骤
332
383
  ```
333
384
 
@@ -338,11 +389,14 @@ APP支付缺少平台或对应字段时,先向用户补问,禁止调用 `cre
338
389
 
339
390
  请点击以下链接确认公钥设置:
340
391
 
341
- [点击确认公钥设置](https://aipay.alipay.com/public-key-confirm?keyConfirmToken=xxx)(无法跳链时,请复制链接到网页浏览器打开)
392
+ 提示:无法跳链时,请复制下方链接到网页浏览器打开。
393
+ [点击确认公钥设置](https://aipay.alipay.com/public-key-confirm?keyConfirmToken=xxx)
342
394
 
343
395
  确认完成后,请告诉我"好了"继续后续流程。
344
396
  ```
345
397
 
398
+ 确认链接必须独占一行并放在“无法跳链”提示之后,禁止将提示文案拼接到 Markdown 链接或 URL 后。
399
+
346
400
  **禁止输出格式:**
347
401
 
348
402
  ```
@@ -353,13 +407,15 @@ APP支付缺少平台或对应字段时,先向用户补问,禁止调用 `cre
353
407
 
354
408
  > 📎 公钥设置调用 `bash scripts/app.sh key <appId> <publicKey>`,脚本自动提取 `confirmPageUrl` 并按标准 Markdown 格式输出。
355
409
 
356
- ### alipayPublicKey 文件写入
410
+ ### alipayPublicKey 本地写入失败非阻塞
411
+
412
+ 以脚本输出为准记录导出结果:`ALIPAY_PUBLIC_KEY_EXPORT_STATUS=EXPORTED` 时同时记录 `ALIPAY_PUBLIC_KEY_FILE`;`ALIPAY_PUBLIC_KEY_EXPORT_STATUS=MANUAL_CONFIGURATION_REQUIRED` 只表示已取得支付宝公钥但本地写入失败,正式集成前需手动配置。RSA2 项未返回 `alipayPublicKey` 时直接报错,不得记录为导出失败。禁止根据固定路径推断文件已经存在。
357
413
 
358
414
  ```bash
359
- # 写入路径,由 app.sh reuse/audit 自动写入
415
+ # 导出路径,由 app.sh reuse/audit 自动写入
360
416
  ~/.config/${APP_ID}-alipayPublicKey.keytext
361
417
 
362
- # 写入时机
418
+ # 导出时机
363
419
  # 1. 复用已有上线应用时
364
420
  # 2. 提交应用审核前
365
421
  ```
@@ -370,14 +426,14 @@ APP支付缺少平台或对应字段时,先向用户补问,禁止调用 `cre
370
426
 
371
427
  **⚠️ 只有确认应用公钥存在后,才继续提交审核。`scripts/app.sh verify-key` 和 `scripts/app.sh audit` 会通过 `queryApplicationSecurityKey` 判断 RSA2 公钥配置:**
372
428
 
373
- - 只取 `signType="RSA2"` 的项。
374
- - 合并兼容读取 `resultObj.alipayKeyList`、`resultObj.securityKeys`、`data.alipayKeyList`、`data.securityKeys`。
375
- - 普通公钥模式下 `certInfoDTO` 可能为 `null`,不能仅凭该字段判定未配置。
376
- - 满足以下任一条件即可视为 RSA2 应用公钥配置已生效:RSA2 项存在 `certInfoDTO.publicKey`、等价 `publicKey` 或 `alipayPublicKey`;RSA2 `securityConfigList.partnerPublicKey` 非空且 `invalid != true`。
429
+ 执行 `audit` 前还必须按 `../flow.md` Step 5 展示当前有效登录会话、可用的脱敏主体标识、产品、`appId` 和“提交应用审核”动作摘要,并取得针对该摘要的明确执行确认。CLI 未返回主体标识时,摘要必须要求用户确认当前登录账号就是操作目标。应用公钥页面的“好了”只表示外部公钥确认完成,不等于授权提交应用审核。
430
+
431
+ - 应用公钥状态与支付宝公钥必须分别按本模块“queryApplicationSecurityKey 返回结果处理”解析:RSA2 `securityConfigList[].partnerPublicKey` 非空即表示应用公钥已配置,同时兼容旧返回中的 `certInfoDTO.publicKey`;支付宝公钥只从 RSA2 `alipayKeyList[].alipayPublicKey` 读取。
432
+ - `alipayPublicKey` 是支付宝公钥,只用于导出验签配置,不得用于证明应用公钥已生效。
377
433
  - `verify-key` 默认最多重试 6 次、每次间隔 5 秒;可通过 `APP_KEY_VERIFY_RETRIES` 和 `APP_KEY_VERIFY_INTERVAL_SECONDS` 调整。
378
- - `alipayPublicKey` 为空时拒绝提审。
379
- - 校验通过后写入 `~/.config/<appId>-alipayPublicKey.keytext`,再提交审核。
380
- - 已获取 `alipayPublicKey` 但本地文件写入失败时,按本地写入失败处理并重试;重试后仍失败则提醒用户后续集成需手动配置支付宝公钥,但不阻塞提审或复用成功路径。
434
+ - 应用公钥已确认但 RSA2 项未返回 `alipayPublicKey` 时,直接返回错误,不继续提审。
435
+ - 校验通过后由 `audit` 在提交审核前尝试写入 `~/.config/<appId>-alipayPublicKey.keytext`。
436
+ - 已获取 `alipayPublicKey` 但本地文件写入失败时,按本地写入失败处理并重试;重试后仍失败则输出同一待配置状态,但不阻塞提审或复用成功路径。
381
437
 
382
438
  执行 `bash scripts/app.sh audit <appId>`。
383
439
 
@@ -399,7 +455,7 @@ APP支付缺少平台或对应字段时,先向用户补问,禁止调用 `cre
399
455
  |------|------|
400
456
  | AppId | <appId> |
401
457
  | 应用状态 | ON_LINE(已上线) |
402
- | 支付宝公钥保存路径 | ~/.config/<appId>-alipayPublicKey.keytext |
458
+ | 支付宝公钥本地配置 | <导出成功:~/.config/<appId>-alipayPublicKey.keytext;本地写入失败:待手动配置> |
403
459
  ```
404
460
 
405
461
  ### 新建应用成功
@@ -411,5 +467,5 @@ APP支付缺少平台或对应字段时,先向用户补问,禁止调用 `cre
411
467
  |------|------|
412
468
  | AppId | <appId> |
413
469
  | 应用状态 | AUDITING(审核中) |
414
- | 支付宝公钥保存路径 | ~/.config/<appId>-alipayPublicKey.keytext |
470
+ | 支付宝公钥本地配置 | <导出成功:~/.config/<appId>-alipayPublicKey.keytext;本地写入失败:待手动配置> |
415
471
  ```
@@ -22,7 +22,7 @@
22
22
 
23
23
  ### 2.1 检查命令
24
24
 
25
- > 📎 已收口到脚本 `scripts/auth.sh init`。Agent 执行流程时调用 `bash scripts/auth.sh init`(见 flow.md Step 3),脚本返回 `AUTH_FLOW:SKIP`(已登录)或 `AUTH_FLOW:READY`(需新授权)。
25
+ > 📎 已收口到脚本 `scripts/auth.sh init`。Agent 执行流程时调用 `bash scripts/auth.sh init`(见 flow.md Step 3);脚本只有在登录有效且目标产品 scope、MCC 均校验通过后才返回 `AUTH_FLOW:SKIP`,需要新授权时返回 `AUTH_FLOW:READY`。校验不匹配时脚本返回对应信号并停止当前操作,不自行 logout;检查或校验无法完成时返回 `AUTH_FLOW:FAILED`,禁止进入状态查询。
26
26
 
27
27
  whoami 原始返回格式:
28
28
 
@@ -40,9 +40,11 @@ whoami 原始返回格式:
40
40
 
41
41
  **检查 `.data.logged_in` 字段(不是外层的 `.success`)**
42
42
 
43
+ 当前约定的 `whoami` 返回只用于校验登录是否有效、是否过期和授权 scope,不包含可依赖的账号主体标识。外部写操作摘要不得从该返回中编造主体名称;按 `../flow.md` Step 5 展示当前有效登录会话,有其他已验证查询返回非敏感主体标识时再脱敏展示,否则要求用户确认当前登录账号就是操作目标。
44
+
43
45
  | 返回值 | 状态 | 处理 |
44
46
  |--------|------|------|
45
- | `logged_in: true` + `is_expired: false` | 正常登录 | 继续后续步骤 |
47
+ | `logged_in: true` + `is_expired: false` | 登录有效 | 继续校验目标产品 scope 和 MCC;均通过后才可进入后续步骤 |
46
48
  | `logged_in: false` 或 `is_expired: true` | 未登录/已过期 | 进入登录授权流程 |
47
49
 
48
50
  ---
@@ -51,6 +53,8 @@ whoami 原始返回格式:
51
53
 
52
54
  **在执行 `login` 命令前,必须先让用户确认产品类型和经营类目!**
53
55
 
56
+ 该确认由 `../flow.md` Step 2 的一次性方案确认满足,但必须是用户对同一产品、经营类目和授权范围作出的明确确认。`full_process` 的项目状态回答、integration 产品确认或服务声明确认均不能替代本确认。复用确认只减少 onboarding 内部的重复询问,不降低本节要求;找不到有效确认记录、确认范围不同或信息发生变化时,必须按本节模板重新等待用户确认。
57
+
54
58
  ### 3.1 输出格式(Markdown)
55
59
 
56
60
  ```markdown
@@ -160,7 +164,8 @@ CLI 返回的 JSON 中包含 `verification_url` 字段,**此链接无法用于
160
164
 
161
165
  ⚠️ 安全提示:请核对授权页面显示的确认码是否与上方一致,如不一致,请勿授权,立即停止操作!
162
166
 
163
- 🌐 授权链接:[点击跳转进行授权]({BROWSER_URL})(无法跳链时,请复制链接到网页浏览器打开)
167
+ 提示:无法跳链时,请复制下方链接到网页浏览器打开。
168
+ 🌐 授权链接:[点击跳转进行授权]({BROWSER_URL})
164
169
 
165
170
  请在完成授权后告诉我"好了"继续后续流程。
166
171
  ```
@@ -169,6 +174,7 @@ CLI 返回的 JSON 中包含 `verification_url` 字段,**此链接无法用于
169
174
  - `auth.sh init` 的输出模板是唯一授权提示模板;Agent 不得自行简写、重排或改写为“授权确认/步骤/输入验证码”等其他格式。
170
175
  - 确认码只用于用户核对授权页面展示内容,绝不是让用户输入的验证码。
171
176
  - 授权链接必须使用完整 Markdown 链接 `[点击跳转进行授权]({BROWSER_URL})`,不得只输出裸链接替代模板。
177
+ - 授权链接必须独占一行并放在“无法跳链”提示之后;禁止将提示文案拼接到 Markdown 链接或 URL 后。
172
178
 
173
179
  ---
174
180
 
@@ -178,7 +184,7 @@ CLI 返回的 JSON 中包含 `verification_url` 字段,**此链接无法用于
178
184
 
179
185
  > 📎 已收口到脚本 `scripts/auth.sh confirm`。Agent 在用户回复"好了"后调用 `bash scripts/auth.sh confirm --scope "$SCOPE" --sales-code "$SALES_CODE" --mcc-code "$MCC_CODE" --product-name "$PRODUCT_NAME" --mcc-name "$MCC_NAME"`(见 flow.md Step 3)。
180
186
 
181
- 脚本内部执行 `login --complete` + scope 校验 + MCC 校验。原始返回格式:
187
+ 脚本内部执行 `login --complete` + scope 校验 + MCC 校验。授权上下文处理规则:
182
188
 
183
189
  > `confirm` / `mismatch` 优先使用显式传入的 `salesCode`、`mccCode`、`scope`、`productName`、`mccName` 等非敏感授权上下文。`auth.sh init` 仍会短期保存本地状态文件,仅用于独立执行子命令时兜底恢复参数。授权成功、过期或失败后脚本会清理该状态文件。
184
190
 
@@ -186,11 +192,11 @@ CLI 返回的 JSON 中包含 `verification_url` 字段,**此链接无法用于
186
192
 
187
193
  | 脚本输出 | 含义 | 处理 |
188
194
  |----------|------|------|
189
- | `AUTH_FLOW:AUTH_SUCCESS` | 授权成功,scope + MCC 校验通过 | 继续 Step 3.1 |
195
+ | `AUTH_FLOW:AUTH_SUCCESS` | 授权成功,scope + MCC 校验通过 | 继续 Step 3.1 状态与资源查询 |
190
196
  | `AUTH_FLOW:PENDING` | 用户尚未完成授权 | 继续等待 |
191
197
  | `AUTH_FLOW:EXPIRED` | 授权链接已过期 | 重新执行 auth.sh init |
192
- | `AUTH_FLOW:SCOPE_MISMATCH` | scope 权限不满足 | 已自动 logout,需重新授权 |
193
- | `AUTH_FLOW:MCC_MISMATCH` | 经营类目未授权 | 已自动 logout,需重新授权 |
198
+ | `AUTH_FLOW:SCOPE_MISMATCH` | scope 权限不满足 | 调用 `auth.sh mismatch`,由其 logout 后重新授权 |
199
+ | `AUTH_FLOW:MCC_MISMATCH` | 经营类目未授权 | 调用 `auth.sh mismatch`,由其 logout 后重新授权 |
194
200
  | `AUTH_FLOW:FAILED` | 授权确认返回未知错误 | 检查返回信息,联系技术支持 |
195
201
 
196
202
  ### 7.3 ⚠️ 禁止轮询
@@ -204,16 +210,16 @@ CLI 返回的 JSON 中包含 `verification_url` 字段,**此链接无法用于
204
210
 
205
211
  > 📎 已收口到脚本:`scripts/auth.sh confirm`(Step 3-6: scope + MCC 校验)
206
212
 
207
- `auth.sh confirm` 在 `login --complete` 成功后自动执行 scope 校验和 MCC 校验,失败时自动 logout。Agent 只需根据脚本返回值判断结果:
213
+ `auth.sh init` 对已有有效登录、`auth.sh confirm` 对本次完成的授权都自动执行同一套 scope 和 MCC 校验;不匹配时返回信号并停止当前操作。Agent 只需根据脚本返回值判断结果:
208
214
 
209
215
  | 脚本输出 | 后续操作 |
210
216
  |----------|----------|
211
- | `AUTH_FLOW:AUTH_SUCCESS` | 进入 Step 3.1 签约状态查询 |
212
- | `AUTH_FLOW:SCOPE_MISMATCH` / `AUTH_FLOW:MCC_MISMATCH` | 调用 `auth.sh mismatch` 重新授权 |
217
+ | `AUTH_FLOW:SKIP` / `AUTH_FLOW:AUTH_SUCCESS` | 进入 Step 3.1 状态与资源查询 |
218
+ | `AUTH_FLOW:SCOPE_MISMATCH` / `AUTH_FLOW:MCC_MISMATCH` | 调用 `auth.sh mismatch`,由其 logout 后重新授权 |
213
219
 
214
220
  #### 7.4.1 校验实现
215
221
 
216
- 由 `auth.sh confirm` 自动完成,无需手动执行。
222
+ 由 `auth.sh init`(已有有效登录)和 `auth.sh confirm`(本次授权完成)自动完成,无需手动执行。
217
223
 
218
224
  **为什么需要这两个校验**:
219
225
  - `login --complete` 只确认用户完成了扫码,不代表授权范围满足业务需求
@@ -230,13 +236,13 @@ CLI 返回的 JSON 中包含 `verification_url` 字段,**此链接无法用于
230
236
  **当检测到授权范围不满足时,必须执行 logout 然后重新授权。**
231
237
 
232
238
  触发条件:
233
- 1. `auth.sh confirm` 返回 `AUTH_FLOW:SCOPE_MISMATCH` / `AUTH_FLOW:MCC_MISMATCH`
239
+ 1. `auth.sh init` 或 `auth.sh confirm` 返回 `AUTH_FLOW:SCOPE_MISMATCH` / `AUTH_FLOW:MCC_MISMATCH`
234
240
  2. MCP 调用返回 `mccCode is not auth` 错误
235
241
  3. MCP 调用返回 `scope is not auth` 错误
236
242
 
237
243
  处理流程:
238
244
 
239
- > 📎 已收口到脚本 `scripts/auth.sh mismatch`。Agent 调用 `bash scripts/auth.sh mismatch --scope "$SCOPE" --sales-code "$SALES_CODE" --mcc-code "$MCC_CODE" --product-name "$PRODUCT_NAME" --mcc-name "$MCC_NAME"`(见 flow.md Step 3),脚本自动执行 logout + 调用 auth init 重新授权。
245
+ > 📎 `scripts/auth.sh init` / `confirm` 和 `error_handler.sh` 只返回或提示授权不匹配并停止当前操作,不执行 logout。Agent 随后调用 `bash scripts/auth.sh mismatch --scope "$SCOPE" --sales-code "$SALES_CODE" --mcc-code "$MCC_CODE" --product-name "$PRODUCT_NAME" --mcc-name "$MCC_NAME"`(见 flow.md Step 3);该子命令是此恢复路径唯一的 logout 入口,退出成功后再调用 auth init 重新授权。
240
246
 
241
247
  ### 8.2 禁止行为
242
248
 
@@ -13,12 +13,12 @@
13
13
 
14
14
  | 函数 | 说明 | 返回 |
15
15
  |------|------|------|
16
- | `unwrap_mcp` | MCP 信封解包,提取 `content[0].text` 中的业务 JSON;非信封结构原样透传 | 解包后的 JSON 字符串 |
16
+ | `unwrap_mcp` | MCP 信封解包,通过单次状态扫描提取 `content[0].text` 中的业务 JSON;混合输出只从完整闭合结构形成候选,并只接受唯一可确定的 MCP 信封或 JSON,候选不唯一时不猜测结果,由错误检测阻断 | 解包后的 JSON 字符串或无法唯一解析的原始文本 |
17
17
  | `detect_error` | 统一错误检测入口,自动解包 MCP 信封后按优先级匹配所有错误类型 | `MCP_AUTH_ERROR` / `MCP_SERVICE_ERROR` / `AUTH_MISMATCH` / `SERVICE_UNSTABLE` / `ERROR:xxx` / `CLI_ERROR:xxx` / `SUCCESS` |
18
18
  | `handle_error` | 统一错误处理入口,调用 `detect_error` 后路由到对应 handler(内含 `unwrap_mcp` 自动解包信封) | `0`=成功, `1`=需用户干预 |
19
- | `handle_mcp_auth_error` | 处理 MCP 认证错误(HTTP 401),执行 logout + 引导重新授权 | - |
19
+ | `handle_mcp_auth_error` | 处理 MCP 认证错误(HTTP 401),校验 logout 成功后再引导重新授权;logout 失败时阻断 | - |
20
20
  | `handle_mcp_service_error` | 处理 MCP 服务不可用(网络/连接错误);沙箱化 Agent 环境提示申请可联网权限重试同一命令,其他环境提示检查网络 | - |
21
- | `handle_auth_mismatch` | 处理授权不匹配(MCC/产品/scope),执行 logout + 引导重新授权 | - |
21
+ | `handle_auth_mismatch` | 识别授权不匹配(MCC/产品/scope),停止当前操作并引导调用 `auth.sh mismatch` | - |
22
22
  | `handle_service_unstable` | 处理 MCP 服务不稳定,提示稍后重试 | - |
23
23
  | `handle_backend_error` | 处理后端业务错误(errorCode),展示错误信息、bizTips、checkedError | - |
24
24
 
@@ -38,7 +38,8 @@
38
38
 
39
39
  ### 处理原则
40
40
  ```
41
- ✅ 检测到 HTTP 401 → 退出当前登录 → 引导用户重新授权
41
+ ✅ 检测到 HTTP 401 → 执行并校验 logout → 仅退出成功后引导用户重新授权
42
+ ❌ logout 失败 → 明确报错并停止重新授权,禁止宣称已退出登录
42
43
  ✅ 清理对话上下文中的授权相关数据
43
44
  ✅ 提供清晰的错误说明和下一步操作指引
44
45
  ❌ 禁止自动重试 MCP 调用(会导致相同的认证错误)
@@ -100,8 +101,9 @@
100
101
 
101
102
  ### 处理原则
102
103
  ```
103
- ✅ 检测到授权不匹配 → 执行 logout 退出登录 → 调用 auth.sh mismatch 重新授权
104
+ ✅ 检测到授权不匹配 → 停止当前操作 → 调用 auth.sh mismatch → 由 mismatch 执行 logout 后重新授权
104
105
  ✅ 重新授权时使用正确的 scope(根据当前 salesCode 确定)
106
+ ✅ 多查询流程中检测到认证失败或授权不匹配 → 立即停止剩余查询;重新授权后只恢复未执行查询,主体无法确认一致时重新查询全部适用状态
105
107
  ❌ 禁止:检测到授权范围不满足后继续执行后续操作
106
108
  ❌ 禁止:不执行 logout 直接重新登录
107
109
  ```
@@ -150,11 +152,12 @@
150
152
  }
151
153
  ```
152
154
 
153
- > ⚠️ 有些 MCP 返回会把真实业务响应包在 `data.response` 或 `errorContext.errorStack[]` 下。错误检测必须优先定位业务错误对象:既要兼容 `errorCode: "xxx"`,也要兼容 `errorCode: { "code": "xxx", "desc": "...", "message": "...", "errorScene": "...", "errorSpecific": "..." }`。错误信息应从同一错误对象提取 `errorMessage` / `errorMsg` / `errorCode.desc` / `errorCode.message` / `bizTips` / `errorScene` / `errorSpecific`,不得只读取顶层字段后兜底为“未知错误”。
155
+ > ⚠️ 有些 MCP 返回会把真实业务响应包在 `data.response` 或 `errorContext.errorStack[]` 下。错误检测必须优先定位业务错误对象:既要兼容 `errorCode: "xxx"`,也要兼容 `errorCode: { "code": "xxx", "desc": "...", "message": "...", "errorScene": "...", "errorSpecific": "..." }`。常规错误继续按 `errorMessage` / `errorMsg` / `errorCode.desc` / `errorCode.message` 等既有字段处理;只有已验证的当前服务写入协议 `data.success=false` 才优先读取 `data.subMsg` / `data.msg`,并忽略仅表示外层调用成功的顶层 `msg="Success"`。不得把该优先级扩展到其他响应结构,也不得丢弃真实业务错误后兜底为“未知错误”。
154
156
 
155
157
  ### 处理原则
156
158
  ```
157
159
  ✅ errorCode 存在 → 展示 errorMessage
160
+ ✅ data.success=false → 优先展示 data.subMsg / data.msg,不把顶层 msg="Success" 当作业务错误
158
161
  ✅ 如有 bizTips → 一并展示给用户
159
162
  ✅ 如有 checkedError → 逐条展示字段级校验错误描述
160
163
  ✅ 如有 errorScene / errorSpecific → 一并展示,便于技术支持定位
@@ -173,7 +176,7 @@
173
176
 
174
177
  > ⚠️ 各 `.sh` 脚本已内置错误检测(source `error_handler.sh` + 调用 `handle_error`)和 MCP 信封解包(`unwrap_mcp`),Agent 执行脚本时无需额外处理。
175
178
 
176
- 在**直接执行 MCP 调用**(非通过脚本)的场景,需注意 `alipay-cli mcp call` 返回 MCP 协议信封,业务 JSON 被包在 `content[0].text` 里,必须先解包:
179
+ 在**直接执行 MCP 调用**(非通过脚本)的场景,需注意 `alipay-cli mcp call` 返回 MCP 协议信封,业务 JSON 被包在 `content[0].text` 里,必须先解包。CLI stdout 混有日志时,`unwrap_mcp` 只提取唯一可确定的信封或 JSON;存在多个候选时不猜测,保留原文并增加歧义标记,后续 `handle_error` 将按非 JSON 异常阻断:
177
180
 
178
181
  ```bash
179
182
  # ① 执行 MCP 调用
@@ -185,9 +188,10 @@ if ! handle_error "$RESULT"; then
185
188
  return 1
186
189
  fi
187
190
 
188
- # ③ 如果返回 0,解包信封后处理业务字段
191
+ # ③ 如果返回 0,解包信封后按当前模块已确认的响应契约处理业务字段
189
192
  BUSINESS=$(unwrap_mcp "$RESULT")
190
- SUCCESS=$(echo "$BUSINESS" | jq -r '.success // false')
193
+ # 不得统一假定成功字段位于 .success;例如服务写入的当前协议使用
194
+ # code="10000"、data.success=true,并从 data.serviceId 读取服务 ID。
191
195
  ```
192
196
 
193
197
  ---
@@ -200,7 +204,7 @@ SUCCESS=$(echo "$BUSINESS" | jq -r '.success // false')
200
204
  ├─────────────────────────────────────────────────────────────────┤
201
205
  │ 📦 MCP 信封解包(unwrap_mcp) │
202
206
  │ 所有 mcp call 返回 {content:[{text:"<业务JSON>"}]} │
203
- │ 必须先 unwrap_mcp 解包,再解析 .success / .resultObj 等字段 │
207
+ │ 必须先 unwrap_mcp 解包,再按当前模块契约解析业务字段 │
204
208
  ├─────────────────────────────────────────────────────────────────┤
205
209
  │ 🔐 MCP_AUTH_ERROR │
206
210
  │ 关键词:HTTP 401 / Authorization is empty / 非法的认证信息 │
@@ -230,10 +234,11 @@ SUCCESS=$(echo "$BUSINESS" | jq -r '.success // false')
230
234
 
231
235
  | Step | MCP 调用位置 | 建议使用的检测函数 |
232
236
  |------|---------------|-------------------|
233
- | Step 1 环境检查 | CLI whoami / login | 由 `auth.sh` 内置处理 |
234
- | Step 3 登录授权 | login --complete / logout | 由 `auth.sh` 内置处理 |
235
- | Step 3.1 签约状态查询 | ar-query.queryArInfosBySalesProd | 由 `query_sign_status.sh` 内置(source error_handler.sh;建议设置 PRODUCT_TYPE 做产品码一致性校验) |
236
- | Step 4 资料采集 | file upload | 由 `upload_screenshots.sh` 内置(source error_handler.sh + unwrap_mcp 解包信封) |
237
+ | Step 1 环境检查 | alipay-cli 可用性与安装检查 | 由 `../../normal/alipay-cli-env.md` 处理,不执行登录状态预检 |
238
+ | Step 3 登录授权 | whoami / login / login --complete / logout | 由 `auth.sh` 内置处理 |
239
+ | Step 3.1 状态与资源查询(签约状态) | ar-query.queryArInfosBySalesProd | 由 `query_sign_status.sh` 内置(source error_handler.sh;建议设置 PRODUCT_TYPE 做产品码一致性校验) |
240
+ | Step 3.1 应用/服务资源查询 | apprelease.queryApplicationList / a2a-pay-service.discoverBazaarServicesForMcp | 分别由 `app.sh list` / `service.sh list` 内置,禁止将失败结果当作空列表 |
241
+ | Step 4 一次性资料与资源决策 | file upload | 由 `upload_screenshots.sh` 内置(source error_handler.sh + unwrap_mcp 解包信封) |
237
242
  | Step 5.1 产品签约 | ar-sign.apply | 由 `ar_sign_apply.sh` 内置(source error_handler.sh) |
238
243
  | Step 5.2 服务注册 | a2a-pay-service.* | 由 `service.sh` 内置(source error_handler.sh) |
239
244
  | Step 5.3 应用发布 | apprelease.* | 由 `app.sh` 内置(source error_handler.sh) |
@@ -1,7 +1,7 @@
1
1
  # 产品签约模块
2
2
 
3
3
  > 本文档定义产品签约的完整流程、参数规范和状态判断逻辑。
4
- > 被引用文档:`SKILL.md` → Step 5 入驻推进 - 签约部分
4
+ > 被引用文档:`onboarding/flow.md` → Step 3.1 签约查询 + Step 5.1 签约提交
5
5
  > 本文档位于 `references/onboarding/modules/`,文中的 `scripts/...` 路径相对本目录;从技能包根目录执行时对应 `references/onboarding/modules/scripts/...`。
6
6
 
7
7
  ---
@@ -12,7 +12,7 @@
12
12
 
13
13
  本模块采用 `ar-sign.apply` **外部直调 / 静态参数模式**:由 `scripts/ar_sign_apply.sh` 基于当前已确认的产品类型、MCC 和资料字段直接构造 `businessProperty` 后提交申请。它不走 `previewFormView` 动态 schema 收集循环,因此只覆盖本文档明确列出的字段和产品。
14
14
 
15
- **触发条件:** Step 3.1 授权后处理中,签约状态为 NOT_SIGNED 时触发。
15
+ **使用条件:** Step 3.1 始终使用本模块的签约状态查询规则;只有查询结果为 `NOT_SIGNED` 时,才使用本模块的签约申请提交规则。`SIGNED_EFFECTIVE`、`SIGN_SUBMITTED`、查询失败或其他状态均禁止提交签约申请。
16
16
 
17
17
  ---
18
18
 
@@ -42,8 +42,8 @@
42
42
  | 返回结果 | 状态判定 | 说明 |
43
43
  |----------|----------|------|
44
44
  | `resultObj.arInfoList` 为空数组 `[]` | `NOT_SIGNED` | 未签约 |
45
- | `resultObj.arInfoList` 不为空,且存在 `arStatus` 为 `"02"` 的记录 | `SIGNED_EFFECTIVE` | 签约已生效,跳过资料采集 |
46
- | `resultObj.arInfoList` 不为空,且存在 `arStatus` 为 `"01"` 的记录 | `SIGN_SUBMITTED` | 已提交签约(待生效),跳过资料采集与重复签约提交 |
45
+ | `resultObj.arInfoList` 不为空,且存在 `arStatus` 为 `"02"` 的记录 | `SIGNED_EFFECTIVE` | 签约已生效,跳过签约材料采集,仍在 Step 4 处理应用/服务决策 |
46
+ | `resultObj.arInfoList` 不为空,且存在 `arStatus` 为 `"01"` 的记录 | `SIGN_SUBMITTED` | 已提交签约(待生效),跳过签约材料和重复签约提交,仍在 Step 4 处理应用/服务决策 |
47
47
 
48
48
  ### 判断逻辑
49
49
 
@@ -53,22 +53,22 @@
53
53
 
54
54
  | 签约状态 | 产品类型 | FLOW 信号 | 后续流程 |
55
55
  |----------|----------|-----------|----------|
56
- | `NOT_SIGNED` | 网站支付 | `FLOW:PC_WEB_NOT_SIGNED` | 进入 Step 4 资料采集(3张网站截图)→ Step 5 签约 + 应用发布 |
57
- | `NOT_SIGNED` | APP支付 | `FLOW:APP_NOT_SIGNED` | 进入 Step 4 资料采集(APP名称 + 3张APP界面截图)→ Step 5 签约 + 应用发布 |
58
- | `NOT_SIGNED` | 按量付费 | `FLOW:AI_PAY_NOT_SIGNED` | 跳过 Step 4,进入 Step 5.1 签约,再继续服务注册 + 应用发布 |
59
- | `SIGNED_EFFECTIVE` | 网站支付 | `FLOW:PC_WEB_SIGNED` | 跳过签约提交,直接执行应用发布 |
60
- | `SIGNED_EFFECTIVE` | APP支付 | `FLOW:APP_SIGNED` | 跳过签约提交,直接执行应用发布 |
61
- | `SIGNED_EFFECTIVE` | 按量付费 | `FLOW:AI_PAY_SIGNED` | 跳过签约提交,直接执行服务注册 + 应用发布 |
62
- | `SIGN_SUBMITTED` | 网站支付 | `FLOW:PC_WEB_SIGNED` | 跳过重复签约提交,直接执行应用发布 |
63
- | `SIGN_SUBMITTED` | APP支付 | `FLOW:APP_SIGNED` | 跳过重复签约提交,直接执行应用发布 |
64
- | `SIGN_SUBMITTED` | 按量付费 | `FLOW:AI_PAY_SIGNED` | 跳过重复签约提交,直接执行服务注册 + 应用发布 |
65
-
66
- **⚠️ 按量付费 无需前置资料采集:**
56
+ | `NOT_SIGNED` | 网站支付 | `FLOW:PC_WEB_NOT_SIGNED` | 进入 Step 4 一次性资料与资源决策(3张网站截图 + 应用决策/条件资料)→ Step 5 签约 + 应用发布 |
57
+ | `NOT_SIGNED` | APP支付 | `FLOW:APP_NOT_SIGNED` | 进入 Step 4 一次性资料与资源决策(APP名称 + 3张APP界面截图 + 应用决策/条件资料)→ Step 5 签约 + 应用发布 |
58
+ | `NOT_SIGNED` | 按量付费 | `FLOW:AI_PAY_NOT_SIGNED` | Step 4 无需收集页面图片,但一次完成服务/应用决策和条件资料;再进入 Step 5.1 签约 |
59
+ | `SIGNED_EFFECTIVE` | 网站支付 | `FLOW:PC_WEB_SIGNED` | Step 4 完成应用决策后,跳过签约提交并执行应用发布 |
60
+ | `SIGNED_EFFECTIVE` | APP支付 | `FLOW:APP_SIGNED` | Step 4 完成应用决策后,跳过签约提交并执行应用发布 |
61
+ | `SIGNED_EFFECTIVE` | 按量付费 | `FLOW:AI_PAY_SIGNED` | Step 4 完成服务/应用决策后,跳过签约提交并执行服务注册 + 应用发布 |
62
+ | `SIGN_SUBMITTED` | 网站支付 | `FLOW:PC_WEB_SIGNED` | Step 4 完成应用决策后,跳过重复签约提交并执行应用发布 |
63
+ | `SIGN_SUBMITTED` | APP支付 | `FLOW:APP_SIGNED` | Step 4 完成应用决策后,跳过重复签约提交并执行应用发布 |
64
+ | `SIGN_SUBMITTED` | 按量付费 | `FLOW:AI_PAY_SIGNED` | Step 4 完成服务/应用决策后,跳过重复签约提交并执行服务注册 + 应用发布 |
65
+
66
+ **⚠️ 按量付费无需签约材料:**
67
67
  ```
68
68
  ✅ 网站支付未签约:需先采集 3 张网站截图,再进入 Step 5 签约
69
69
  ✅ APP支付未签约:需先采集 APP 名称和 3 张APP界面截图,再进入 Step 5 签约
70
- ✅ 按量付费 未签约:跳过 Step 4,进入 Step 5.1 签约,再继续服务注册 + 应用发布
71
- ❌ 禁止:按量付费 在 Step 4 收集服务注册信息(服务信息在 Step 5 服务注册时交互式收集)
70
+ ✅ 按量付费 未签约:Step 4 无需签约页面图片,但前置完成服务/应用决策和条件资料;Step 5 仍先提交签约
71
+ ✅ 按量付费在 Step 4 基于已查询的服务候选,一次收集新建/修改分支的完整五项服务资料;Step 5.2 才执行写操作
72
72
  ```
73
73
 
74
74
  **按量付费签约后的必要后续动作:**
@@ -188,8 +188,8 @@ bash scripts/ar_sign_apply.sh --product apppay --sales-code "I108030000100004131
188
188
  | `mccCode` | Step 2 方案规划 | 运行时变量,格式 `Axxxx_Bxxxx`,不持久化到状态文件 |
189
189
  | `channelCode` | 固定值 | `"B_SK_SH_RPC"` |
190
190
  | `orderType` | 固定值 | `"NEW_SIGN"` |
191
- | `screenshot` | Step 4 资料采集 | **仅网站支付/APP支付需要**(3个上传后的图片引用值),按量付费 无需此项 |
192
- | `appName` | Step 4 资料采集 | **仅APP支付需要**;脚本参数仍为 `--app-name`,提交到 MCP 时映射为 `nativeAppDTO.name` |
191
+ | `screenshot` | Step 4 一次性资料与资源决策 | **仅未签约的网站支付/APP支付需要**(3个上传后的图片引用值),按量付费无需此项 |
192
+ | `appName` | Step 4 一次性资料与资源决策 | **仅未签约的 APP支付需要**;脚本参数仍为 `--app-name`,提交到 MCP 时映射为 `nativeAppDTO.name` |
193
193
  | `appStatus` | 固定值 | **仅APP支付需要**,本次固定为 `OFFLINE` |
194
194
 
195
195
  ### 按量付费接入产物映射
@@ -209,7 +209,8 @@ bash scripts/ar_sign_apply.sh --product apppay --sales-code "I108030000100004131
209
209
  ✅ 网站支付未签约 → 需要 3 张网站截图(首页、商品页、支付页)
210
210
  ✅ APP支付未签约 → 需要 APP 名称和 3 张APP界面截图(首页、商品页、支付页),签约状态固定按 OFFLINE 提交
211
211
  ✅ 按量付费 未签约 → 无需截图,直接签约
212
- ✅ 网站支付/APP支付材料不足 → 不提交签约;先进入/回到集成流程完成支付页/支付能力集成,再回来上传截图
212
+ ✅ 网站支付/APP支付缺少支付页或支付能力 → 不提交签约;先进入/回到集成流程完成实现,再回来上传图片
213
+ ✅ 网站支付/APP支付页面和支付能力已存在、仅缺三张页面图片 → 保留在 onboarding Step 4 收集和上传,不进入集成流程
213
214
  ❌ 禁止:按量付费 签约时传入 screenshot 字段
214
215
  ❌ 禁止:网站支付/APP支付 签约时省略 screenshot 字段
215
216
  ❌ 禁止:将“支付页”自行改口为“支付成功页”或要求用户提供文档未定义的页面
@@ -228,7 +229,7 @@ bash scripts/ar_sign_apply.sh --product apppay --sales-code "I108030000100004131
228
229
 
229
230
  > ⚠️ **签约提交成功后,无需等待签约审核通过,应立即继续推进后续步骤。**
230
231
 
231
- 签约申请提交后,后端会异步审核,`arStatus` 为 `"01"`(已提交待生效)。应用创建和服务注册不依赖签约审核通过,可以并行推进。
232
+ 签约申请提交后,后端会异步审核,`arStatus` 为 `"01"`(已提交待生效)。应用创建和服务注册不依赖签约审核通过,可以继续推进。为减少用户交互,应用/服务列表查询及分支资料采集可在签约提交前完成;当前流程仍先提交签约,成功后才执行服务或应用写操作。
232
233
 
233
234
  ### FLOW 信号
234
235