@alipay/alipay-aipay 1.0.0 → 1.0.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.
- package/bin/alipay-aipay.js +6 -0
- package/dist/commands/install.d.ts +11 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +182 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/prepare-tools.d.ts +5 -0
- package/dist/commands/prepare-tools.d.ts.map +1 -0
- package/dist/commands/prepare-tools.js +29 -0
- package/dist/commands/prepare-tools.js.map +1 -0
- package/dist/commands/uninstall.d.ts +10 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +82 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +10 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +155 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +65 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +43 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/alipay-cli.d.ts +15 -0
- package/dist/utils/alipay-cli.d.ts.map +1 -0
- package/dist/utils/alipay-cli.js +221 -0
- package/dist/utils/alipay-cli.js.map +1 -0
- package/dist/utils/config.d.ts +48 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +207 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/file.d.ts +55 -0
- package/dist/utils/file.d.ts.map +1 -0
- package/dist/utils/file.js +154 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/gpg.d.ts +14 -0
- package/dist/utils/gpg.d.ts.map +1 -0
- package/dist/utils/gpg.js +247 -0
- package/dist/utils/gpg.js.map +1 -0
- package/dist/utils/jq.d.ts +14 -0
- package/dist/utils/jq.d.ts.map +1 -0
- package/dist/utils/jq.js +221 -0
- package/dist/utils/jq.js.map +1 -0
- package/dist/utils/npm.d.ts +17 -0
- package/dist/utils/npm.d.ts.map +1 -0
- package/dist/utils/npm.js +42 -0
- package/dist/utils/npm.js.map +1 -0
- package/dist/utils/shell.d.ts +11 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +54 -0
- package/dist/utils/shell.js.map +1 -0
- package/package.json +48 -7
- package/skill/SKILL.md +118 -0
- package/skill/references/integration/flow.md +487 -0
- package/skill/references/integration/modules/alipay-sdk-reminder.md +256 -0
- package/skill/references/integration/modules/checklist.md +122 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/skill/references/integration/modules/interface-guide.md +90 -0
- package/skill/references/integration/modules/product-decision.md +90 -0
- package/skill/references/integration/modules/sandbox/a2m-sandbox-test.md +270 -0
- package/skill/references/integration/modules/sandbox/alipay-sandbox-tool.md +133 -0
- package/skill/references/integration/modules/sandbox/sandbox-setup-guide.md +218 -0
- package/skill/references/integration/modules/scripts/local_402_sandbox_pay.py +659 -0
- package/skill/references/normal/alipay-cli-env.md +214 -0
- package/skill/references/normal/rejection-guide.md +37 -0
- package/skill/references/normal/scripts/common.sh +32 -0
- package/skill/references/normal/scripts/detect_dev_tool.sh +46 -0
- package/skill/references/onboarding/flow.md +573 -0
- package/skill/references/onboarding/modules/app-release.md +415 -0
- package/skill/references/onboarding/modules/authorization.md +269 -0
- package/skill/references/onboarding/modules/error-handling.md +251 -0
- package/skill/references/onboarding/modules/mcc-reference.md +209 -0
- package/skill/references/onboarding/modules/product-sign.md +304 -0
- package/skill/references/onboarding/modules/scripts/app.sh +705 -0
- package/skill/references/onboarding/modules/scripts/ar_sign_apply.sh +248 -0
- package/skill/references/onboarding/modules/scripts/auth.sh +505 -0
- package/skill/references/onboarding/modules/scripts/error_handler.sh +452 -0
- package/skill/references/onboarding/modules/scripts/query_sign_status.sh +146 -0
- package/skill/references/onboarding/modules/scripts/service.sh +267 -0
- package/skill/references/onboarding/modules/scripts/upload_screenshots.sh +152 -0
- package/skill/references/onboarding/modules/service-registration.md +294 -0
|
@@ -0,0 +1,452 @@
|
|
|
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
|
+
# ─── JSON 错误字段提取 ─────────────────────────────────────────────────────
|
|
51
|
+
# 部分 MCP 后端会把真实业务响应包在 data/response 或 errorContext.errorStack 下。
|
|
52
|
+
# 下面的提取函数优先定位同一个错误对象,避免 success=false 时丢失真实错误体。
|
|
53
|
+
extract_first_named_field() {
|
|
54
|
+
local JSON="$1"
|
|
55
|
+
local FIELD="$2"
|
|
56
|
+
echo "$JSON" | jq -r --arg field "$FIELD" '
|
|
57
|
+
[.. | objects | .[$field]? | select(. != null and (tostring != ""))][0] // ""
|
|
58
|
+
' 2>/dev/null
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
extract_error_object() {
|
|
62
|
+
echo "$1" | jq -c '
|
|
63
|
+
[
|
|
64
|
+
.. | objects |
|
|
65
|
+
select(
|
|
66
|
+
((.errorCode? | type) == "string" and .errorCode != "") or
|
|
67
|
+
((.errorCode? | type) == "object" and ((.errorCode.code? // "") != ""))
|
|
68
|
+
)
|
|
69
|
+
][0] // empty
|
|
70
|
+
' 2>/dev/null
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
extract_error_code() {
|
|
74
|
+
local ERROR_OBJECT
|
|
75
|
+
ERROR_OBJECT=$(extract_error_object "$1")
|
|
76
|
+
if [ -n "$ERROR_OBJECT" ]; then
|
|
77
|
+
echo "$ERROR_OBJECT" | jq -r '
|
|
78
|
+
if (.errorCode | type) == "string" then .errorCode
|
|
79
|
+
elif (.errorCode | type) == "object" then (.errorCode.code // "")
|
|
80
|
+
else ""
|
|
81
|
+
end
|
|
82
|
+
' 2>/dev/null
|
|
83
|
+
return
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
echo ""
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
extract_error_message() {
|
|
90
|
+
local JSON="$1"
|
|
91
|
+
local ERROR_OBJECT
|
|
92
|
+
ERROR_OBJECT=$(extract_error_object "$JSON")
|
|
93
|
+
if [ -n "$ERROR_OBJECT" ]; then
|
|
94
|
+
echo "$ERROR_OBJECT" | jq -r '
|
|
95
|
+
.errorMessage //
|
|
96
|
+
.errorMsg //
|
|
97
|
+
.error.message //
|
|
98
|
+
.message //
|
|
99
|
+
(if (.errorCode | type) == "object" then (.errorCode.desc // .errorCode.message) else empty end) //
|
|
100
|
+
"未知错误"
|
|
101
|
+
' 2>/dev/null
|
|
102
|
+
return
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
echo "$JSON" | jq -r '
|
|
106
|
+
[
|
|
107
|
+
.. | objects |
|
|
108
|
+
(.errorMessage?, .errorMsg?, .message?, (.error? | objects | .message?)) |
|
|
109
|
+
select(. != null and (tostring != ""))
|
|
110
|
+
][0] // "未知错误"
|
|
111
|
+
' 2>/dev/null
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
extract_biz_tips() {
|
|
115
|
+
local ERROR_OBJECT
|
|
116
|
+
ERROR_OBJECT=$(extract_error_object "$1")
|
|
117
|
+
if [ -n "$ERROR_OBJECT" ]; then
|
|
118
|
+
echo "$ERROR_OBJECT" | jq -r '.bizTips // ""' 2>/dev/null
|
|
119
|
+
return
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
extract_first_named_field "$1" "bizTips"
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
extract_need_retry() {
|
|
126
|
+
local JSON="$1"
|
|
127
|
+
local ERROR_OBJECT
|
|
128
|
+
ERROR_OBJECT=$(extract_error_object "$JSON")
|
|
129
|
+
if [ -n "$ERROR_OBJECT" ]; then
|
|
130
|
+
echo "$ERROR_OBJECT" | jq -r 'if .needRetry == true then "true" else "false" end' 2>/dev/null
|
|
131
|
+
return
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
echo "$JSON" | jq -r '
|
|
135
|
+
if any(.. | objects; .needRetry? == true) then "true" else "false" end
|
|
136
|
+
' 2>/dev/null
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
extract_error_object_field() {
|
|
140
|
+
local JSON="$1"
|
|
141
|
+
local FIELD="$2"
|
|
142
|
+
local ERROR_OBJECT
|
|
143
|
+
ERROR_OBJECT=$(extract_error_object "$JSON")
|
|
144
|
+
if [ -n "$ERROR_OBJECT" ]; then
|
|
145
|
+
echo "$ERROR_OBJECT" | jq -r --arg field "$FIELD" '
|
|
146
|
+
.[$field] //
|
|
147
|
+
(if (.errorCode | type) == "object" then (.errorCode[$field] // "") else "" end)
|
|
148
|
+
' 2>/dev/null
|
|
149
|
+
return
|
|
150
|
+
fi
|
|
151
|
+
|
|
152
|
+
extract_first_named_field "$JSON" "$FIELD"
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
extract_success_state() {
|
|
156
|
+
local JSON="$1"
|
|
157
|
+
echo "$JSON" | jq -r '
|
|
158
|
+
if any(.. | objects; .success? == false) then "false"
|
|
159
|
+
elif any(.. | objects; .success? == true) then "true"
|
|
160
|
+
else "null"
|
|
161
|
+
end
|
|
162
|
+
' 2>/dev/null
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
extract_checked_errors() {
|
|
166
|
+
local JSON="$1"
|
|
167
|
+
echo "$JSON" | jq -c '
|
|
168
|
+
[
|
|
169
|
+
.. | objects |
|
|
170
|
+
(
|
|
171
|
+
.checkedError?,
|
|
172
|
+
(.resultObj? | objects | .checkedError?),
|
|
173
|
+
(.data? | objects | .checkedError?)
|
|
174
|
+
) |
|
|
175
|
+
select(. != null)
|
|
176
|
+
][0] // empty
|
|
177
|
+
' 2>/dev/null
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
# ─── 统一错误检测 ──────────────────────────────────────────────────────────
|
|
181
|
+
# 参数: $1 - CLI 执行结果文本(原始输出,含信封或不含)
|
|
182
|
+
# 返回: MCP_AUTH_ERROR | MCP_SERVICE_ERROR | AUTH_MISMATCH | SERVICE_UNSTABLE | ERROR:xxx | CLI_ERROR:xxx | SUCCESS
|
|
183
|
+
detect_error() {
|
|
184
|
+
local CLI_RESULT="$1"
|
|
185
|
+
|
|
186
|
+
# 空输入视为异常,不应被当作 SUCCESS
|
|
187
|
+
if [ -z "$CLI_RESULT" ]; then
|
|
188
|
+
echo "CLI_ERROR:CLI 返回为空"
|
|
189
|
+
return
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
# 先解包 MCP 信封,再进行错误检测
|
|
193
|
+
local UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
|
|
194
|
+
|
|
195
|
+
# 1. 优先检测 MCP 认证错误(HTTP 401)
|
|
196
|
+
if echo "$UNWRAPPED" | grep -qiE "HTTP 401|Authorization is empty|非法的认证信息"; then
|
|
197
|
+
echo "MCP_AUTH_ERROR"
|
|
198
|
+
return
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
# 2. MCP 服务不稳定(后端返回的服务异常)
|
|
202
|
+
if echo "$UNWRAPPED" | grep -qiE "MCP.*服务.*不稳定|服务暂时不可用"; then
|
|
203
|
+
echo "SERVICE_UNSTABLE"
|
|
204
|
+
return
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
# 3. MCP 调用失败(网络/连接错误)
|
|
208
|
+
if echo "$UNWRAPPED" | grep -qiE "MCP 调用失败|connection refused|timeout|network error"; then
|
|
209
|
+
echo "MCP_SERVICE_ERROR"
|
|
210
|
+
return
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
# 4. 授权信息不匹配(MCC/产品/scope 未授权)
|
|
214
|
+
if echo "$UNWRAPPED" | grep -qiE "mccCode.*is not auth|salesProductCodes.*is not auth|scope.*is not auth"; then
|
|
215
|
+
echo "AUTH_MISMATCH"
|
|
216
|
+
return
|
|
217
|
+
fi
|
|
218
|
+
|
|
219
|
+
if ! echo "$UNWRAPPED" | jq -e . >/dev/null 2>&1; then
|
|
220
|
+
local FIRST_LINE
|
|
221
|
+
FIRST_LINE=$(printf "%s" "$UNWRAPPED" | sed -n '1p')
|
|
222
|
+
echo "CLI_ERROR:${FIRST_LINE:-CLI 返回非 JSON 内容}"
|
|
223
|
+
return
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# 5. 通用业务错误(从解包后的 JSON 中提取 errorCode)
|
|
227
|
+
local ERROR_CODE=$(extract_error_code "$UNWRAPPED")
|
|
228
|
+
if [ -n "$ERROR_CODE" ] && [ "$ERROR_CODE" != "null" ]; then
|
|
229
|
+
echo "ERROR:$ERROR_CODE"
|
|
230
|
+
return
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
# 6. CLI 命令本身的错误(success: false,从解包后的 JSON 提取)
|
|
234
|
+
# 注意: MCP 业务响应可能嵌套在 data/response 下,因此递归检测 success=false。
|
|
235
|
+
local SUCCESS=$(extract_success_state "$UNWRAPPED")
|
|
236
|
+
if [ "$SUCCESS" = "false" ]; then
|
|
237
|
+
local ERROR_MSG=$(extract_error_message "$UNWRAPPED")
|
|
238
|
+
echo "CLI_ERROR:$ERROR_MSG"
|
|
239
|
+
return
|
|
240
|
+
fi
|
|
241
|
+
|
|
242
|
+
echo "SUCCESS"
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
# ─── MCP 认证错误处理 ──────────────────────────────────────────────────────
|
|
246
|
+
handle_mcp_auth_error() {
|
|
247
|
+
echo ""
|
|
248
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
249
|
+
echo "🔐 未登录或授权已过期"
|
|
250
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
251
|
+
echo ""
|
|
252
|
+
echo "❌ 当前登录状态已失效,无法继续操作"
|
|
253
|
+
echo ""
|
|
254
|
+
echo "📋 原因:MCP 调用返回认证错误(HTTP 401)"
|
|
255
|
+
echo "📋 说明:Authorization is empty(认证信息为空)"
|
|
256
|
+
echo ""
|
|
257
|
+
echo "🔄 正在退出当前登录..."
|
|
258
|
+
export PLATFORM=${DEV_TOOL_NAME:-unknown} && alipay-cli logout --json 2>/dev/null
|
|
259
|
+
|
|
260
|
+
echo ""
|
|
261
|
+
echo "✅ 已退出登录状态"
|
|
262
|
+
echo ""
|
|
263
|
+
echo "📌 请重新执行登录授权流程:"
|
|
264
|
+
echo " 1. 我会生成授权链接"
|
|
265
|
+
echo " 2. 您使用支付宝扫码授权"
|
|
266
|
+
echo " 3. 授权成功后继续当前操作"
|
|
267
|
+
echo ""
|
|
268
|
+
echo "请回复「继续」开始重新授权,或「退出」结束流程。"
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
# ─── MCP 服务不可用处理 ────────────────────────────────────────────────────
|
|
272
|
+
handle_mcp_service_error() {
|
|
273
|
+
local CLI_RESULT="$1"
|
|
274
|
+
local UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
|
|
275
|
+
|
|
276
|
+
echo ""
|
|
277
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
278
|
+
echo "⚠️ MCP 服务暂时不可用"
|
|
279
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
280
|
+
echo ""
|
|
281
|
+
if [ "${DEV_TOOL_NAME:-unknown}" != "unknown" ]; then
|
|
282
|
+
echo "❌ 当前命令需要访问支付宝服务,但当前 Agent 执行环境可能没有外网权限"
|
|
283
|
+
echo ""
|
|
284
|
+
echo "📋 处理方式:"
|
|
285
|
+
echo " - Agent 应申请可联网权限后重试同一条命令"
|
|
286
|
+
echo " - 不要要求用户排查本机网络,也不要更换业务参数"
|
|
287
|
+
echo ""
|
|
288
|
+
echo "请授权 Agent 联网重试,或稍后重新执行当前命令。"
|
|
289
|
+
return
|
|
290
|
+
fi
|
|
291
|
+
|
|
292
|
+
echo "❌ 无法连接到支付宝服务,请稍后重试"
|
|
293
|
+
echo ""
|
|
294
|
+
echo "📋 错误详情:"
|
|
295
|
+
echo "$UNWRAPPED" | jq -r '.error.message // .errorMessage // .message // "未知错误"' 2>/dev/null || echo "$UNWRAPPED"
|
|
296
|
+
echo ""
|
|
297
|
+
echo "您可以:"
|
|
298
|
+
echo " 1. 检查网络连接是否正常"
|
|
299
|
+
echo " 2. 等待几分钟后重新执行"
|
|
300
|
+
echo " 3. 联系技术支持获取帮助"
|
|
301
|
+
echo ""
|
|
302
|
+
echo "请回复「重试」重新尝试,或「退出」结束流程。"
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
# ─── 授权信息不匹配处理 ────────────────────────────────────────────────────
|
|
306
|
+
handle_auth_mismatch() {
|
|
307
|
+
local CLI_RESULT="$1"
|
|
308
|
+
local UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
|
|
309
|
+
|
|
310
|
+
echo ""
|
|
311
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
312
|
+
echo "❌ 授权信息不匹配,需要重新授权"
|
|
313
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
314
|
+
|
|
315
|
+
if echo "$UNWRAPPED" | grep -qi "mccCode is not auth"; then
|
|
316
|
+
echo "📋 原因:经营类目未授权"
|
|
317
|
+
elif echo "$UNWRAPPED" | grep -qi "salesProductCodes is not auth"; then
|
|
318
|
+
echo "📋 原因:产品未授权"
|
|
319
|
+
elif echo "$UNWRAPPED" | grep -qi "scope is not auth"; then
|
|
320
|
+
echo "📋 原因:授权 scope 不满足"
|
|
321
|
+
fi
|
|
322
|
+
|
|
323
|
+
echo ""
|
|
324
|
+
echo ""
|
|
325
|
+
|
|
326
|
+
echo "🔄 正在退出当前登录..."
|
|
327
|
+
export PLATFORM=${DEV_TOOL_NAME:-unknown} && alipay-cli logout --json 2>/dev/null
|
|
328
|
+
|
|
329
|
+
echo "✅ 已退出登录,请重新执行登录授权流程"
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
# ─── 后端业务错误处理(完整透出错误信息) ──────────────────────────────────
|
|
333
|
+
handle_backend_error() {
|
|
334
|
+
local CLI_RESULT="$1"
|
|
335
|
+
local ERROR_CODE="$2"
|
|
336
|
+
local UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
|
|
337
|
+
|
|
338
|
+
echo ""
|
|
339
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
340
|
+
echo "❌ 业务处理失败"
|
|
341
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
342
|
+
echo ""
|
|
343
|
+
echo "📋 错误码:$ERROR_CODE"
|
|
344
|
+
|
|
345
|
+
# 提取错误信息
|
|
346
|
+
local ERROR_MSG=$(extract_error_message "$UNWRAPPED")
|
|
347
|
+
local BIZ_TIPS=$(extract_biz_tips "$UNWRAPPED")
|
|
348
|
+
local NEED_RETRY=$(extract_need_retry "$UNWRAPPED")
|
|
349
|
+
local ERROR_SCENE=$(extract_error_object_field "$UNWRAPPED" "errorScene")
|
|
350
|
+
local ERROR_SPECIFIC=$(extract_error_object_field "$UNWRAPPED" "errorSpecific")
|
|
351
|
+
|
|
352
|
+
echo "📋 错误信息:$ERROR_MSG"
|
|
353
|
+
|
|
354
|
+
if [ -n "$ERROR_SCENE" ] || [ -n "$ERROR_SPECIFIC" ]; then
|
|
355
|
+
echo "📋 错误场景:${ERROR_SCENE:-未知} / ${ERROR_SPECIFIC:-未知}"
|
|
356
|
+
fi
|
|
357
|
+
|
|
358
|
+
# 透出 checkedError 中的详细错误描述(如 ar-sign.apply 返回的字段级校验错误)
|
|
359
|
+
local CHECKED_ERRORS=$(extract_checked_errors "$UNWRAPPED")
|
|
360
|
+
if [ -n "$CHECKED_ERRORS" ] && [ "$CHECKED_ERRORS" != "null" ] && [ "$CHECKED_ERRORS" != "[]" ]; then
|
|
361
|
+
echo ""
|
|
362
|
+
echo "📋 详细校验错误:"
|
|
363
|
+
echo "$CHECKED_ERRORS" | jq -r '.[]? | .errorDesc // .message // . // empty' 2>/dev/null | while IFS= read -r line; do
|
|
364
|
+
[ -n "$line" ] && echo " - $line"
|
|
365
|
+
done
|
|
366
|
+
fi
|
|
367
|
+
|
|
368
|
+
if [ -n "$BIZ_TIPS" ] && [ "$BIZ_TIPS" != "null" ] && [ "$BIZ_TIPS" != "" ]; then
|
|
369
|
+
echo ""
|
|
370
|
+
echo "💡 提示:$BIZ_TIPS"
|
|
371
|
+
fi
|
|
372
|
+
|
|
373
|
+
if [ "$ERROR_CODE" = "APP_MAX_ERROR" ]; then
|
|
374
|
+
echo ""
|
|
375
|
+
echo "📌 处理建议:当前主体下应用数量已达到上限,无法继续新建应用。请优先复用已有上线应用;如必须新建,请前往支付宝开放平台处理应用配额或联系支付宝技术支持。"
|
|
376
|
+
fi
|
|
377
|
+
|
|
378
|
+
if [ "$NEED_RETRY" = "true" ]; then
|
|
379
|
+
echo ""
|
|
380
|
+
echo "🔄 此错误可重试,请回复「重试」重新执行"
|
|
381
|
+
fi
|
|
382
|
+
|
|
383
|
+
echo ""
|
|
384
|
+
echo "如需帮助,请联系技术支持并提供以上错误信息。"
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
# ─── MCP 服务不稳定处理 ────────────────────────────────────────────────────
|
|
388
|
+
handle_service_unstable() {
|
|
389
|
+
echo ""
|
|
390
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
391
|
+
echo "⚠️ MCP 服务暂时不稳定"
|
|
392
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
393
|
+
echo ""
|
|
394
|
+
echo "当前无法继续执行,请稍后重试。"
|
|
395
|
+
echo ""
|
|
396
|
+
echo "您可以:"
|
|
397
|
+
echo " 1. 等待几分钟后重新执行"
|
|
398
|
+
echo " 2. 检查网络连接是否正常"
|
|
399
|
+
echo " 3. 联系技术支持获取帮助"
|
|
400
|
+
echo ""
|
|
401
|
+
echo "请回复「重试」重新尝试,或「退出」结束流程。"
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
# ─── 统一错误处理入口 ──────────────────────────────────────────────────────
|
|
405
|
+
# 参数: $1 - CLI 执行结果文本(原始输出,含信封或不含)
|
|
406
|
+
# 返回: 0=成功, 1=失败(需要用户干预)
|
|
407
|
+
handle_error() {
|
|
408
|
+
local CLI_RESULT="$1"
|
|
409
|
+
local ERROR_TYPE=$(detect_error "$CLI_RESULT")
|
|
410
|
+
# 解包一次供 CLI_ERROR 分支使用(其他分支由各自的 handler 自己解包)
|
|
411
|
+
local _UNWRAPPED=$(unwrap_mcp "$CLI_RESULT")
|
|
412
|
+
|
|
413
|
+
case "$ERROR_TYPE" in
|
|
414
|
+
"MCP_AUTH_ERROR")
|
|
415
|
+
handle_mcp_auth_error
|
|
416
|
+
;;
|
|
417
|
+
"MCP_SERVICE_ERROR")
|
|
418
|
+
handle_mcp_service_error "$CLI_RESULT"
|
|
419
|
+
;;
|
|
420
|
+
"AUTH_MISMATCH")
|
|
421
|
+
handle_auth_mismatch "$CLI_RESULT"
|
|
422
|
+
;;
|
|
423
|
+
"SERVICE_UNSTABLE")
|
|
424
|
+
handle_service_unstable
|
|
425
|
+
;;
|
|
426
|
+
"ERROR:"*)
|
|
427
|
+
local CODE="${ERROR_TYPE#ERROR:}"
|
|
428
|
+
handle_backend_error "$CLI_RESULT" "$CODE"
|
|
429
|
+
;;
|
|
430
|
+
"CLI_ERROR:"*)
|
|
431
|
+
local MSG="${ERROR_TYPE#CLI_ERROR:}"
|
|
432
|
+
echo "❌ 命令执行失败:$MSG"
|
|
433
|
+
# CLI_ERROR 也透出 bizTips 和 checkedError(如果有的话)
|
|
434
|
+
local CLI_BIZ_TIPS=$(extract_biz_tips "$_UNWRAPPED")
|
|
435
|
+
if [ -n "$CLI_BIZ_TIPS" ] && [ "$CLI_BIZ_TIPS" != "null" ] && [ "$CLI_BIZ_TIPS" != "" ]; then
|
|
436
|
+
echo "💡 $CLI_BIZ_TIPS"
|
|
437
|
+
fi
|
|
438
|
+
local CLI_CHECKED=$(extract_checked_errors "$_UNWRAPPED")
|
|
439
|
+
if [ -n "$CLI_CHECKED" ] && [ "$CLI_CHECKED" != "null" ] && [ "$CLI_CHECKED" != "[]" ]; then
|
|
440
|
+
echo "📋 详细校验错误:"
|
|
441
|
+
echo "$CLI_CHECKED" | jq -r '.[]? | .errorDesc // .message // . // empty' 2>/dev/null | while IFS= read -r line; do
|
|
442
|
+
[ -n "$line" ] && echo " - $line"
|
|
443
|
+
done
|
|
444
|
+
fi
|
|
445
|
+
;;
|
|
446
|
+
"SUCCESS")
|
|
447
|
+
return 0
|
|
448
|
+
;;
|
|
449
|
+
esac
|
|
450
|
+
|
|
451
|
+
return 1
|
|
452
|
+
}
|
|
@@ -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
|