@alipay/alipay-aipay 0.1.1-beta.1

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 (114) hide show
  1. package/README.md +1 -0
  2. package/bin/alipay-aipay.js +6 -0
  3. package/dist/commands/install.d.ts +10 -0
  4. package/dist/commands/install.d.ts.map +1 -0
  5. package/dist/commands/install.js +92 -0
  6. package/dist/commands/install.js.map +1 -0
  7. package/dist/commands/uninstall.d.ts +10 -0
  8. package/dist/commands/uninstall.d.ts.map +1 -0
  9. package/dist/commands/uninstall.js +82 -0
  10. package/dist/commands/uninstall.js.map +1 -0
  11. package/dist/commands/update.d.ts +10 -0
  12. package/dist/commands/update.d.ts.map +1 -0
  13. package/dist/commands/update.js +125 -0
  14. package/dist/commands/update.js.map +1 -0
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +51 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/types.d.ts +43 -0
  20. package/dist/types.d.ts.map +1 -0
  21. package/dist/types.js +2 -0
  22. package/dist/types.js.map +1 -0
  23. package/dist/utils/alipay-cli.d.ts +15 -0
  24. package/dist/utils/alipay-cli.d.ts.map +1 -0
  25. package/dist/utils/alipay-cli.js +228 -0
  26. package/dist/utils/alipay-cli.js.map +1 -0
  27. package/dist/utils/config.d.ts +48 -0
  28. package/dist/utils/config.d.ts.map +1 -0
  29. package/dist/utils/config.js +207 -0
  30. package/dist/utils/config.js.map +1 -0
  31. package/dist/utils/file.d.ts +55 -0
  32. package/dist/utils/file.d.ts.map +1 -0
  33. package/dist/utils/file.js +154 -0
  34. package/dist/utils/file.js.map +1 -0
  35. package/dist/utils/gpg.d.ts +14 -0
  36. package/dist/utils/gpg.d.ts.map +1 -0
  37. package/dist/utils/gpg.js +247 -0
  38. package/dist/utils/gpg.js.map +1 -0
  39. package/dist/utils/jq.d.ts +14 -0
  40. package/dist/utils/jq.d.ts.map +1 -0
  41. package/dist/utils/jq.js +221 -0
  42. package/dist/utils/jq.js.map +1 -0
  43. package/dist/utils/npm.d.ts +17 -0
  44. package/dist/utils/npm.d.ts.map +1 -0
  45. package/dist/utils/npm.js +42 -0
  46. package/dist/utils/npm.js.map +1 -0
  47. package/dist/utils/shell.d.ts +11 -0
  48. package/dist/utils/shell.d.ts.map +1 -0
  49. package/dist/utils/shell.js +54 -0
  50. package/dist/utils/shell.js.map +1 -0
  51. package/package.json +53 -0
  52. package/skill/SKILL.md +118 -0
  53. package/skill/references/integration/flow.md +487 -0
  54. package/skill/references/integration/modules/alipay-sdk-reminder.md +256 -0
  55. package/skill/references/integration/modules/checklist.md +122 -0
  56. package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +68 -0
  57. package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +77 -0
  58. package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +74 -0
  59. package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +73 -0
  60. 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 +58 -0
  61. 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 +128 -0
  62. package/skill/references/integration/modules/code-examples/csharp/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.cs +500 -0
  63. package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +72 -0
  64. package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +80 -0
  65. package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +78 -0
  66. package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +77 -0
  67. 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 +66 -0
  68. 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 +135 -0
  69. package/skill/references/integration/modules/code-examples/java/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemoController.java +610 -0
  70. package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +51 -0
  71. package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +57 -0
  72. package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +55 -0
  73. package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +54 -0
  74. 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 +77 -0
  75. 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 +65 -0
  76. package/skill/references/integration/modules/code-examples/nodejs/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.js +461 -0
  77. package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +59 -0
  78. package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +67 -0
  79. package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +66 -0
  80. package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +65 -0
  81. 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 +56 -0
  82. 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 +107 -0
  83. package/skill/references/integration/modules/code-examples/php/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.php +444 -0
  84. package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/345/205/263/351/227/255/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +57 -0
  85. package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +65 -0
  86. package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +63 -0
  87. package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//347/273/237/344/270/200/346/224/266/345/215/225/344/272/244/346/230/223/351/200/200/346/254/276/346/237/245/350/257/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +62 -0
  88. 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 +48 -0
  89. 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 +43 -0
  90. package/skill/references/integration/modules/code-examples/python/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.py +465 -0
  91. package/skill/references/integration/modules/interface-guide.md +90 -0
  92. package/skill/references/integration/modules/product-decision.md +90 -0
  93. package/skill/references/integration/modules/sandbox/a2m-sandbox-test.md +270 -0
  94. package/skill/references/integration/modules/sandbox/alipay-sandbox-tool.md +133 -0
  95. package/skill/references/integration/modules/sandbox/sandbox-setup-guide.md +218 -0
  96. package/skill/references/integration/modules/scripts/local_402_sandbox_pay.py +659 -0
  97. package/skill/references/normal/alipay-cli-env.md +211 -0
  98. package/skill/references/normal/rejection-guide.md +37 -0
  99. package/skill/references/normal/scripts/common.sh +32 -0
  100. package/skill/references/normal/scripts/detect_dev_tool.sh +46 -0
  101. package/skill/references/onboarding/flow.md +571 -0
  102. package/skill/references/onboarding/modules/app-release.md +411 -0
  103. package/skill/references/onboarding/modules/authorization.md +269 -0
  104. package/skill/references/onboarding/modules/error-handling.md +247 -0
  105. package/skill/references/onboarding/modules/mcc-reference.md +209 -0
  106. package/skill/references/onboarding/modules/product-sign.md +304 -0
  107. package/skill/references/onboarding/modules/scripts/app.sh +705 -0
  108. package/skill/references/onboarding/modules/scripts/ar_sign_apply.sh +248 -0
  109. package/skill/references/onboarding/modules/scripts/auth.sh +505 -0
  110. package/skill/references/onboarding/modules/scripts/error_handler.sh +312 -0
  111. package/skill/references/onboarding/modules/scripts/query_sign_status.sh +146 -0
  112. package/skill/references/onboarding/modules/scripts/service.sh +267 -0
  113. package/skill/references/onboarding/modules/scripts/upload_screenshots.sh +152 -0
  114. package/skill/references/onboarding/modules/service-registration.md +294 -0
