@alipay/alipay-aipay 1.2.2 → 1.5.0

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 (104) hide show
  1. package/README.md +5 -0
  2. package/dist/commands/install.d.ts.map +1 -1
  3. package/dist/commands/install.js +13 -12
  4. package/dist/commands/install.js.map +1 -1
  5. package/dist/commands/uninstall.d.ts.map +1 -1
  6. package/dist/commands/uninstall.js +17 -9
  7. package/dist/commands/uninstall.js.map +1 -1
  8. package/dist/commands/update.d.ts.map +1 -1
  9. package/dist/commands/update.js +5 -5
  10. package/dist/commands/update.js.map +1 -1
  11. package/dist/index.js +4 -4
  12. package/dist/index.js.map +1 -1
  13. package/dist/utils/config.d.ts +5 -3
  14. package/dist/utils/config.d.ts.map +1 -1
  15. package/dist/utils/config.js +34 -12
  16. package/dist/utils/config.js.map +1 -1
  17. package/dist/utils/file.d.ts +8 -0
  18. package/dist/utils/file.d.ts.map +1 -1
  19. package/dist/utils/file.js +161 -9
  20. package/dist/utils/file.js.map +1 -1
  21. package/dist/utils/jq.d.ts.map +1 -1
  22. package/dist/utils/jq.js +8 -0
  23. package/dist/utils/jq.js.map +1 -1
  24. package/package.json +9 -5
  25. package/skill/SKILL.md +15 -169
  26. package/skill/VERSION +1 -1
  27. package/skill/references/integration/flow.md +388 -291
  28. package/skill/references/integration/modules/alipay-sdk-reminder.md +5 -3
  29. package/skill/references/integration/modules/checklist.md +54 -32
  30. package/skill/references/integration/modules/code-examples/csharp/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +199 -0
  31. package/skill/references/integration/modules/code-examples/csharp/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +8 -4
  32. package/skill/references/integration/modules/code-examples/csharp/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +6 -2
  33. package/skill/references/integration/modules/code-examples/csharp/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.cs +3 -1
  34. package/skill/references/integration/modules/code-examples/java/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +184 -0
  35. package/skill/references/integration/modules/code-examples/java/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +4 -1
  36. package/skill/references/integration/modules/code-examples/java/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +5 -2
  37. package/skill/references/integration/modules/code-examples/java/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemoController.java +3 -1
  38. package/skill/references/integration/modules/code-examples/nodejs/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +135 -0
  39. package/skill/references/integration/modules/code-examples/nodejs/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +16 -10
  40. package/skill/references/integration/modules/code-examples/nodejs/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +10 -4
  41. package/skill/references/integration/modules/code-examples/nodejs/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.js +2 -1
  42. package/skill/references/integration/modules/code-examples/php/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +157 -0
  43. package/skill/references/integration/modules/code-examples/php/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +4 -1
  44. package/skill/references/integration/modules/code-examples/php/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +5 -2
  45. package/skill/references/integration/modules/code-examples/php/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.php +2 -1
  46. package/skill/references/integration/modules/code-examples/python/1-/351/200/232/347/224/250/346/216/245/345/217/243//345/274/202/346/255/245/351/200/232/347/237/245/345/244/204/347/220/206/344/273/243/347/240/201/347/244/272/344/276/213.md +128 -0
  47. package/skill/references/integration/modules/code-examples/python/2-/347/275/221/347/253/231/346/224/257/344/273/230//347/273/237/344/270/200/346/224/266/345/215/225/344/270/213/345/215/225/345/271/266/346/224/257/344/273/230/351/241/265/351/235/242/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +4 -1
  48. package/skill/references/integration/modules/code-examples/python/3-APP/346/224/257/344/273/230/APP/346/224/257/344/273/230/346/216/245/345/217/243/344/273/243/347/240/201/347/244/272/344/276/213.md +5 -1
  49. package/skill/references/integration/modules/code-examples/python/4-/346/214/211/351/207/217/344/273/230/350/264/271/A2MPaymentDemo.py +4 -2
  50. package/skill/references/integration/modules/interface-contract/aipay-interface-contract.md +52 -0
  51. package/skill/references/integration/modules/interface-contract/apppay-interface-contract.md +45 -0
  52. package/skill/references/integration/modules/interface-contract/common-trade-contract.md +42 -0
  53. package/skill/references/integration/modules/interface-contract/notify-url-contract.md +68 -0
  54. package/skill/references/integration/modules/interface-contract/webpay-interface-contract.md +44 -0
  55. package/skill/references/integration/modules/interface-guide.md +38 -71
  56. package/skill/references/integration/modules/product-decision.md +18 -35
  57. package/skill/references/integration/modules/sandbox/a2m-sandbox-test.md +62 -94
  58. package/skill/references/integration/modules/sandbox/alipay-sandbox-tool.md +43 -40
  59. package/skill/references/integration/modules/sandbox/sandbox-setup-guide.md +93 -114
  60. package/skill/references/integration/modules/scripts/local_402_sandbox_pay.py +358 -148
  61. package/skill/references/integration/modules/scripts/sandbox_config.sh +299 -0
  62. package/skill/references/integration/modules/troubleshooting-flow.md +28 -0
  63. package/skill/references/normal/alipay-cli-env.md +15 -5
  64. package/skill/references/normal/full-process-routing.md +82 -0
  65. package/skill/references/normal/json/customer-messages.json +942 -0
  66. package/skill/references/normal/json/policy-rules.json +179 -0
  67. package/skill/references/normal/rejection-guide.md +12 -7
  68. package/skill/references/normal/scripts/alipay_cli_env.mjs +33 -0
  69. package/skill/references/normal/scripts/alipay_cli_env.sh +55 -0
  70. package/skill/references/normal/scripts/common.sh +151 -0
  71. package/skill/references/normal/scripts/detect_dev_tool.sh +5 -1
  72. package/skill/references/normal/scripts/flow_loader.mjs +241 -0
  73. package/skill/references/normal/scripts/integration_context_runner.mjs +166 -0
  74. package/skill/references/normal/scripts/integration_message_runner.mjs +1023 -0
  75. package/skill/references/normal/scripts/interaction_reply.mjs +133 -0
  76. package/skill/references/normal/scripts/onboarding_discovery_runner.mjs +224 -0
  77. package/skill/references/normal/scripts/onboarding_message_runner.mjs +451 -0
  78. package/skill/references/normal/scripts/onboarding_recovery_runner.mjs +96 -0
  79. package/skill/references/normal/scripts/open_official_url.sh +82 -0
  80. package/skill/references/normal/scripts/platform_compat.mjs +39 -0
  81. package/skill/references/normal/scripts/project_route_inspector.sh +132 -0
  82. package/skill/references/normal/scripts/python_script_runner.mjs +56 -0
  83. package/skill/references/normal/scripts/render_customer_message.mjs +1288 -0
  84. package/skill/references/normal/scripts/self_update.mjs +160 -0
  85. package/skill/references/normal/scripts/telemetry.mjs +1327 -0
  86. package/skill/references/normal/self-update.md +18 -51
  87. package/skill/references/normal/telemetry.md +26 -0
  88. package/skill/references/onboarding/flow.md +421 -309
  89. package/skill/references/onboarding/modules/app-release.md +44 -438
  90. package/skill/references/onboarding/modules/authorization.md +25 -281
  91. package/skill/references/onboarding/modules/error-handling.md +31 -237
  92. package/skill/references/onboarding/modules/product-sign.md +25 -294
  93. package/skill/references/onboarding/modules/scripts/app.sh +445 -169
  94. package/skill/references/onboarding/modules/scripts/ar_sign_apply.sh +47 -28
  95. package/skill/references/onboarding/modules/scripts/auth.sh +484 -167
  96. package/skill/references/onboarding/modules/scripts/download_key_tool.sh +157 -0
  97. package/skill/references/onboarding/modules/scripts/error_handler.sh +101 -130
  98. package/skill/references/onboarding/modules/scripts/network_retry.sh +96 -0
  99. package/skill/references/onboarding/modules/scripts/query_sign_status.sh +20 -71
  100. package/skill/references/onboarding/modules/scripts/service.sh +154 -89
  101. package/skill/references/onboarding/modules/scripts/sign_status_parser.sh +58 -0
  102. package/skill/references/onboarding/modules/scripts/upload_screenshots.sh +34 -20
  103. package/skill/references/onboarding/modules/service-registration.md +20 -317
  104. package/skill/references/runtime-entry.md +63 -0