@@ -0,0 +1,312 @@
1
+ #!/bin/bash
2
+ #=============================================================================
3
+ # 脚本名称: error_handler.sh
4
+ # 功能描述: 签约流程统一错误检测与处理,供所有 .sh 脚本 source 引用
5
+ # 源文件: error-handling.md(本文档为可执行版本)
6
+ # 用法: source scripts/error_handler.sh
7
+ # if ! handle_error "$RESULT"; then return 1; fi
8
+ #=============================================================================
9
+
10
+ ERROR_HANDLER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ COMMON_SCRIPT="${ERROR_HANDLER_DIR}/../../../normal/scripts/common.sh"
12
+ if [ -f "$COMMON_SCRIPT" ]; then
13
+ # shellcheck source=/dev/null
14
+ source "$COMMON_SCRIPT"
15
+ init_dev_tool_name
16
+ else
17
+ echo "❌ 缺少公共脚本: $COMMON_SCRIPT"
18
+ return 1 2>/dev/null || exit 1
19
+ fi
20
+
21
+ # ─── MCP 信封解包 ──────────────────────────────────────────────────────────
22
+ # alipay-cli mcp call 返回 MCP 协议信封:
23
+ # { "content": [ { "text": "<业务JSON>", "type": "text" } ] }
24
+ # 业务 JSON(含 success / resultObj / errorCode)被包在 content[0].text 里。
25
+ # 本函数负责解包:若检测到信封结构,提取 content[0].text;否则原样返回。
26
+ #
27
+ # 对于非 mcp call 的命令(如 alipay-cli login / whoami),返回不带信封,
28
+ # 保证这些命令的原样透传。
29
+ unwrap_mcp() {
30
+ local RAW="$1"
31
+ if [ -z "$RAW" ]; then
32
+ echo ""
33
+ return
34
+ fi
35
+
36
+ if ! echo "$RAW" | jq -e . >/dev/null 2>&1; then
37
+ echo "$RAW"
38
+ return
39
+ fi
40
+
41
+ local TEXT
42
+ TEXT=$(echo "$RAW" | jq -r 'if (.content | type == "array") and (.content[0].text != null) then .content[0].text else empty end' 2>/dev/null)
43
+ if [ -n "$TEXT" ]; then
44
+ echo "$TEXT"
45
+ else
46
+ echo "$RAW"
47
+ fi
48
+ }
49
+
50
+ # ─── 统一错误检测 ──────────────────────────────────────────────────────────
51
+ # 参数: $1 - CLI 执行结果文本(原始输出,含信封或不含)
52
+ # 返回: MCP_AUTH_ERROR | MCP_SERVICE_ERROR | AUTH_MISMATCH | SERVICE_UNSTABLE | ERROR:xxx | CLI_ERROR:xxx | SUCCESS
53
+ detect_error() {
54
+ local CLI_RESULT="$1"
55
+
56
+ # 空输入视为异常,不应被当作 SUCCESS
57
+ if [ -z "$CLI_RESULT" ]; then
58
+ echo "CLI_ERROR:CLI 返回为空"
59
+ return
60
+ fi
61
+
62
+ # 先解包 MCP 信封,再进行错误检测
63
+ local UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
64
+
65
+ # 1. 优先检测 MCP 认证错误(HTTP 401)
66
+ if echo "$UNWRAPPED" | grep -qiE "HTTP 401|Authorization is empty|非法的认证信息"; then
67
+ echo "MCP_AUTH_ERROR"
68
+ return
69
+ fi
70
+
71
+ # 2. MCP 服务不稳定(后端返回的服务异常)
72
+ if echo "$UNWRAPPED" | grep -qiE "MCP.*服务.*不稳定|服务暂时不可用"; then
73
+ echo "SERVICE_UNSTABLE"
74
+ return
75
+ fi
76
+
77
+ # 3. MCP 调用失败(网络/连接错误)
78
+ if echo "$UNWRAPPED" | grep -qiE "MCP 调用失败|connection refused|timeout|network error"; then
79
+ echo "MCP_SERVICE_ERROR"
80
+ return
81
+ fi
82
+
83
+ # 4. 授权信息不匹配(MCC/产品/scope 未授权)
84
+ if echo "$UNWRAPPED" | grep -qiE "mccCode.*is not auth|salesProductCodes.*is not auth|scope.*is not auth"; then
85
+ echo "AUTH_MISMATCH"
86
+ return
87
+ fi
88
+
89
+ if ! echo "$UNWRAPPED" | jq -e . >/dev/null 2>&1; then
90
+ local FIRST_LINE
91
+ FIRST_LINE=$(printf "%s" "$UNWRAPPED" | sed -n '1p')
92
+ echo "CLI_ERROR:${FIRST_LINE:-CLI 返回非 JSON 内容}"
93
+ return
94
+ fi
95
+
96
+ # 5. 通用业务错误(从解包后的 JSON 中提取 errorCode)
97
+ local ERROR_CODE=$(echo "$UNWRAPPED" | jq -r '.errorCode // .data.errorCode // ""' 2>/dev/null)
98
+ if [ -n "$ERROR_CODE" ] && [ "$ERROR_CODE" != "null" ]; then
99
+ echo "ERROR:$ERROR_CODE"
100
+ return
101
+ fi
102
+
103
+ # 6. CLI 命令本身的错误(success: false,从解包后的 JSON 提取)
104
+ # 注意: jq 的 // 对 false 视为 falsy 会触发 alternative,所以不能写 .success // "true"
105
+ # 必须先将 false 转为字符串再判断
106
+ local SUCCESS=$(echo "$UNWRAPPED" | jq -r 'if .success == false then "false" elif .success == true then "true" else "null" end' 2>/dev/null)
107
+ if [ "$SUCCESS" = "false" ]; then
108
+ local ERROR_MSG=$(echo "$UNWRAPPED" | jq -r '.error.message // .errorMessage // .message // "未知错误"' 2>/dev/null)
109
+ echo "CLI_ERROR:$ERROR_MSG"
110
+ return
111
+ fi
112
+
113
+ echo "SUCCESS"
114
+ }
115
+
116
+ # ─── MCP 认证错误处理 ──────────────────────────────────────────────────────
117
+ handle_mcp_auth_error() {
118
+ echo ""
119
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
120
+ echo "🔐 未登录或授权已过期"
121
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
122
+ echo ""
123
+ echo "❌ 当前登录状态已失效,无法继续操作"
124
+ echo ""
125
+ echo "📋 原因:MCP 调用返回认证错误(HTTP 401)"
126
+ echo "📋 说明:Authorization is empty(认证信息为空)"
127
+ echo ""
128
+ echo "🔄 正在退出当前登录..."
129
+ export PLATFORM=${DEV_TOOL_NAME:-unknown} && alipay-cli logout --json 2>/dev/null
130
+
131
+ echo ""
132
+ echo "✅ 已退出登录状态"
133
+ echo ""
134
+ echo "📌 请重新执行登录授权流程:"
135
+ echo " 1. 我会生成授权链接"
136
+ echo " 2. 您使用支付宝扫码授权"
137
+ echo " 3. 授权成功后继续当前操作"
138
+ echo ""
139
+ echo "请回复「继续」开始重新授权,或「退出」结束流程。"
140
+ }
141
+
142
+ # ─── MCP 服务不可用处理 ────────────────────────────────────────────────────
143
+ handle_mcp_service_error() {
144
+ local CLI_RESULT="$1"
145
+ local UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
146
+
147
+ echo ""
148
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
149
+ echo "⚠️ MCP 服务暂时不可用"
150
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
151
+ echo ""
152
+ if [ "${DEV_TOOL_NAME:-unknown}" != "unknown" ]; then
153
+ echo "❌ 当前命令需要访问支付宝服务,但当前 Agent 执行环境可能没有外网权限"
154
+ echo ""
155
+ echo "📋 处理方式:"
156
+ echo " - Agent 应申请可联网权限后重试同一条命令"
157
+ echo " - 不要要求用户排查本机网络,也不要更换业务参数"
158
+ echo ""
159
+ echo "请授权 Agent 联网重试,或稍后重新执行当前命令。"
160
+ return
161
+ fi
162
+
163
+ echo "❌ 无法连接到支付宝服务,请稍后重试"
164
+ echo ""
165
+ echo "📋 错误详情:"
166
+ echo "$UNWRAPPED" | jq -r '.error.message // .errorMessage // .message // "未知错误"' 2>/dev/null || echo "$UNWRAPPED"
167
+ echo ""
168
+ echo "您可以:"
169
+ echo " 1. 检查网络连接是否正常"
170
+ echo " 2. 等待几分钟后重新执行"
171
+ echo " 3. 联系技术支持获取帮助"
172
+ echo ""
173
+ echo "请回复「重试」重新尝试,或「退出」结束流程。"
174
+ }
175
+
176
+ # ─── 授权信息不匹配处理 ────────────────────────────────────────────────────
177
+ handle_auth_mismatch() {
178
+ local CLI_RESULT="$1"
179
+ local UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
180
+
181
+ echo ""
182
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
183
+ echo "❌ 授权信息不匹配,需要重新授权"
184
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
185
+
186
+ if echo "$UNWRAPPED" | grep -qi "mccCode is not auth"; then
187
+ echo "📋 原因:经营类目未授权"
188
+ elif echo "$UNWRAPPED" | grep -qi "salesProductCodes is not auth"; then
189
+ echo "📋 原因:产品未授权"
190
+ elif echo "$UNWRAPPED" | grep -qi "scope is not auth"; then
191
+ echo "📋 原因:授权 scope 不满足"
192
+ fi
193
+
194
+ echo ""
195
+ echo ""
196
+
197
+ echo "🔄 正在退出当前登录..."
198
+ export PLATFORM=${DEV_TOOL_NAME:-unknown} && alipay-cli logout --json 2>/dev/null
199
+
200
+ echo "✅ 已退出登录,请重新执行登录授权流程"
201
+ }
202
+
203
+ # ─── 后端业务错误处理(完整透出错误信息) ──────────────────────────────────
204
+ handle_backend_error() {
205
+ local CLI_RESULT="$1"
206
+ local ERROR_CODE="$2"
207
+ local UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
208
+
209
+ echo ""
210
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
211
+ echo "❌ 业务处理失败"
212
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
213
+ echo ""
214
+ echo "📋 错误码:$ERROR_CODE"
215
+
216
+ # 提取错误信息
217
+ local ERROR_MSG=$(echo "$UNWRAPPED" | jq -r '.errorMessage // .data.errorMessage // .error.message // .message // "未知错误"' 2>/dev/null)
218
+ local BIZ_TIPS=$(echo "$UNWRAPPED" | jq -r '.bizTips // .data.bizTips // ""' 2>/dev/null)
219
+ local NEED_RETRY=$(echo "$UNWRAPPED" | jq -r '.needRetry // .data.needRetry // "false"' 2>/dev/null)
220
+
221
+ echo "📋 错误信息:$ERROR_MSG"
222
+
223
+ # 透出 checkedError 中的详细错误描述(如 ar-sign.apply 返回的字段级校验错误)
224
+ local CHECKED_ERRORS=$(echo "$UNWRAPPED" | jq -r '.resultObj.checkedError // .data.checkedError // empty' 2>/dev/null)
225
+ if [ -n "$CHECKED_ERRORS" ] && [ "$CHECKED_ERRORS" != "null" ] && [ "$CHECKED_ERRORS" != "[]" ]; then
226
+ echo ""
227
+ echo "📋 详细校验错误:"
228
+ echo "$CHECKED_ERRORS" | jq -r '.[]? | .errorDesc // .message // . // empty' 2>/dev/null | while IFS= read -r line; do
229
+ [ -n "$line" ] && echo " - $line"
230
+ done
231
+ fi
232
+
233
+ if [ -n "$BIZ_TIPS" ] && [ "$BIZ_TIPS" != "null" ] && [ "$BIZ_TIPS" != "" ]; then
234
+ echo ""
235
+ echo "💡 提示:$BIZ_TIPS"
236
+ fi
237
+
238
+ if [ "$NEED_RETRY" = "true" ]; then
239
+ echo ""
240
+ echo "🔄 此错误可重试,请回复「重试」重新执行"
241
+ fi
242
+
243
+ echo ""
244
+ echo "如需帮助,请联系技术支持并提供以上错误信息。"
245
+ }
246
+
247
+ # ─── MCP 服务不稳定处理 ────────────────────────────────────────────────────
248
+ handle_service_unstable() {
249
+ echo ""
250
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
251
+ echo "⚠️ MCP 服务暂时不稳定"
252
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
253
+ echo ""
254
+ echo "当前无法继续执行,请稍后重试。"
255
+ echo ""
256
+ echo "您可以:"
257
+ echo " 1. 等待几分钟后重新执行"
258
+ echo " 2. 检查网络连接是否正常"
259
+ echo " 3. 联系技术支持获取帮助"
260
+ echo ""
261
+ echo "请回复「重试」重新尝试,或「退出」结束流程。"
262
+ }
263
+
264
+ # ─── 统一错误处理入口 ──────────────────────────────────────────────────────
265
+ # 参数: $1 - CLI 执行结果文本(原始输出,含信封或不含)
266
+ # 返回: 0=成功, 1=失败(需要用户干预)
267
+ handle_error() {
268
+ local CLI_RESULT="$1"
269
+ local ERROR_TYPE=$(detect_error "$CLI_RESULT")
270
+ # 解包一次供 CLI_ERROR 分支使用(其他分支由各自的 handler 自己解包)
271
+ local _UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
272
+
273
+ case "$ERROR_TYPE" in
274
+ "MCP_AUTH_ERROR")
275
+ handle_mcp_auth_error
276
+ ;;
277
+ "MCP_SERVICE_ERROR")
278
+ handle_mcp_service_error "$CLI_RESULT"
279
+ ;;
280
+ "AUTH_MISMATCH")
281
+ handle_auth_mismatch "$CLI_RESULT"
282
+ ;;
283
+ "SERVICE_UNSTABLE")
284
+ handle_service_unstable
285
+ ;;
286
+ "ERROR:"*)
287
+ local CODE="${ERROR_TYPE#ERROR:}"
288
+ handle_backend_error "$CLI_RESULT" "$CODE"
289
+ ;;
290
+ "CLI_ERROR:"*)
291
+ local MSG="${ERROR_TYPE#CLI_ERROR:}"
292
+ echo "❌ 命令执行失败:$MSG"
293
+ # CLI_ERROR 也透出 bizTips 和 checkedError(如果有的话)
294
+ local CLI_BIZ_TIPS=$(echo "$_UNWRAPPED" | jq -r '.bizTips // .data.bizTips // ""' 2>/dev/null)
295
+ if [ -n "$CLI_BIZ_TIPS" ] && [ "$CLI_BIZ_TIPS" != "null" ] && [ "$CLI_BIZ_TIPS" != "" ]; then
296
+ echo "💡 $CLI_BIZ_TIPS"
297
+ fi
298
+ local CLI_CHECKED=$(echo "$_UNWRAPPED" | jq -r '.resultObj.checkedError // .data.checkedError // empty' 2>/dev/null)
299
+ if [ -n "$CLI_CHECKED" ] && [ "$CLI_CHECKED" != "null" ] && [ "$CLI_CHECKED" != "[]" ]; then
300
+ echo "📋 详细校验错误:"
301
+ echo "$CLI_CHECKED" | jq -r '.[]? | .errorDesc // .message // . // empty' 2>/dev/null | while IFS= read -r line; do
302
+ [ -n "$line" ] && echo " - $line"
303
+ done
304
+ fi
305
+ ;;
306
+ "SUCCESS")
307
+ return 0
308
+ ;;
309
+ esac
310
+
311
+ return 1
312
+ }
@@ -0,0 +1,146 @@
1
+ #!/bin/bash
2
+ #=============================================================================
3
+ # 脚本名称: query_sign_status.sh
4
+ # 功能描述: 查询签约状态并根据结果判断后续流程
5
+ # 调用位置: Step 3.1 签约状态查询
6
+ # 调用前置: 脚本通过 error_handler.sh 间接初始化 DEV_TOOL_NAME;需传入 --sales-code,或兼容使用 SALES_CODE 环境变量
7
+ # 用法: bash query_sign_status.sh --sales-code <code> [--product-type aipay|webpay|apppay]
8
+ # 返回值: 输出签约状态判断结果和处理建议
9
+ # SIGN_STATUS=NOT_SIGNED | SIGN_STATUS=SIGNED_EFFECTIVE | SIGN_STATUS=SIGN_SUBMITTED | SIGN_STATUS=OTHER_STATUS
10
+ # 按量付费: FLOW:AI_PAY_NOT_SIGNED | FLOW:AI_PAY_SIGNED
11
+ # 网站支付: FLOW:PC_WEB_NOT_SIGNED | FLOW:PC_WEB_SIGNED
12
+ # APP支付: FLOW:APP_NOT_SIGNED | FLOW:APP_SIGNED
13
+ #=============================================================================
14
+
15
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16
+
17
+ # 一次性 source error_handler(含 unwrap_mcp)
18
+ if [ -f "${SCRIPT_DIR}/error_handler.sh" ]; then
19
+ source "${SCRIPT_DIR}/error_handler.sh"
20
+ else
21
+ echo "❌ 缺少错误处理脚本: ${SCRIPT_DIR}/error_handler.sh"
22
+ exit 1
23
+ fi
24
+
25
+ require_command jq || exit 1
26
+ require_command alipay-cli || exit 1
27
+
28
+ export PRODUCT_TYPE="${PRODUCT_TYPE:-unknown}"
29
+
30
+ while [[ $# -gt 0 ]]; do
31
+ case $1 in
32
+ --sales-code)
33
+ [ $# -ge 2 ] || { echo "❌ 缺少参数值: $1"; exit 1; }
34
+ SALES_CODE="$2"; shift 2 ;;
35
+ --product-type)
36
+ [ $# -ge 2 ] || { echo "❌ 缺少参数值: $1"; exit 1; }
37
+ PRODUCT_TYPE="$2"; shift 2 ;;
38
+ *)
39
+ echo "❌ 未知参数: $1"
40
+ echo "用法: bash query_sign_status.sh --sales-code <code> [--product-type aipay|webpay|apppay]"
41
+ exit 1 ;;
42
+ esac
43
+ done
44
+
45
+ if [ -z "$SALES_CODE" ]; then
46
+ echo "❌ 缺少 salesCode(请传入 --sales-code,或设置 SALES_CODE 环境变量)"
47
+ exit 1
48
+ fi
49
+
50
+ case "$SALES_CODE" in
51
+ "I1080300001000160457")
52
+ EXPECTED_PRODUCT_TYPE="aipay"
53
+ ;;
54
+ "I1080300001000041203")
55
+ EXPECTED_PRODUCT_TYPE="webpay"
56
+ ;;
57
+ "I1080300001000041313")
58
+ EXPECTED_PRODUCT_TYPE="apppay"
59
+ ;;
60
+ *)
61
+ echo "❌ 未知 SALES_CODE: ${SALES_CODE}"
62
+ exit 1
63
+ ;;
64
+ esac
65
+
66
+ if [ "$PRODUCT_TYPE" != "unknown" ] && [ "$PRODUCT_TYPE" != "$EXPECTED_PRODUCT_TYPE" ]; then
67
+ echo "❌ PRODUCT_TYPE 与 SALES_CODE 不匹配:PRODUCT_TYPE=${PRODUCT_TYPE}, SALES_CODE=${SALES_CODE}"
68
+ echo "📋 期望 PRODUCT_TYPE=${EXPECTED_PRODUCT_TYPE}"
69
+ exit 1
70
+ fi
71
+
72
+ emit_signed_flow() {
73
+ case "$SALES_CODE" in
74
+ "I1080300001000041203")
75
+ echo "FLOW:PC_WEB_SIGNED"
76
+ # 网站支付已生效或已提交:跳过签约提交,直接进入应用发布
77
+ ;;
78
+ "I1080300001000041313")
79
+ echo "FLOW:APP_SIGNED"
80
+ # APP支付已生效或已提交:跳过签约提交,直接进入应用发布
81
+ ;;
82
+ "I1080300001000160457")
83
+ echo "FLOW:AI_PAY_SIGNED"
84
+ # 按量付费已生效或已提交:跳过签约提交,直接进入服务注册 + 应用发布
85
+ ;;
86
+ esac
87
+ }
88
+
89
+ # 查询签约状态
90
+ RESULT=$(export PLATFORM=${DEV_TOOL_NAME} && alipay-cli mcp call ar-query.queryArInfosBySalesProd \
91
+ -d "{\"request\":{\"salesProductCodes\":[\"${SALES_CODE}\"]},\"ctx\":{}}" \
92
+ --json 2>/dev/null)
93
+
94
+ # 错误检测
95
+ if ! handle_error "$RESULT"; then
96
+ exit 1
97
+ fi
98
+
99
+ # 解包 MCP 信封后解析业务字段
100
+ BUSINESS=$(unwrap_mcp "$RESULT")
101
+
102
+ # 使用 // [] 安全提取数组,判断签约状态;解析失败必须阻断,避免误判为未签约
103
+ AR_LIST=$(echo "$BUSINESS" | jq -c '.resultObj.arInfoList // []' 2>/dev/null)
104
+ if [ -z "$AR_LIST" ] || ! echo "$AR_LIST" | jq -e 'type == "array"' >/dev/null 2>&1; then
105
+ echo "❌ 签约状态返回结构异常,无法解析 arInfoList"
106
+ exit 1
107
+ fi
108
+ AR_COUNT=$(echo "$AR_LIST" | jq 'length')
109
+
110
+ if [ "$AR_COUNT" -eq 0 ]; then
111
+ echo "📋 未签约 (NOT_SIGNED),进入资料采集流程"
112
+ echo "SIGN_STATUS=NOT_SIGNED"
113
+
114
+ case "$SALES_CODE" in
115
+ "I1080300001000041203")
116
+ echo "FLOW:PC_WEB_NOT_SIGNED"
117
+ # 网站支付未签约:需先采集 3 张网站截图,再进入 Step 5 签约
118
+ ;;
119
+ "I1080300001000041313")
120
+ echo "FLOW:APP_NOT_SIGNED"
121
+ # APP支付未签约:需先采集 APP 名称和 3 张APP界面截图,再进入 Step 5 签约
122
+ ;;
123
+ "I1080300001000160457")
124
+ echo "FLOW:AI_PAY_NOT_SIGNED"
125
+ # 按量付费未签约:跳过 Step 4,进入 Step 5.1 签约,再继续服务注册 + 应用发布
126
+ ;;
127
+ esac
128
+ else
129
+ # 使用 // [] 避免迭代 null 报错
130
+ HAS_EFFECTIVE=$(echo "$AR_LIST" | jq -r '[.[] | select(.arStatus == "02")] | length')
131
+ HAS_SUBMITTED=$(echo "$AR_LIST" | jq -r '[.[] | select(.arStatus == "01")] | length')
132
+
133
+ if [ "$HAS_EFFECTIVE" -gt 0 ]; then
134
+ echo "✅ 已签约(已生效),跳过资料采集"
135
+ echo "SIGN_STATUS=SIGNED_EFFECTIVE"
136
+ emit_signed_flow
137
+ elif [ "$HAS_SUBMITTED" -gt 0 ]; then
138
+ echo "📋 已提交签约(待生效),无需重复提交签约,继续推进后续步骤"
139
+ echo "SIGN_STATUS=SIGN_SUBMITTED"
140
+ emit_signed_flow
141
+ else
142
+ echo "📋 其他签约状态,进入资料采集流程"
143
+ echo "SIGN_STATUS=OTHER_STATUS"
144
+ echo "FLOW:OTHER_STATUS"
145
+ fi
146
+ fi