@@ -0,0 +1,299 @@
1
+ #!/bin/bash
2
+
3
+ set -u
4
+
5
+ MODE="${1:-}"
6
+ PRODUCT_TYPE=""
7
+ PROJECT_PATH=""
8
+ LANGUAGE=""
9
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+ NORMAL_SCRIPTS="${SCRIPT_DIR}/../../../normal/scripts"
11
+ RENDERER="${NORMAL_SCRIPTS}/render_customer_message.mjs"
12
+ DETECTOR="${NORMAL_SCRIPTS}/detect_dev_tool.sh"
13
+ COMMON_SCRIPT="${NORMAL_SCRIPTS}/common.sh"
14
+
15
+ if [ -f "$COMMON_SCRIPT" ]; then
16
+ # shellcheck source=/dev/null
17
+ source "$COMMON_SCRIPT"
18
+ else
19
+ echo "SANDBOX_ERROR:缺少公共脚本 $COMMON_SCRIPT" >&2
20
+ exit 1
21
+ fi
22
+
23
+ case "$MODE" in
24
+ create|verify|ensure|reverify)
25
+ if [ "${2:-}" = "aipay" ] || [ "${2:-}" = "webpay" ] || [ "${2:-}" = "apppay" ]; then
26
+ echo "SANDBOX_ERROR:${MODE} 不接受 productType 参数;用法 sandbox_config.sh ${MODE} <projectPath> <language>" >&2
27
+ exit 2
28
+ fi
29
+ PROJECT_PATH="${2:-}"
30
+ LANGUAGE="${3:-}"
31
+ ;;
32
+ summary)
33
+ PRODUCT_TYPE="${2:-}"
34
+ PROJECT_PATH="${3:-}"
35
+ LANGUAGE="${4:-}"
36
+ ;;
37
+ *)
38
+ echo "SANDBOX_ERROR:用法 sandbox_config.sh <ensure|reverify|create|verify> <projectPath> <language> 或 sandbox_config.sh summary <productType> <projectPath> <language>" >&2
39
+ exit 2
40
+ ;;
41
+ esac
42
+
43
+ normalize_language() {
44
+ local value compact
45
+ value="${1:-}"
46
+ compact=$(printf '%s' "$value" | tr '[:upper:]' '[:lower:]' | sed 's/[ ._-]//g')
47
+ case "$compact" in
48
+ java) printf '%s\n' "Java" ;;
49
+ python|python3|py) printf '%s\n' "Python" ;;
50
+ nodejs|node|javascript|js) printf '%s\n' "Node.js" ;;
51
+ c#|csharp|dotnet|net) printf '%s\n' "C#" ;;
52
+ php) printf '%s\n' "PHP" ;;
53
+ *) return 1 ;;
54
+ esac
55
+ }
56
+
57
+ LANGUAGE="$(normalize_language "$LANGUAGE")" || {
58
+ echo "SANDBOX_ERROR:语言非法,仅支持 Java|Python|Node.js|C#|PHP;Node.js 请使用 Node.js 或 nodejs" >&2
59
+ exit 2
60
+ }
61
+
62
+ CONFIG_PATH="${PROJECT_PATH}/.alipay-sandbox.json"
63
+ GITIGNORE_PATH="${PROJECT_PATH}/.gitignore"
64
+
65
+ if [ "$MODE" = "summary" ]; then
66
+ case "$PRODUCT_TYPE" in aipay) PRODUCT_NAME="AI 按量付费" ;; webpay) PRODUCT_NAME="AI 网页应用收款" ;; apppay) PRODUCT_NAME="AI 移动应用收款" ;; *) echo "SANDBOX_ERROR:产品非法,仅支持 aipay|webpay|apppay" >&2; exit 2 ;; esac
67
+ fi
68
+ case "$PROJECT_PATH" in /*) ;; *) echo "SANDBOX_ERROR:项目路径必须为绝对路径" >&2; exit 2 ;; esac
69
+ [ -d "$PROJECT_PATH" ] && [ ! -L "$PROJECT_PATH" ] || { echo "SANDBOX_ERROR:项目目录不可访问或不安全" >&2; exit 2; }
70
+ detected=()
71
+ find "$PROJECT_PATH" -maxdepth 4 -type f \( -name pom.xml -o -name build.gradle -o -name build.gradle.kts \) -print -quit | grep -q . && detected+=(Java)
72
+ find "$PROJECT_PATH" -maxdepth 4 -type f -name package.json -print -quit | grep -q . && detected+=(Node.js)
73
+ find "$PROJECT_PATH" -maxdepth 4 -type f \( -name requirements.txt -o -name pyproject.toml \) -print -quit | grep -q . && detected+=(Python)
74
+ find "$PROJECT_PATH" -maxdepth 4 -type f -name '*.csproj' -print -quit | grep -q . && detected+=(C#)
75
+ find "$PROJECT_PATH" -maxdepth 4 -type f -name composer.json -print -quit | grep -q . && detected+=(PHP)
76
+ language_detected=false
77
+ for detected_language in "${detected[@]}"; do
78
+ [ "$detected_language" = "$LANGUAGE" ] && language_detected=true
79
+ done
80
+ [ "$language_detected" = true ] || { echo "SANDBOX_ERROR:未发现与已确认语言一致的项目构建标识" >&2; exit 2; }
81
+
82
+ if [ "$MODE" = "ensure" ] || [ "$MODE" = "reverify" ]; then
83
+ if [ "$MODE" = "reverify" ] || [ -e "$CONFIG_PATH" ] || [ -L "$CONFIG_PATH" ]; then
84
+ ENSURE_MODE="verify"
85
+ ENSURE_ACTION="VERIFIED"
86
+ PENDING_VARIANT="VERIFY"
87
+ PENDING_MARKER="FLOW:SANDBOX_CONFIG_PENDING_VERIFY"
88
+ else
89
+ ENSURE_MODE="create"
90
+ ENSURE_ACTION="CREATED"
91
+ PENDING_VARIANT="CREATE"
92
+ PENDING_MARKER="FLOW:SANDBOX_CONFIG_PENDING_CREATE"
93
+ fi
94
+
95
+ attempt=1
96
+ while true; do
97
+ ensure_output=$(bash "$0" "$ENSURE_MODE" "$PROJECT_PATH" "$LANGUAGE" 2>&1)
98
+ ensure_rc=$?
99
+ if [ "$ensure_rc" -eq 0 ] &&
100
+ [ "$(printf '%s\n' "$ensure_output" | grep -Fxc "ALIPAY_AIPAY_INTERNAL:SANDBOX_CONFIG_PATH=$CONFIG_PATH")" -eq 1 ] &&
101
+ [ "$(printf '%s\n' "$ensure_output" | grep -Fxc 'ALIPAY_AIPAY_INTERNAL:FLOW:SANDBOX_CONFIG_READY')" -eq 1 ] &&
102
+ ! printf '%s\n' "$ensure_output" | grep -q '^SANDBOX_ERROR:'; then
103
+ emit_control_field "SANDBOX_ENSURE_ACTION" "$ENSURE_ACTION" || exit 1
104
+ emit_control_field "SANDBOX_CONFIG_PATH" "$CONFIG_PATH" || exit 1
105
+ emit_control "FLOW:SANDBOX_CONFIG_READY"
106
+ exit 0
107
+ fi
108
+
109
+ if [ "$attempt" -lt 3 ] && printf '%s\n' "$ensure_output" | grep -qE \
110
+ 'SANDBOX_ERROR:(候选 data 缺少|配置缺少)当前语言或测试账号必含字段'; then
111
+ attempt=$((attempt + 1))
112
+ sleep 3
113
+ continue
114
+ fi
115
+ break
116
+ done
117
+
118
+ printf '%s' '{}' | node "$RENDERER" sandbox.configuration.pending --variant "$PENDING_VARIANT" || {
119
+ echo "SANDBOX_ERROR:沙箱待配置消息渲染失败" >&2
120
+ exit 1
121
+ }
122
+ emit_control_field "SANDBOX_PENDING_PATH" "$CONFIG_PATH" || exit 1
123
+ emit_control "$PENDING_MARKER"
124
+ exit 0
125
+ fi
126
+
127
+ extract_json_payload() {
128
+ local raw="$1" line_count span start end candidate normalized selected="" match_count=0
129
+ if normalized=$(printf '%s' "$raw" | jq -sce 'if length == 1 and (.[0] | type == "object") then .[0] else empty end' 2>/dev/null); then
130
+ printf '%s' "$normalized"
131
+ return 0
132
+ fi
133
+
134
+ line_count=$(printf '%s\n' "$raw" | awk 'END { print NR }')
135
+ span="$line_count"
136
+ while [ "$span" -ge 1 ]; do
137
+ start=1
138
+ while [ $((start + span - 1)) -le "$line_count" ]; do
139
+ end=$((start + span - 1))
140
+ candidate=$(printf '%s\n' "$raw" | sed -n "${start},${end}p")
141
+ if normalized=$(printf '%s' "$candidate" | jq -sce 'if length == 1 and (.[0] | type == "object") then .[0] else empty end' 2>/dev/null) &&
142
+ printf '%s' "$normalized" | jq -e 'has("success") or ((.result.content[0].text? // .content[0].text?) | type == "string")' >/dev/null 2>&1; then
143
+ if [ "$normalized" != "$selected" ]; then
144
+ selected="$normalized"
145
+ match_count=$((match_count + 1))
146
+ fi
147
+ fi
148
+ start=$((start + 1))
149
+ done
150
+ span=$((span - 1))
151
+ done
152
+ [ "$match_count" -eq 1 ] || return 1
153
+ printf '%s' "$selected"
154
+ }
155
+
156
+ ensure_gitignore_protection() {
157
+ if [ -L "$GITIGNORE_PATH" ] || { [ -e "$GITIGNORE_PATH" ] && [ ! -f "$GITIGNORE_PATH" ]; }; then
158
+ echo "SANDBOX_ERROR:.gitignore 不是安全的普通文件" >&2
159
+ return 1
160
+ fi
161
+ if [ -f "$GITIGNORE_PATH" ] && grep -Fxq '/.alipay-sandbox.json' "$GITIGNORE_PATH"; then
162
+ return 0
163
+ fi
164
+ if [ -s "$GITIGNORE_PATH" ] && [ -n "$(tail -c 1 "$GITIGNORE_PATH" 2>/dev/null)" ]; then
165
+ printf '\n' >>"$GITIGNORE_PATH" || return 1
166
+ fi
167
+ printf '/.alipay-sandbox.json\n' >>"$GITIGNORE_PATH" || return 1
168
+ }
169
+
170
+ ensure_config_not_tracked() {
171
+ command -v git >/dev/null 2>&1 || return 0
172
+ git -C "$PROJECT_PATH" rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
173
+ if git -C "$PROJECT_PATH" ls-files --error-unmatch -- '.alipay-sandbox.json' >/dev/null 2>&1; then
174
+ return 1
175
+ fi
176
+ return 0
177
+ }
178
+
179
+ ensure_config_permissions() {
180
+ local mode
181
+ chmod 600 "$CONFIG_PATH" 2>/dev/null || return 1
182
+ if mode=$(stat -f '%Lp' "$CONFIG_PATH" 2>/dev/null); then
183
+ :
184
+ elif mode=$(stat -c '%a' "$CONFIG_PATH" 2>/dev/null); then
185
+ :
186
+ else
187
+ return 1
188
+ fi
189
+ [ "$mode" = "600" ]
190
+ }
191
+
192
+ validate_data() {
193
+ local data="$1"
194
+ echo "$data" | jq -e --arg language "$LANGUAGE" '
195
+ (.appIds|type)=="array" and (.appIds|length)>0 and .appIds[0] as $app |
196
+ ($app.appId|type)=="string" and ($app.appId|length)>0 and
197
+ ($app.alipayPublicKey|type)=="string" and ($app.alipayPublicKey|length)>0 and
198
+ ($app.appPublicKey|type)=="string" and ($app.appPublicKey|length)>0 and
199
+ (if $language=="Java" then ($app.appPrivateKey|type)=="string" and ($app.appPrivateKey|length)>0
200
+ else ($app.appPrivatePkcsKey|type)=="string" and ($app.appPrivatePkcsKey|length)>0 end) and
201
+ (.sandboxAccounts.partner.userId|type)=="string" and (.sandboxAccounts.partner.userId|length)>0 and
202
+ (.sandboxAccounts.user.userId|type)=="string" and (.sandboxAccounts.user.userId|length)>0 and
203
+ (.sandboxAccounts.user.email|type)=="string" and (.sandboxAccounts.user.email|length)>0 and
204
+ (.sandboxAccounts.user.logonPassword|type)=="string" and (.sandboxAccounts.user.logonPassword|length)>0 and
205
+ (.sandboxAccounts.user.payPassword|type)=="string" and (.sandboxAccounts.user.payPassword|length)>0
206
+ ' >/dev/null 2>&1
207
+ }
208
+
209
+ render_summary() {
210
+ local data="$1" rows input
211
+ rows=$(echo "$data" | jq -r '
212
+ def safe: tostring|gsub("[|\\r\\n]";" ");
213
+ .appIds[0] as $app |
214
+ ["| 应用 | appId="+($app.appId|safe)+", pid="+(($app.pid//"未返回")|safe)+" |",
215
+ "| 商家账号 | userId="+(.sandboxAccounts.partner.userId|safe)+" |",
216
+ "| 买家账号 | userId="+(.sandboxAccounts.user.userId|safe)+", 登录账号="+(.sandboxAccounts.user.email|safe)+", 登录密码="+(.sandboxAccounts.user.logonPassword|safe)+", 支付密码="+(.sandboxAccounts.user.payPassword|safe)+" |",
217
+ "| 沙箱 | sandboxId="+((.sandboxId//"未返回")|safe)+" |"] | join("\n")
218
+ ') || return 1
219
+ input=$(jq -cn --arg productName "$PRODUCT_NAME" --arg configPath "$CONFIG_PATH" --arg environmentRows "$rows" '{productName:$productName,configPath:$configPath,environmentRows:$environmentRows}') || return 1
220
+ printf '%s' "$input" | node "$RENDERER" sandbox.environment.summary --variant DEFAULT || return 1
221
+ printf '%s' '{}' | node "$RENDERER" sandbox.environment.reminder --variant DEFAULT || return 1
222
+ }
223
+
224
+ if [ "$MODE" = "create" ]; then
225
+ command -v alipay-cli >/dev/null 2>&1 || { echo "SANDBOX_ERROR:缺少 alipay-cli" >&2; exit 1; }
226
+ { [ ! -e "$CONFIG_PATH" ] && [ ! -L "$CONFIG_PATH" ]; } || { echo "SANDBOX_ERROR:配置文件已存在或为不安全符号链接,禁止重复创建或覆盖" >&2; exit 1; }
227
+ ensure_config_not_tracked || { echo "SANDBOX_ERROR:沙箱配置路径已被 Git 跟踪,必须先从版本控制中移除" >&2; exit 1; }
228
+ ensure_gitignore_protection || { echo "SANDBOX_ERROR:无法为沙箱配置建立 Git 忽略保护" >&2; exit 1; }
229
+ PLATFORM=$(bash "$DETECTOR") || PLATFORM="unknown"
230
+ init_platform_id
231
+ attempt=1
232
+ while true; do
233
+ raw=$(env -u PRODUCT PLATFORM="$PLATFORM" PLATFORM_ID="${PLATFORM_ID:-}" alipay-cli mcp call alipay-anonymous-sandbox.createAnonymousSandbox --data '{"request":{"appType":"PUBLICAPP"}}' --json 2>&1)
234
+ rc=$?
235
+ [ "$rc" -eq 0 ] && break
236
+ if printf '%s' "$raw" | grep -qiE '版本过旧|version.*old'; then break; fi
237
+ if [ "$attempt" -lt 3 ] && printf '%s' "$raw" | grep -qiE 'MCP_SERVICE_ERROR|SERVICE_UNSTABLE|timeout|timed out|connection|network|ECONN|socket|temporar'; then
238
+ attempt=$((attempt + 1))
239
+ sleep 3
240
+ continue
241
+ fi
242
+ break
243
+ done
244
+ [ "$rc" -eq 0 ] || { echo "SANDBOX_ERROR:快速沙箱 CLI 调用失败" >&2; exit 1; }
245
+ outer=$(extract_json_payload "$raw") || { echo "SANDBOX_ERROR:CLI 输出中未找到唯一合法 JSON 对象" >&2; exit 1; }
246
+ text=$(echo "$outer" | jq -r '.result.content[0].text // .content[0].text // empty')
247
+ if [ -n "$text" ]; then
248
+ business=$(printf '%s' "$text" | jq -c . 2>/dev/null) || { echo "SANDBOX_ERROR:content[0].text 不是合法 JSON" >&2; exit 1; }
249
+ else
250
+ business="$outer"
251
+ fi
252
+ if [ "$(echo "$business" | jq -r '.success // false')" != "true" ] && echo "$business" | jq -r '.msg // .resultMsg // ""' | grep -q '证书密钥'; then
253
+ sleep 2
254
+ raw=$(env -u PRODUCT PLATFORM="$PLATFORM" PLATFORM_ID="${PLATFORM_ID:-}" alipay-cli mcp call alipay-anonymous-sandbox.createAnonymousSandbox --data '{"request":{"appType":"PUBLICAPP"}}' --json 2>&1)
255
+ rc=$?
256
+ [ "$rc" -eq 0 ] || { echo "SANDBOX_ERROR:证书密钥临时错误重试后 CLI 调用失败" >&2; exit 1; }
257
+ outer=$(extract_json_payload "$raw") || { echo "SANDBOX_ERROR:重试输出中未找到唯一合法 JSON 对象" >&2; exit 1; }
258
+ text=$(echo "$outer" | jq -r '.result.content[0].text // .content[0].text // empty')
259
+ if [ -n "$text" ]; then business=$(printf '%s' "$text" | jq -c . 2>/dev/null) || { echo "SANDBOX_ERROR:重试 content[0].text 非法" >&2; exit 1; }; else business="$outer"; fi
260
+ fi
261
+ [ "$(echo "$business" | jq -r '.success // false')" = "true" ] || {
262
+ echo "$business" | jq -r '"SANDBOX_ERROR:"+(.errorCode//"UNKNOWN"|tostring)+" "+(.msg//.resultMsg//"快速沙箱创建失败")+" traceId="+(.traceId//"未返回"|tostring)' >&2
263
+ exit 1
264
+ }
265
+ data=$(echo "$business" | jq -c '.data // null') || exit 1
266
+ validate_data "$data" || { echo "SANDBOX_ERROR:候选 data 缺少当前语言或测试账号必含字段" >&2; exit 1; }
267
+ temp=$(mktemp "${PROJECT_PATH}/.alipay-sandbox.XXXXXX") || exit 1
268
+ chmod 600 "$temp" 2>/dev/null || true
269
+ printf '%s\n' "$data" >"$temp" || { rm -f "$temp"; exit 1; }
270
+ mv "$temp" "$CONFIG_PATH" || { rm -f "$temp"; exit 1; }
271
+ ensure_config_permissions || { echo "SANDBOX_ERROR:无法确认配置权限为 0600" >&2; exit 1; }
272
+ elif [ "$MODE" = "verify" ]; then
273
+ [ -f "$CONFIG_PATH" ] && [ ! -L "$CONFIG_PATH" ] || { echo "SANDBOX_ERROR:配置文件不存在或不安全" >&2; exit 1; }
274
+ ensure_config_not_tracked || { echo "SANDBOX_ERROR:沙箱配置已被 Git 跟踪,必须先从版本控制中移除" >&2; exit 1; }
275
+ ensure_gitignore_protection || { echo "SANDBOX_ERROR:无法为沙箱配置建立 Git 忽略保护" >&2; exit 1; }
276
+ data=$(jq -c . "$CONFIG_PATH" 2>/dev/null) || { echo "SANDBOX_ERROR:配置不是合法 JSON" >&2; exit 1; }
277
+ validate_data "$data" || { echo "SANDBOX_ERROR:配置缺少当前语言或测试账号必含字段" >&2; exit 1; }
278
+ ensure_config_permissions || { echo "SANDBOX_ERROR:无法确认配置权限为 0600" >&2; exit 1; }
279
+ elif [ "$MODE" = "summary" ]; then
280
+ [ -f "$CONFIG_PATH" ] && [ ! -L "$CONFIG_PATH" ] || { echo "SANDBOX_ERROR:配置文件不存在或不安全" >&2; exit 1; }
281
+ ensure_config_not_tracked || { echo "SANDBOX_ERROR:沙箱配置已被 Git 跟踪,必须先从版本控制中移除" >&2; exit 1; }
282
+ ensure_gitignore_protection || { echo "SANDBOX_ERROR:无法为沙箱配置建立 Git 忽略保护" >&2; exit 1; }
283
+ data=$(jq -c . "$CONFIG_PATH" 2>/dev/null) || { echo "SANDBOX_ERROR:配置不是合法 JSON" >&2; exit 1; }
284
+ validate_data "$data" || { echo "SANDBOX_ERROR:配置缺少当前语言或测试账号必含字段" >&2; exit 1; }
285
+ ensure_config_permissions || { echo "SANDBOX_ERROR:无法确认配置权限为 0600" >&2; exit 1; }
286
+ else
287
+ echo "SANDBOX_ERROR:用法 sandbox_config.sh <ensure|reverify|create|verify> <projectPath> <language> 或 sandbox_config.sh summary <productType> <projectPath> <language>" >&2
288
+ exit 2
289
+ fi
290
+
291
+ if [ "$MODE" = "summary" ]; then
292
+ render_summary "$data" || exit 1
293
+ emit_control_field "SANDBOX_CONFIG_PATH" "$CONFIG_PATH" || exit 1
294
+ emit_control "FLOW:SANDBOX_CONFIGURED"
295
+ exit 0
296
+ fi
297
+
298
+ emit_control_field "SANDBOX_CONFIG_PATH" "$CONFIG_PATH" || exit 1
299
+ emit_control "FLOW:SANDBOX_CONFIG_READY"
@@ -0,0 +1,28 @@
1
+ # 支付集成问题排查
2
+
3
+ 仅在用户报告集成报错、错误码、问题、排查、调试或异常时读取。先确认当前支付产品;错误码查询还必须确认报错接口,缺少时暂停排查并请用户补充。
4
+
5
+ ## 分流
6
+
7
+ 1. `invalid-signature` 或验签失败:优先进入验签专项。
8
+ 2. 有明确错误码:先查[公共错误码说明](https://ideservice.alipay.com/cms/site/02km9f),无匹配时再按已确认产品和接口查业务接口文档。
9
+ 3. 无明确错误码:查当前产品常见问题文档。
10
+
11
+ | 产品 | 常见问题文档 |
12
+ |---|---|
13
+ | AI 按量付费 | [AI 按量付费常见问题](https://ideservice.alipay.com/cms/site/0j7uos) |
14
+ | AI 网页应用收款 | [AI 网页应用收款常见问题](https://ideservice.alipay.com/cms/site/0j3kh1) |
15
+ | AI 移动应用收款 | [AI 移动应用收款常见问题](https://ideservice.alipay.com/cms/site/0j3pih) |
16
+
17
+ 没有确定依据时明确说明无法确认,禁止编造;引导用户查阅[支付宝开放平台](https://open.alipay.com?form=payskill)或咨询[支付宝技术支持](https://opensupport.alipay.com/support/intelligent-services?form=payskill)。
18
+
19
+ ## 验签失败专项
20
+
21
+ 严禁在没有实际请求证据时把 `invalid-signature`、`ERR_OSSL_UNSUPPORTED` 或验签失败归因于私钥格式,也不得添加 PEM 头尾或擅自转换密钥。按以下顺序核对:
22
+
23
+ 1. 实际发送、参与签名和服务端验签的参数集是否完全一致。
24
+ 2. 私钥字段是否正确:Java 使用 `appPrivateKey`,其他语言使用 `appPrivatePkcsKey`。
25
+ 3. `signType` 是否为 `RSA2`。
26
+ 4. 网关地址是否与当前环境一致。
27
+
28
+ 线上环境确认公私钥不匹配时,建议用户登录支付宝开放平台重新上传应用公钥,并在应用配置中重新配置应用公私钥对。更完整原则见 `alipay-sdk-reminder.md` 的验签失败排查章节。
@@ -42,11 +42,12 @@ fi
42
42
  **执行要求:**
43
43
  - 对已知需要联网的命令,如果当前 Agent 环境网络受限且支持显式授权,应首次执行即申请可联网权限,不要先在受限沙箱内试跑。
44
44
  - 若命令已经因网络失败,重试时必须复用同一条命令并申请可联网权限;不要把该失败解释为用户网络故障。
45
+ - `auth.sh init|confirm|mismatch` 返回 `AUTH_FLOW:RETRY_WITH_NETWORK` 时,表示当前 Agent 执行环境没有取得可确认 CLI 结果;必须申请联网权限后重试同一条完整脚本命令,不得解释为支付宝业务失败、logout 失败或 login 失败,也不得要求用户手动 logout/login 代替本轮脚本事实。
45
46
  - 本地纯解析、文件检查、`bash -n`、`jq` 校验等不联网命令仍可在默认沙箱内执行。
46
47
 
47
48
  **减少重复授权:**
48
- - 优先执行 Skill 内置脚本,例如 `bash modules/scripts/auth.sh ...`、`bash modules/scripts/app.sh ...`、`bash modules/scripts/service.sh ...`,不要把每次 `alipay-cli mcp call` 都展开成新的长命令。
49
- - 在支持前缀持久授权的工具中,申请可联网权限时使用稳定命令前缀作为授权范围,例如 `bash modules/scripts/auth.sh` 或 `bash modules/scripts/app.sh`。同一脚本后续不同参数更容易复用授权。
49
+ - 优先执行 Skill 内置脚本;从本文件所在的 `references/normal/` 目录调用 onboarding 脚本时,使用 `bash ../onboarding/modules/scripts/auth.sh ...`、`bash ../onboarding/modules/scripts/app.sh ...`、`bash ../onboarding/modules/scripts/service.sh ...`,不要把每次 `alipay-cli mcp call` 都展开成新的长命令。
50
+ - 在支持前缀持久授权的工具中,申请可联网权限时使用当前实际脚本绝对路径对应的稳定命令前缀作为授权范围。同一脚本后续不同参数更容易复用授权;不得为了复用授权改调另一份 Skill 副本。
50
51
  - 避免用 `DEV_TOOL_NAME=<tool> bash ...`、`PLATFORM=<tool> alipay-cli ...` 作为常规调用形态;这类环境变量前缀会让授权规则更难复用。签约脚本会通过公共初始化设置 `DEV_TOOL_NAME`,直接执行脚本即可。
51
52
  - 产品上下文优先通过脚本参数传入,例如 `--sales-code`、`--mcc-code`、`--product-type`;不要用 `PRODUCT_TYPE=... SALES_CODE=... bash ...` 作为常规调用形态。
52
53
  - 只有脚本未覆盖的临时排查命令,才直接调用 `alipay-cli`;这类命令需要按具体前缀单独授权。
@@ -87,7 +88,7 @@ which gpg 2>/dev/null
87
88
  >
88
89
  > 不要额外设置 `HOMEBREW_API_DOMAIN`;formula 索引保持使用 Homebrew 默认 API,避免镜像索引不完整导致安装失败。
89
90
 
90
- 签约脚本需要 jq 解析 JSON,先检查:
91
+ 签约脚本和 Unix/macOS/Linux 快速沙箱脚本需要 jq 解析 JSON,先检查:
91
92
  ```bash
92
93
  jq --version
93
94
  ```
@@ -117,6 +118,8 @@ jq --version
117
118
  >
118
119
  > 不要额外设置 `HOMEBREW_API_DOMAIN`;formula 索引保持使用 Homebrew 默认 API,避免镜像索引不完整导致安装失败。
119
120
 
121
+ Windows Integration 代码开发路径通过 Node runner 完成项目解析、项目扫描和标准消息渲染,只要求当前 Node 运行时,不把 Bash、jq 或该路径不会调用的 alipay-cli 作为 Step 1 阻断项;进入产品开通或执行既有 shell/CLI 脚本时仍按对应 flow 补齐依赖。Unix/macOS/Linux 和 Onboarding 的既有检查边界不变。
122
+
120
123
  ---
121
124
 
122
125
  ## 4. CLI 安装
@@ -163,15 +166,22 @@ source ~/.bashrc # Linux/bash
163
166
 
164
167
  > ⚠️ **强制规范:检测结果仅供内部使用,禁止向用户输出!**
165
168
 
166
- AI 编程工具检测使用通用脚本 `scripts/detect_dev_tool.sh`。shell 脚本通过 `scripts/common.sh` 提供的 `init_dev_tool_name` 初始化 `DEV_TOOL_NAME`,再用于设置 `PLATFORM` 上下文;文档示例或非 shell 流程可直接参考 `detect_dev_tool.sh` 的输出。
169
+ AI 编程工具检测使用通用脚本 `scripts/detect_dev_tool.sh`。shell 脚本通过 `scripts/common.sh` 提供的 `init_alipay_cli_context` 初始化 `DEV_TOOL_NAME`、`PLATFORM` 和 `PLATFORM_ID`;其中 `PLATFORM_ID` 取当前 telemetry `run_id`,用于把同一流程的 Skill 时间戳事件和 alipay-cli 上报关联起来。Onboarding 在产品确认后还通过同一公共脚本把 `aipay|webpay|apppay` 严格映射为 CLI 环境变量 `PRODUCT=AIPAY|WEBPAY|APPPAY`,所有环境检查、登录、查询、写入和文件上传调用都必须携带当前值;该字段不进入 MCP 请求 JSON。Integration 的产品确定前环境检查和快速沙箱仍不传 `PRODUCT`。若宿主环境提供 `COZE_PROJECT_ID`、`MEOO_PROJECT_ID`,或 `MIAODA` 环境下的 `VITE_APP_ID`/`PLATFORM_ID`,telemetry 新建 run 时直接使用该项目 ID 作为 `run_id`,脚本也会将同一值作为 `PLATFORM_ID`。文档示例或非 shell 流程可直接参考 `detect_dev_tool.sh` 的输出。
167
170
 
168
171
  ```
169
172
  ❌ 禁止:向用户输出"环境检查完成,检测到您正在使用 Claude Code 环境"等检测结果
170
173
  ❌ 禁止:向用户透出任何关于 AI 编程工具检测的信息
171
- ✅ 正确:检测结果仅供内部使用,只用于设置 PLATFORM 环境变量
174
+ ✅ 正确:检测结果仅供内部使用,只用于脚本设置 `PLATFORM`;`PLATFORM_ID` 由脚本从当前 `run_id` 派生,Onboarding 的 `PRODUCT` 由已确认产品映射
172
175
  ✅ 正确:静默完成检测,直接进入下一步流程
173
176
  ```
174
177
 
178
+ ### 5.1 页面打开与下载能力降级
179
+
180
+ - 授权页或公钥确认页由 `scripts/open_official_url.sh` 在精确 HTTPS 主机、路径、查询参数和当前上下文校验通过后默认调用 macOS `open`、Linux `xdg-open` 或可用的 Windows PowerShell;只返回 `OPENED` / `OPEN_FAILED` / `GUI_UNAVAILABLE` / `LINK_ONLY`,不输出临时 URL。Skill 不另询问是否打开。
181
+ - 宿主缺少 GUI、opener 不存在或当前权限不允许打开时,不安装桌面工具、不绕过宿主审批,直接由标准消息保留同一裸 URL 和复制访问兜底。
182
+ - 目标应用缺少用户已准备的应用公钥时,macOS/Windows 直接执行 onboarding 的 `download_key_tool.sh`,默认保存到用户 `Downloads` 目录并展示实际安装包路径;Linux、缺少 `curl`/`node`、目录不可用、下载源不可达或下载校验失败均回退 `https://opendocs.alipay.com/isv/02kipk`。脚本 stdout 直接输出标准对客文案,不输出 `DOWNLOADED`、`PATH=`、`DOWNLOAD_FAILED` 或 `DOWNLOAD_REASON` 机器标记。下载不安装、不启动、不生成密钥,Skill 不另询问是否下载。
183
+ - 页面打开和下载能力检测不改变 alipay-cli、MCP、业务确认或网络重试契约;宿主权限提示不是 Skill 业务确认。
184
+
175
185
  ---
176
186
 
177
187
  ## 6. 检测与安装流程图
@@ -0,0 +1,82 @@
1
+ # 完整接入编排
2
+
3
+ 本文件是 `full_process` 唯一入口。启动确认前只复用 Integration 步骤 1 的项目、语言、当前系统分支环境和沙箱准备;不得开发代码、进入 Onboarding 或读取开通信息。
4
+
5
+ 目标项目和技术栈可确定后,从本文件目录执行 `node scripts/flow_loader.mjs integration entry`,只加载 Integration 当前入口阶段并按其步骤 1/2 准备和确认;禁止整份读取 `../integration/flow.md`。loader bundle 中的命令仍以源文件目录 `references/integration/` 为 workdir。代码开发满足衔接条件后执行 `node scripts/flow_loader.mjs onboarding entry`,其 bundle 命令以 `references/onboarding/` 为 workdir;禁止整份读取 `../onboarding/flow.md`。
6
+
7
+ 本文 Skill 命令以 `references/normal/` 为 workdir。项目选择时的 `PROJECT_INPUT` 保留用户原始表达;明确“新建/创建”项目、网站、商城、应用或同类新产物时固定使用 `--intent new`,不得因当前目录已有项目改写为 `--intent existing`。新建项目使用空路径或 runner 安全默认目录;复用项目须选定具体项目根,未知位置先定位候选。“当前目录”仅在 runner 识别为项目根时接受。扫描和后续脚本只使用解析后的规范化绝对路径。
8
+
9
+ ## 边界
10
+
11
+ - 只编排 Integration 与 Onboarding,不复制其状态、完成条件和红线。完整接入复用 Integration 步骤 2 的唯一 `integration.start.confirm`、同一检查器事实和模板,本轮只渲染一次。
12
+ - 先确定项目、语言和创建方式。`NEW_PROJECT` 空路径检查后初始化最小骨架,再执行 Integration 步骤 1;沙箱不依赖产品、不传 `PRODUCT`、不展示摘要,待配置仍继续。确认前禁止读取/展示 MCC、授权范围和开通材料/待办。
13
+ - 项目事实只来自 runner 与实际文件。未知位置用 `locate-projects --search-input "$SEARCH_INPUT" --format message` 查标记并等待选择;不得扫描上层大目录。完整性仍以 Integration 全部适用项和 checklist 为准。
14
+
15
+ ## 新项目准备与路由分类
16
+
17
+ 项目来源互斥:`CURRENT_PROJECT` 为当前目录内项目根,`OTHER_PROJECT` 为用户以绝对路径提供的目录外项目;未选定/不可访问/不可识别则为 `PROJECT_UNRESOLVED`,禁止凭描述生成状态。
18
+
19
+ `NEW_PROJECT` 只用于初始化前:
20
+
21
+ ```bash
22
+ node scripts/integration_message_runner.mjs resolve-project --project-input "$PROJECT_INPUT" --base-path "$USER_WORKSPACE_ROOT" --intent new
23
+ ```
24
+
25
+ 未指定位置时使用用户目录下 `alipay-aipay-projects/pay-demo`,非空占用则加安全后缀。只有 `preparationStatus=READY` 才初始化;其他结果不得清空/覆盖。初始化且沙箱终态确定后单向成为当前会话的 `PREPARED_NEW_PROJECT`;不持久化,重入重扫。`NEW_PROJECT` 不扫描代码,`PREPARED_NEW_PROJECT` 不恢复为空目录状态。
26
+
27
+ ### 固定检查器与 runner 终态协议
28
+
29
+ - `resolve-project --intent new` 只接受退出码 0、唯一 JSON、规范化绝对 `projectPath`、`projectSelection/projectOrigin=NEW_PROJECT`、`projectOriginLabel=本轮新建项目` 和 `preparationStatus=READY`;否则保持 `PROJECT_UNRESOLVED`。
30
+ - `resolve-project --intent existing` 只接受退出码 0、唯一 JSON、规范化绝对路径、`CURRENT_PROJECT|OTHER_PROJECT` 和 `EXISTING_PROJECT/现有项目`。相对路径限 `--base-path` 内,目录外由用户提供绝对路径;失败不得以描述/cwd 代替。
31
+ - `locate-projects` 用于未知位置/多候选,缺省搜索词为 `当前目录`。stdout 是唯一候选消息;选择后仍执行 `resolve-project --intent existing`。
32
+ - `start-confirm` 内部只执行一次项目扫描,校验后将同一对象交给 renderer;失败为 `STATUS_UNKNOWN`。禁止改写命令、另跑扫描、抽取代码,或追加 `find`、`ls`、`stat`、额外 `jq` 和临时脚本复核同一结果。
33
+
34
+ ## 维度二:目标产品集成状态
35
+
36
+ 项目和沙箱取得确定终态后再确定产品并扫描合法项目分类。已有描述能唯一映射时直接复用;否则只执行下列消息并等待,仍不唯一时重复同一消息。目标产品明确前不得执行 `scan`。
37
+
38
+ ```bash
39
+ node scripts/integration_message_runner.mjs product-clarify
40
+ ```
41
+
42
+ - `TARGET_PARTIAL`:发现目标代码/配置,仍完整验证;并存时优先。
43
+ - `OTHER_PRODUCT_ONLY`:仅有其他产品,保留。
44
+ - `NO_PAYMENT`:无支付能力。
45
+ - `STATUS_UNKNOWN`:不可访问、证据冲突/不足或产品不明,停止。
46
+
47
+ 合法项目分类与前三种代码状态确认后进入 Integration;`PROJECT_UNRESOLVED/STATUS_UNKNOWN` 继续澄清。Unix/macOS/Linux 的 `CREATE_PENDING|VERIFY_PENDING` 和 Windows 的 `VERIFY_PENDING` 都不阻止扫描/开发。新项目保留 `projectOriginLabel=本轮新建项目`;已有项目“新建”只能新增能力或使用空路径。这些分类只用于本轮分流,不持久化。
48
+
49
+ ## 完整接入启动确认
50
+
51
+ 合法项目分类、前三种代码状态、产品、语言和框架全部确定后才能发起 `integration.start.confirm`。缺项目/技术栈时执行下列 `integration.context.required`;只缺新项目位置用 `integration.project_path.required`。禁止使用 AskUserQuestion、request_user_input、宿主超时默认值、Agent 自创选项或自由话术替代;不得先输出扫描摘要或方案。
52
+
53
+ ```bash
54
+ node scripts/integration_message_runner.mjs context-required --missing-items "$MISSING_ITEMS"
55
+ ```
56
+
57
+ `MISSING_ITEMS` 只由 `项目路径`、`技术栈` 组成;产品不明确仍用 `product.clarify`。stdout 原文发出后等待,未补齐前不得初始化、安装或修改。路径输入均先 `resolve-project`;未知位置或需候选时执行:
58
+
59
+ ```bash
60
+ node scripts/integration_message_runner.mjs locate-projects --base-path "$USER_WORKSPACE_ROOT" --search-input "$SEARCH_INPUT" --format message
61
+ ```
62
+
63
+ 字段齐备后执行唯一 runner;禁止拆开执行项目扫描、`jq` 或 `render_customer_message.mjs`,也不得附加解析。runner stdout 是本动作唯一对客消息,必须把 stdout 原文作为当前回复正文发给用户;发出 stdout 原文后立即停止本轮并等待当前摘要的明确肯定回复。收到回复后执行 `node scripts/interaction_reply.mjs confirm --reply "$USER_REPLY"`,只有唯一 `REPLY_DECISION=CONFIRMED` 才推进;摘要变化后旧回复失效。该内部判定不新增用户操作点;静态扫描只决定进入验证,不证明完成。
64
+
65
+ ```bash
66
+ node scripts/integration_message_runner.mjs start-confirm --product-type "$PRODUCT_TYPE" --product-name "$PRODUCT_NAME" --project-path "$PROJECT_PATH" --project-selection "$PROJECT_SELECTION" --language "$SERVER_LANGUAGE" --framework "$FRAMEWORK"
67
+ ```
68
+
69
+ 上面命令失败时不得展示手写确认或进入子流程。成功时必须同时保存唯一 `ALIPAY_AIPAY_INTERNAL:PROJECT_CONFIRM_RECEIPT=<receipt>`;缺失、重复或不可解析视为失败。参数必须是当前确定值,禁止直接拼用户输入。runner 校验产品 variant 并固定服务声明;实际范围仍取当前 Integration flow 和 checklist。
70
+
71
+ 分流、展示和交接事实必须来自 runner 内同一次 `scan` 对象;禁止用描述、Agent 自报或历史分类代替。`evidence` 仅内部校验,不进 renderer;Onboarding Step 1 前禁止传/猜 `mccCode`。确认同时满足 `INT.START.CONFIRMED` 与 `INT.SERVICE_STATEMENT.CONFIRMED` 后,执行 `node scripts/flow_loader.mjs integration development --product-type "$PRODUCT_TYPE" --project-confirm-receipt "$PROJECT_CONFIRM_RECEIPT"`。只有内部 `PROJECT_CONFIRMATION=VALID` 才进入步骤 3;`STALE` 时 loader stdout 已重新渲染当前标准确认,必须原文发送并等待新的明确肯定回复。loader 自动记录确认和预开发阅读 stage,禁止手工执行 telemetry;确认有效时禁止再次渲染 `integration.start.confirm`。
72
+
73
+ 合法组合必须确认产品、路径/来源、代码状态、语言/框架、服务声明和顺序;发现其他产品时确认保留。当前完整摘要展示前的零散信息、`新建` 选择、未选候选或新项目未准备均不能替代;当前完整摘要展示后的 `继续` 属于有效肯定回复。确认后仍完整执行 Integration 和 checklist。
74
+
75
+ ## 子流程衔接规则
76
+
77
+ - 启动确认后直接进入 Integration 步骤 3;项目、产品、语言或框架变化使确认失效,重新扫描并确认。
78
+ - Integration 先完整执行和校验。只有沙箱待配置,或 READY 且仅剩非阻塞人工待验证项时,保持“部分通过”进入 Onboarding;其他代码、安全或依据缺口停在 Integration,不提前登录或收集开通材料。
79
+ - 阶段间只复用有效的产品、项目、代码产物和 CLI 检查,不再询问是否进入 Onboarding;保留方案确认。
80
+ - 授权后分别查询签约、应用和适用服务;分支独立,单分支失败不回滚其他成功,认证/授权不匹配或主体变化全局阻断。一次只收集一个类别,提前材料直接校验且不重复索取。
81
+ - 签约材料通过后直接提交;服务创建摘要后直接创建,修改仍确认;当前候选列表选择“新建”且重查未变化后直接创建,用户公钥直接生成官方确认页,校验成功后直接提审。均不增加额外确认点;按量付费沙箱测试仍属 Integration 默认动作。
82
+ - 当前终点汇总代码、沙箱、签约、服务、应用和待办;人工待验证项带入 Onboarding Step 6,不增加确认。有待生效/审核/验证或配置缺口时不得宣称生产就绪。