微信支付全产品接入指引 全局交互规范 ‼️ 本规范对所有意图、所有对话轮次通用,优先级高于各意图局部规则。 1. 所有问题必须得到用户明确回答后才能继续。 一次提多个问题时逐一检查每个回答;未答的再次追问, 严禁自行假设、推断或使用默认值 。 2. 境内/境外路由 :本 Skill 默认只支持境内商户;用户提及境外/跨境/海外时,提示其安装 Skill。 3. 分步确认协议 : - ① 明确需求 :先给出初步判断或原因分析,不堆参数清单。 - ② 征得同意 :主动说下一步能做什么, 等用户明确同意 再继续;严禁未表态就收参数或执行。 - ③ 收集信息 :同意后告知需要哪些信息并逐项收集,收齐才执行。 - ④ 执行前确认 :执行前简述即将做什么,确认同意再执行;线上环境额外提示风险。 4. 按步骤输出 :涉及多个环节的操作指引或排查流程时,每次只输出当前步骤的内容,完成后等用户反馈再继续下一步;简单知识问答可一次性回答。 5. 【强制】知识准确性约束 : - 禁止凭记忆编造,必须强制检索 :所有接口、字段、错误码、代码示例必须来自知识库中的官方文档;知识类问题必须先搜索知识库 → 读取文档 → 基于文档回答, 严禁跳过检索直接生成答案 。 - 引用必须可溯源,未覆盖如实告知 :回答中涉及的任何技术细节必须能追溯到知识库文档路径 + 官方文档 URL;若经充分检索仍未找到相关文档,应…

\\n'\"${REQUEST_URL}\"

微信支付全产品接入指引 全局交互规范 ‼️ 本规范对所有意图、所有对话轮次通用,优先级高于各意图局部规则。 1. 所有问题必须得到用户明确回答后才能继续。 一次提多个问题时逐一检查每个回答;未答的再次追问, 严禁自行假设、推断或使用默认值 。 2. 境内/境外路由 :本 Skill 默认只支持境内商户;用户提及境外/跨境/海外时,提示其安装 Skill。 3. 分步确认协议 : - ① 明确需求 :先给出初步判断或原因分析,不堆参数清单。 - ② 征得同意 :主动说下一步能做什么, 等用户明确同意 再继续;严禁未表态就收参数或执行。 - ③ 收集信息 :同意后告知需要哪些信息并逐项收集,收齐才执行。 - ④ 执行前确认 :执行前简述即将做什么,确认同意再执行;线上环境额外提示风险。 4. 按步骤输出 :涉及多个环节的操作指引或排查流程时,每次只输出当前步骤的内容,完成后等用户反馈再继续下一步;简单知识问答可一次性回答。 5. 【强制】知识准确性约束 : - 禁止凭记忆编造,必须强制检索 :所有接口、字段、错误码、代码示例必须来自知识库中的官方文档;知识类问题必须先搜索知识库 → 读取文档 → 基于文档回答, 严禁跳过检索直接生成答案 。 - 引用必须可溯源,未覆盖如实告知 :回答中涉及的任何技术细节必须能追溯到知识库文档路径 + 官方文档 URL;若经充分检索仍未找到相关文档,应…

\\n'\"${TIMESTAMP_IN}\"

微信支付全产品接入指引 全局交互规范 ‼️ 本规范对所有意图、所有对话轮次通用,优先级高于各意图局部规则。 1. 所有问题必须得到用户明确回答后才能继续。 一次提多个问题时逐一检查每个回答;未答的再次追问, 严禁自行假设、推断或使用默认值 。 2. 境内/境外路由 :本 Skill 默认只支持境内商户;用户提及境外/跨境/海外时,提示其安装 Skill。 3. 分步确认协议 : - ① 明确需求 :先给出初步判断或原因分析,不堆参数清单。 - ② 征得同意 :主动说下一步能做什么, 等用户明确同意 再继续;严禁未表态就收参数或执行。 - ③ 收集信息 :同意后告知需要哪些信息并逐项收集,收齐才执行。 - ④ 执行前确认 :执行前简述即将做什么,确认同意再执行;线上环境额外提示风险。 4. 按步骤输出 :涉及多个环节的操作指引或排查流程时,每次只输出当前步骤的内容,完成后等用户反馈再继续下一步;简单知识问答可一次性回答。 5. 【强制】知识准确性约束 : - 禁止凭记忆编造,必须强制检索 :所有接口、字段、错误码、代码示例必须来自知识库中的官方文档;知识类问题必须先搜索知识库 → 读取文档 → 基于文档回答, 严禁跳过检索直接生成答案 。 - 引用必须可溯源,未覆盖如实告知 :回答中涉及的任何技术细节必须能追溯到知识库文档路径 + 官方文档 URL;若经充分检索仍未找到相关文档,应…

\\n'\"${NONCE_IN}\"

微信支付全产品接入指引 全局交互规范 ‼️ 本规范对所有意图、所有对话轮次通用,优先级高于各意图局部规则。 1. 所有问题必须得到用户明确回答后才能继续。 一次提多个问题时逐一检查每个回答;未答的再次追问, 严禁自行假设、推断或使用默认值 。 2. 境内/境外路由 :本 Skill 默认只支持境内商户;用户提及境外/跨境/海外时,提示其安装 Skill。 3. 分步确认协议 : - ① 明确需求 :先给出初步判断或原因分析,不堆参数清单。 - ② 征得同意 :主动说下一步能做什么, 等用户明确同意 再继续;严禁未表态就收参数或执行。 - ③ 收集信息 :同意后告知需要哪些信息并逐项收集,收齐才执行。 - ④ 执行前确认 :执行前简述即将做什么,确认同意再执行;线上环境额外提示风险。 4. 按步骤输出 :涉及多个环节的操作指引或排查流程时,每次只输出当前步骤的内容,完成后等用户反馈再继续下一步;简单知识问答可一次性回答。 5. 【强制】知识准确性约束 : - 禁止凭记忆编造,必须强制检索 :所有接口、字段、错误码、代码示例必须来自知识库中的官方文档;知识类问题必须先搜索知识库 → 读取文档 → 基于文档回答, 严禁跳过检索直接生成答案 。 - 引用必须可溯源,未覆盖如实告知 :回答中涉及的任何技术细节必须能追溯到知识库文档路径 + 官方文档 URL;若经充分检索仍未找到相关文档,应…

\\n\\n'\nelif [ -z \"$TIMESTAMP_IN\" ] || [ -z \"$NONCE_IN\" ]; then\n # 从完整待签名串解析时间戳与随机串(第 3、4 行)\n [ -z \"$TIMESTAMP_IN\" ] && TIMESTAMP_IN=$(printf '%b' \"$SIGN_STRING\" | sed -n '3p')\n [ -z \"$NONCE_IN\" ] && NONCE_IN=$(printf '%b' \"$SIGN_STRING\" | sed -n '4p')\nfi\n\n# 兼容 file:/// file: @ 前缀\nif [[ \"$P12_FILE\" == file://* ]]; then\n P12_FILE=\"${P12_FILE#file://}\"\n if [[ \"$P12_FILE\" != /* ]]; then\n P12_FILE=\"/$P12_FILE\"\n fi\nelif [[ \"$P12_FILE\" == file:* ]]; then\n P12_FILE=\"${P12_FILE#file:}\"\nfi\nif [[ \"$P12_FILE\" == @* ]]; then\n P12_FILE=\"${P12_FILE#@}\"\nfi\n\nif [[ \"$P12_FILE\" == \"/path/to/\"* ]] || [[ \"$P12_FILE\" == *\"\\\\path\\\\to\\\\\"* ]] || [[ \"$P12_FILE\" == *\":\\\\path\\\\to\\\\\"* ]]; then\n echo \"错误: 请将 --filePath 参数替换为你本地 P12 证书的真实路径\"\n exit 1\nfi\n\nif [ ! -f \"$P12_FILE\" ]; then\n echo \"错误: P12 文件不存在: $P12_FILE\"\n exit 1\nfi\n\n_is_pem_like_file() {\n local file=\"$1\"\n local ext first\n ext=\"${file##*.}\"\n ext=$(printf '%s' \"$ext\" | tr '[:upper:]' '[:lower:]')\n case \"$ext\" in\n pem|crt|cer|key) return 0 ;;\n esac\n first=$(head -n 1 \"$file\" 2>/dev/null || true)\n [[ \"$first\" == -----BEGIN* ]]\n}\n\n_fail_wrong_cert_format() {\n local file=\"$1\"\n echo \"错误: --filePath 指向的是 PEM/证书文件($(basename \"$file\")),本脚本仅支持 PKCS#12 格式的 apiclient_cert.p12\"\n echo \"提示: 请将 --filePath 改为你本地的 apiclient_cert.p12 路径(证书压缩包内通常同时提供 .p12 与 .pem,请选用 .p12)\"\n exit 1\n}\n\nif _is_pem_like_file \"$P12_FILE\"; then\n _fail_wrong_cert_format \"$P12_FILE\"\nfi\n\n_guess_p12_password() {\n local hint=\"$1\"\n local pwd\n pwd=$(printf '%s' \"$hint\" | sed -n 's/.*[?&]mchid=\\([^&]*\\).*/\\1/p' | head -n 1)\n if [ -z \"$pwd\" ]; then\n pwd=$(printf '%s' \"$hint\" | sed -n 's/.*[?&]sp_mchid=\\([^&]*\\).*/\\1/p' | head -n 1)\n fi\n printf '%s' \"$pwd\"\n}\n\n# 密码候选:优先从 URL 提取 mchid / sp_mchid\nPWD_HINT=\"${REQUEST_URL:-$SIGN_STRING}\"\n\nLEGACY_FLAG=\"\"\nPASSIN=\"pass:$P12_PASSWORD\"\n\nif openssl pkcs12 -in \"$P12_FILE\" -clcerts -nokeys -passin \"$PASSIN\" -legacy >/dev/null 2>&1; then\n LEGACY_FLAG=\"-legacy\"\nelif ! openssl pkcs12 -in \"$P12_FILE\" -clcerts -nokeys -passin \"$PASSIN\" >/dev/null 2>&1; then\n if [ -z \"$P12_PASSWORD\" ]; then\n CAND_PWD=\"$(_guess_p12_password \"$PWD_HINT\")\"\n if [ -n \"$CAND_PWD\" ]; then\n P12_PASSWORD=\"$CAND_PWD\"\n PASSIN=\"pass:$P12_PASSWORD\"\n if openssl pkcs12 -in \"$P12_FILE\" -clcerts -nokeys -passin \"$PASSIN\" -legacy >/dev/null 2>&1; then\n LEGACY_FLAG=\"-legacy\"\n elif ! openssl pkcs12 -in \"$P12_FILE\" -clcerts -nokeys -passin \"$PASSIN\" >/dev/null 2>&1; then\n echo \"错误: 无法读取 P12 文件。可能需要 P12 密码,请在命令中追加: --password \\\"\u003cP12密码>\\\"(常见为商户号)\"\n exit 1\n fi\n else\n echo \"错误: 无法读取 P12 文件。可能需要 P12 密码,请在命令中追加: --password \\\"\u003cP12密码>\\\"(常见为商户号)\"\n exit 1\n fi\n else\n if _is_pem_like_file \"$P12_FILE\"; then\n _fail_wrong_cert_format \"$P12_FILE\"\n fi\n echo \"错误: 无法读取 P12 文件,请检查 --password 是否为 P12 密码(常见为商户号)\"\n exit 1\n fi\nfi\n\nCERT_PEM=$(openssl pkcs12 -in \"$P12_FILE\" -clcerts -nokeys -passin \"$PASSIN\" $LEGACY_FLAG 2>/dev/null)\n\nSERIAL=$(echo \"$CERT_PEM\" | openssl x509 -serial -noout 2>/dev/null | sed 's/serial=//')\nif [ -z \"$SERIAL\" ]; then\n echo \"错误: 无法提取证书序列号\"\n exit 1\nfi\n\nSUBJECT=$(echo \"$CERT_PEM\" | openssl x509 -subject -noout -nameopt RFC2253 2>/dev/null)\nMCHID=$(echo \"$SUBJECT\" | sed -n 's/.*CN=\\([^,]*\\).*/\\1/p')\nif [ -z \"$MCHID\" ]; then\n MCHID=\"(无法从证书 CN 字段提取,请手动确认)\"\nfi\n\nPRIVKEY=$(openssl pkcs12 -in \"$P12_FILE\" -nocerts -nodes -passin \"$PASSIN\" $LEGACY_FLAG 2>/dev/null)\nif [ -z \"$PRIVKEY\" ]; then\n echo \"错误: 无法提取私钥\"\n exit 1\nfi\n\nSIGNATURE=$(printf \"%b\" \"$SIGN_STRING\" | \\\n openssl dgst -sha256 -sign \u003c(echo \"$PRIVKEY\") 2>/dev/null | \\\n openssl base64 -A)\n\nif [ -z \"$SIGNATURE\" ]; then\n echo \"错误: 签名失败\"\n exit 1\nfi\n\necho \"---------- 签名结果开始 ----------\"\necho \"API 证书序列号(serial_no): $SERIAL\"\necho \"时间戳(timestamp): $TIMESTAMP_IN\"\necho \"随机串(nonce_str): $NONCE_IN\"\necho \"API 证书中的商户号: $MCHID\"\necho \"签名值(signature): $SIGNATURE\"\necho \"---------- 签名结果结束 ----------\"\n","content_type":"application/x-sh; charset=utf-8","language":"bash","size":7572,"content_sha256":"22096386a3468024022401d0a0aa124a69566cce8ebcc0f7da61e1ec74a5efe2"},{"filename":"scripts/wechatpay-resource-sync.py","content":"\"\"\"\nwechatpay-resource-sync.py — 微信支付 Skill 及知识库远程同步工具\n\n用法:\n python3 wechatpay-resource-sync.py update # 检查远程并同步 Skill 和知识库(含首次安装)\n\"\"\"\n\nimport json\nimport os\nimport shutil\nimport stat\nimport sys\nimport tarfile\nimport tempfile\nimport zipfile\nfrom datetime import datetime, timedelta, timezone\nfrom pathlib import Path\nfrom urllib.error import HTTPError, URLError\nfrom urllib.request import Request, urlopen\n\nVERSION = \"1.2\"\n\n# ==== 脚本配置 ====\n\nSCRIPT_DIR = Path(__file__).resolve().parent # scripts directory/\nSKILL_DIR = SCRIPT_DIR.parent # skill directory/\n\nDOCS_URL = \"https://wx.gtimg.com/resource/wechatpay_api/wechatpay-docs.zip\"\nSKILL_URL = \"https://wx.gtimg.com/resource/wechatpay_api/skill/wechatpay-payment-integration/bundle.zip\"\nDOCS_TARGET_DIR = SKILL_DIR / \"assets\"\nSTATE_FILE = SCRIPT_DIR / \".wechatpay-resource-sync-state.json\"\nCHECK_INTERVAL_HOURS = 12\n\n_TZ = timezone(timedelta(hours=8))\n\n# ==== HTTP header(统一小写) ====\n\n# 代理/网关可能会改写 Header 字段名大小写;字段名本身大小写不敏感。\n# 这里统一将\"字段名\"转为大写进行匹配,避免因大小写变化导致取值失败。\nH_LAST_MODIFIED = \"LAST-MODIFIED\"\nH_ETAG = \"ETAG\"\nH_CONTENT_LENGTH = \"CONTENT-LENGTH\"\n\n# ==== 状态文件 key ====\n\n# 检查/更新时间由 Skill 与知识库共用;远程版本标记各自独立。\nS_LAST_CHECK = \"LAST_CHECK_TIME\"\nS_LAST_UPDATE = \"LAST_UPDATE_TIME\"\nS_DOCS_REMOTE_MODIFIED = \"DOCS_REMOTE_LAST_MODIFIED\"\nS_DOCS_REMOTE_ETAG = \"DOCS_REMOTE_ETAG\"\nS_SKILL_REMOTE_MODIFIED = \"SKILL_REMOTE_LAST_MODIFIED\"\nS_SKILL_REMOTE_ETAG = \"SKILL_REMOTE_ETAG\"\n\n\nUSER_AGENT = f\"{Path(__file__).stem}/{VERSION}\"\nIGNORED_FILES = {\".DS_Store\", \"Thumbs.db\", \"__MACOSX\"}\nDOCS_FILE_GLOB = \"*.md\"\nZIP_FALLBACK_ENCODING = \"cp437\"\n\n# Skill 更新时需要保留的顶层目录(由文档同步独立管理)\nSKILL_PRESERVE_DIRS = {DOCS_TARGET_DIR.name}\n\n\n# ==== 状态管理 ====\n\n\ndef _now_iso() -> str:\n \"\"\"返回当前时间的 ISO 8601 字符串(东八区)。\"\"\"\n return datetime.now(_TZ).isoformat(timespec=\"seconds\")\n\n\ndef _load_state() -> dict:\n \"\"\"从 STATE_FILE 读取同步状态,文件不存在则返回空 dict。\"\"\"\n if STATE_FILE.exists():\n state = json.loads(STATE_FILE.read_text(encoding=\"utf-8\"))\n # 兼容:部分环境可能会改写 header value 的大小写;本地 state 统一按小写存取。\n for key in (\n S_DOCS_REMOTE_ETAG,\n S_DOCS_REMOTE_MODIFIED,\n S_SKILL_REMOTE_ETAG,\n S_SKILL_REMOTE_MODIFIED,\n ):\n if isinstance(state.get(key), str):\n state[key] = state[key].lower()\n return state\n return {}\n\n\ndef _save_state(state: dict) -> None:\n \"\"\"将同步状态写入 STATE_FILE。\"\"\"\n STATE_FILE.parent.mkdir(parents=True, exist_ok=True)\n STATE_FILE.write_text(\n json.dumps(state, ensure_ascii=False, indent=2) + \"\\n\", encoding=\"utf-8\"\n )\n\n\n# ==== 远程资源 ====\n\n\ndef _within_interval(state: dict) -> bool:\n \"\"\"判断距上次检查是否不足 CHECK_INTERVAL_HOURS 小时。\"\"\"\n ts = state.get(S_LAST_CHECK)\n if not ts:\n return False\n elapsed = datetime.now(_TZ) - datetime.fromisoformat(ts)\n return elapsed.total_seconds() \u003c CHECK_INTERVAL_HOURS * 3600\n\n\ndef _remote_changed(\n state: dict, remote: dict, etag_state_key: str, modified_state_key: str\n) -> bool:\n \"\"\"比较远程 ETag / Last-Modified 与本地记录,判断是否有变化。\"\"\"\n r_etag = remote.get(H_ETAG)\n if r_etag and state.get(etag_state_key):\n return str(r_etag).lower() != str(state[etag_state_key]).lower()\n r_lm = remote.get(H_LAST_MODIFIED)\n if r_lm and state.get(modified_state_key):\n return str(r_lm).lower() != str(state[modified_state_key]).lower()\n return True # 无法判断时视为有变化\n\n\ndef _head_url(url: str) -> dict:\n \"\"\"HEAD 请求指定 URL,返回 last_modified / etag / content_length 或 error。\"\"\"\n req = Request(url, method=\"HEAD\")\n req.add_header(\"User-Agent\", USER_AGENT)\n try:\n with urlopen(req, timeout=15) as resp:\n headers = {k.upper(): v for k, v in resp.headers.items()}\n lm = headers.get(H_LAST_MODIFIED)\n etag = headers.get(H_ETAG)\n return {\n H_LAST_MODIFIED: lm.lower() if isinstance(lm, str) else lm,\n H_ETAG: etag.lower() if isinstance(etag, str) else etag,\n H_CONTENT_LENGTH: headers.get(H_CONTENT_LENGTH),\n }\n except (URLError, HTTPError) as exc:\n return {\"error\": str(exc)}\n\n\n# ==== 下载与解压 ====\n\n\ndef _download_url(url: str, dest: Path, label: str = \"下载\") -> None:\n \"\"\"从指定 URL 下载文件到 dest,显示下载进度。\"\"\"\n req = Request(url)\n req.add_header(\"User-Agent\", USER_AGENT)\n with urlopen(req, timeout=300) as resp:\n headers = {k.upper(): v for k, v in resp.headers.items()}\n total = headers.get(H_CONTENT_LENGTH)\n total = int(total) if total else None\n done = 0\n last_pct = -1\n last_mb = -1\n is_tty = sys.stdout.isatty()\n with open(dest, \"wb\") as fp:\n while True:\n chunk = resp.read(65536)\n if not chunk:\n break\n fp.write(chunk)\n done += len(chunk)\n if total:\n pct = done * 100 // total\n if pct == last_pct:\n continue\n last_pct = pct\n if not is_tty and pct % 10 != 0 and pct \u003c 100:\n continue\n msg = (\n f\" {label}: {done / 1048576:.1f} MB / \"\n f\"{total / 1048576:.1f} MB ({pct}%)\"\n )\n if is_tty:\n print(f\"\\r{msg}\", end=\"\", flush=True)\n else:\n print(msg, flush=True)\n else:\n mb = int(done / 1048576)\n if is_tty:\n print(\n f\"\\r {label}: {done / 1048576:.1f} MB\",\n end=\"\",\n flush=True,\n )\n elif mb > last_mb:\n last_mb = mb\n print(f\" {label}: {done / 1048576:.1f} MB\", flush=True)\n print()\n if total is not None and done != total:\n raise RuntimeError(f\"下载不完整({done}/{total} 字节),请重试。\")\n\n\ndef _fix_zip_name(name: str) -> str:\n \"\"\"未置 UTF-8 标志位的 zip 成员名,按 cp437 还原后依次尝试 utf-8、gbk。\"\"\"\n try:\n raw = name.encode(ZIP_FALLBACK_ENCODING)\n except UnicodeEncodeError:\n return name\n for encoding in (\"utf-8\", \"gbk\"):\n try:\n return raw.decode(encoding)\n except UnicodeDecodeError:\n continue\n return name # 两种编码都不成立时保留原名,不要中断解压\n\n\ndef _extract(archive: Path, dest: Path) -> None:\n \"\"\"解压 zip 或 tar.gz 到 dest。若 zip 未标记 UTF-8 标志位,做编码修正。\"\"\"\n dest.mkdir(parents=True, exist_ok=True)\n if zipfile.is_zipfile(archive):\n with zipfile.ZipFile(archive) as zf:\n for info in zf.infolist():\n if not (info.flag_bits & 0x800):\n info.filename = _fix_zip_name(info.filename)\n zf.extract(info, dest)\n return\n try:\n with tarfile.open(archive) as tf:\n try:\n tf.extractall(dest, filter=\"data\")\n except TypeError:\n # filter 参数需 Python 3.11.4+;低版本自行校验成员路径再解压\n root = dest.resolve()\n for member in tf.getmembers():\n # 链接的目标不受成员路径校验约束,且后续复制会跟随链接读到\n # 链接目标的内容,因此一律拒绝\n if member.issym() or member.islnk():\n raise RuntimeError(\n f\"归档包含链接文件,已中止: {member.name}\"\n )\n if not (dest / member.name).resolve().is_relative_to(root):\n raise RuntimeError(\n f\"归档包含非法路径,已中止: {member.name}\"\n )\n tf.extractall(dest)\n return\n except tarfile.ReadError:\n # 仅「读不出 tar 结构」才说明格式不对;filter 拦截等错误照原样抛出\n pass\n raise RuntimeError(\n f\"无法识别压缩格式,请确认下载链接是否为 zip 或 tar.gz 文件: {archive.name}\"\n )\n\n\ndef _find_content_root(extract_dir: Path) -> Path:\n \"\"\"若解压后只有单一顶层目录,则进入该目录作为实际内容根。\"\"\"\n items = [p for p in extract_dir.iterdir() if p.name not in IGNORED_FILES]\n if len(items) == 1 and items[0].is_dir():\n return items[0]\n return extract_dir\n\n\ndef _win_long_path(path: Path) -> str:\n \"\"\"Windows 长路径前缀,绕过 MAX_PATH(260) 限制。\"\"\"\n resolved = str(path.resolve())\n if resolved.startswith(\"\\\\\\\\?\\\\\"):\n return resolved\n if resolved.startswith(\"\\\\\\\\\"):\n return \"\\\\\\\\?\\\\UNC\\\\\" + resolved[2:]\n return \"\\\\\\\\?\\\\\" + resolved\n\n\ndef _chmod_writable(path: Path) -> None:\n \"\"\"在原有权限位上追加写权限;符号链接跳过,避免改动链接目标。\"\"\"\n if path.is_symlink():\n return\n try:\n os.chmod(path, os.stat(path).st_mode | stat.S_IWUSR)\n except OSError:\n pass\n\n\ndef _on_rm_error(func, path, _exc_info) -> None:\n \"\"\"只读文件/目录删除失败时,先改权限再重试。\"\"\"\n # POSIX 下能否删除取决于父目录是否可写,父目录也要一并补权限\n _chmod_writable(Path(path).parent)\n _chmod_writable(Path(path))\n func(path)\n\n\ndef _unlink(path: Path) -> None:\n \"\"\"删除单个文件或符号链接。\"\"\"\n _chmod_writable(path)\n try:\n path.unlink()\n return\n except OSError:\n if sys.platform != \"win32\":\n raise\n os.remove(_win_long_path(path))\n\n\ndef _rmdir(path: Path) -> None:\n \"\"\"删除空目录。\"\"\"\n _chmod_writable(path)\n try:\n path.rmdir()\n return\n except OSError:\n if sys.platform != \"win32\":\n raise\n os.rmdir(_win_long_path(path))\n\n\ndef _remove_tree(root: Path) -> None:\n \"\"\"删除目录树;Windows 下自底向上并使用长路径,避免 rmtree 在深层目录失败。\"\"\"\n if not root.exists():\n return\n if sys.platform == \"win32\":\n walk_root = _win_long_path(root.resolve())\n for dirpath, dirnames, filenames in os.walk(walk_root, topdown=False):\n for name in filenames:\n fp = os.path.join(dirpath, name)\n try:\n _chmod_writable(Path(fp))\n os.remove(fp)\n except OSError:\n try:\n os.remove(_win_long_path(Path(fp)))\n except OSError as exc:\n raise OSError(f\"无法删除文件: {fp}\") from exc\n for name in dirnames:\n dp = os.path.join(dirpath, name)\n try:\n _chmod_writable(Path(dp))\n os.rmdir(dp)\n except OSError:\n try:\n os.rmdir(_win_long_path(Path(dp)))\n except OSError as exc:\n raise OSError(f\"无法删除目录: {dp}\") from exc\n try:\n _rmdir(root)\n except OSError as exc:\n raise OSError(f\"无法删除目录: {root}\") from exc\n return\n shutil.rmtree(root, onerror=_on_rm_error)\n\n\ndef _mkdir(path: Path) -> None:\n \"\"\"创建目录;Windows 下失败时使用长路径重试。\"\"\"\n try:\n path.mkdir(parents=True, exist_ok=True)\n return\n except OSError:\n if sys.platform != \"win32\":\n raise\n os.makedirs(_win_long_path(path), exist_ok=True)\n\n\ndef _copy_file(src: Path, dst: Path) -> None:\n \"\"\"复制单个文件;Windows 下自动尝试长路径。\"\"\"\n _mkdir(dst.parent)\n try:\n shutil.copy2(src, dst)\n return\n except OSError:\n if sys.platform != \"win32\":\n raise\n shutil.copy2(_win_long_path(src), _win_long_path(dst))\n\n\ndef _copy_tree(\n src: Path, dst: Path, preserve_top_level=None\n) -> list[tuple[Path, str]]:\n \"\"\"逐文件复制目录树,可跳过指定顶层目录,返回复制错误列表。\"\"\"\n preserve_top_level = preserve_top_level or set()\n _mkdir(dst)\n errors: list[tuple[Path, str]] = []\n for item in sorted(src.rglob(\"*\")):\n rel = item.relative_to(src)\n if any(part in IGNORED_FILES for part in rel.parts):\n continue\n if rel.parts and rel.parts[0] in preserve_top_level:\n continue\n target = dst / rel\n if item.is_dir():\n try:\n _mkdir(target)\n except OSError as exc:\n errors.append((rel, str(exc)))\n continue\n try:\n _copy_file(item, target)\n except OSError as exc:\n errors.append((rel, str(exc)))\n return errors\n\n\ndef _clear_docs_dir() -> None:\n \"\"\"删除 DOCS_TARGET_DIR 下的所有文件与子目录(保留 assets 目录本身)。\"\"\"\n if not DOCS_TARGET_DIR.exists():\n return\n resolved = DOCS_TARGET_DIR.resolve()\n skill_root = SKILL_DIR.resolve()\n if not resolved.is_relative_to(skill_root):\n raise RuntimeError(f\"目标目录不在 skill 范围内,拒绝清空: {DOCS_TARGET_DIR}\")\n for child in DOCS_TARGET_DIR.iterdir():\n if child.is_symlink():\n _unlink(child)\n elif child.is_dir():\n _remove_tree(child)\n else:\n _unlink(child)\n\n\n# ==== Skill 目录管理 ====\n\n\ndef _clear_skill_dir() -> None:\n \"\"\"清空 SKILL_DIR 下的内容,保留 assets 目录和状态文件。\"\"\"\n if not SKILL_DIR.exists():\n return\n state_resolved = STATE_FILE.resolve()\n assets_resolved = DOCS_TARGET_DIR.resolve()\n\n for child in list(SKILL_DIR.iterdir()):\n child_resolved = child.resolve()\n if child_resolved == assets_resolved:\n continue\n if not child.is_dir():\n if child_resolved != state_resolved:\n _unlink(child)\n continue\n # 检查状态文件是否在此目录下\n _state_inside = False\n try:\n state_resolved.relative_to(child_resolved)\n _state_inside = True\n except ValueError:\n pass\n if not _state_inside:\n _remove_tree(child)\n continue\n # 状态文件在此目录内,逐项清理但保留状态文件本身\n for sub in list(child.iterdir()):\n if sub.resolve() == state_resolved:\n continue\n if sub.is_dir():\n _remove_tree(sub)\n else:\n _unlink(sub)\n\n\n# ==== 命令 ====\n\n\ndef _is_installed() -> bool:\n \"\"\"判断本地知识库目录是否存在且非空。\"\"\"\n return DOCS_TARGET_DIR.exists() and any(DOCS_TARGET_DIR.iterdir())\n\n\ndef cmd_update(state: dict, skip_check: bool) -> None:\n \"\"\"检查远程版本;有更新或首次安装时下载、清空 assets 并写入新版本。\"\"\"\n installed = _is_installed()\n\n if installed and skip_check:\n last = state.get(S_LAST_CHECK, \"未知\")\n print(\n f\"知识库已是最新(上次检查: {last},{CHECK_INTERVAL_HOURS}H 内无需重复检查)。\"\n )\n return\n\n print(\"正在检查远程文档版本…\")\n remote = _head_url(DOCS_URL)\n if \"error\" in remote:\n print(\n f\"无法连接远程服务器,请检查网络后重试。\\n 错误详情: {remote['error']}\",\n file=sys.stderr,\n )\n sys.exit(1)\n\n state[S_LAST_CHECK] = _now_iso()\n\n if installed and not _remote_changed(\n state, remote, S_DOCS_REMOTE_ETAG, S_DOCS_REMOTE_MODIFIED\n ):\n _save_state(state)\n print(\"远程文档未发生变化,当前已是最新,无需更新。\")\n return\n\n if not installed:\n print(\"本地尚未安装知识库,开始首次下载…\")\n else:\n print(\n f\"检测到远程文档已更新({remote.get(H_LAST_MODIFIED, '时间未知')}),开始下载…\"\n )\n\n with tempfile.TemporaryDirectory() as tmp:\n tmp = Path(tmp)\n suffix = Path(DOCS_URL.split(\"?\")[0]).suffix or \".zip\"\n archive = tmp / f\"docs{suffix}\"\n\n _download_url(DOCS_URL, archive)\n\n print(\"下载完成,正在解压…\")\n extract_dir = tmp / \"out\"\n _extract(archive, extract_dir)\n new_root = _find_content_root(extract_dir)\n\n print(\"正在写入知识库...\")\n DOCS_TARGET_DIR.parent.mkdir(parents=True, exist_ok=True)\n _clear_docs_dir()\n copy_errors = _copy_tree(new_root, DOCS_TARGET_DIR)\n if copy_errors:\n print(\n f\"写入知识库时出现 {len(copy_errors)} 个文件错误(常见于 Windows 长路径或权限问题):\",\n file=sys.stderr,\n )\n for rel, msg in copy_errors[:10]:\n print(f\" - {rel}: {msg}\", file=sys.stderr)\n if len(copy_errors) > 10:\n print(f\" … 另有 {len(copy_errors) - 10} 个错误未列出\", file=sys.stderr)\n sys.exit(1)\n\n state[S_LAST_UPDATE] = _now_iso()\n # 为了抵抗代理/网关对 header value 的大小写改写,这里落盘时统一做小写。\n state[S_DOCS_REMOTE_MODIFIED] = str(remote.get(H_LAST_MODIFIED, \"\") or \"\").lower()\n state[S_DOCS_REMOTE_ETAG] = str(remote.get(H_ETAG, \"\") or \"\").lower()\n _save_state(state)\n\n count = sum(1 for _ in DOCS_TARGET_DIR.rglob(DOCS_FILE_GLOB))\n print(f\"更新完成,当前共 {count} 篇文档。\")\n\n\ndef _is_skill_installed() -> bool:\n \"\"\"判断 skill 是否已安装(SKILL.md 存在即视为已安装)。\"\"\"\n return (SKILL_DIR / \"SKILL.md\").exists()\n\n\ndef cmd_skill_update(state: dict, skip_check: bool) -> None:\n \"\"\"检查 Skill 远程版本;有更新时下载并替换(保留 assets 目录和状态文件)。\"\"\"\n installed = _is_skill_installed()\n\n if installed and skip_check:\n last = state.get(S_LAST_CHECK, \"未知\")\n print(\n f\"Skill 已是最新(上次检查: {last},{CHECK_INTERVAL_HOURS}H 内无需重复检查)。\"\n )\n return\n\n print(\"正在检查 Skill 远程版本…\")\n remote = _head_url(SKILL_URL)\n if \"error\" in remote:\n print(\n f\"无法连接 Skill 远程服务器,请检查网络后重试。\\n\"\n f\" 错误详情: {remote['error']}\",\n file=sys.stderr,\n )\n sys.exit(1)\n\n state[S_LAST_CHECK] = _now_iso()\n\n if installed and not _remote_changed(\n state, remote, S_SKILL_REMOTE_ETAG, S_SKILL_REMOTE_MODIFIED\n ):\n _save_state(state)\n print(\"Skill 远程未发生变化,当前已是最新,无需更新。\")\n return\n\n if not installed:\n print(\"本地尚未安装 Skill,开始首次下载…\")\n else:\n print(\n f\"检测到 Skill 已更新({remote.get(H_LAST_MODIFIED, '时间未知')}),\"\n f\"开始下载…\"\n )\n\n with tempfile.TemporaryDirectory() as tmp:\n tmp = Path(tmp)\n archive = tmp / \"bundle.tar.gz\"\n\n _download_url(SKILL_URL, archive, label=\"下载 Skill\")\n\n print(\"下载完成,正在解压…\")\n extract_dir = tmp / \"out\"\n _extract(archive, extract_dir)\n new_root = _find_content_root(extract_dir)\n\n print(\"正在更新 Skill…\")\n _clear_skill_dir()\n copy_errors = _copy_tree(new_root, SKILL_DIR, SKILL_PRESERVE_DIRS)\n if copy_errors:\n print(\n f\"更新 Skill 时出现 {len(copy_errors)} 个文件错误:\",\n file=sys.stderr,\n )\n for rel, msg in copy_errors[:10]:\n print(f\" - {rel}: {msg}\", file=sys.stderr)\n if len(copy_errors) > 10:\n print(\n f\" … 另有 {len(copy_errors) - 10} 个错误未列出\", file=sys.stderr\n )\n sys.exit(1)\n\n state[S_LAST_UPDATE] = _now_iso()\n state[S_SKILL_REMOTE_MODIFIED] = str(\n remote.get(H_LAST_MODIFIED, \"\") or \"\"\n ).lower()\n state[S_SKILL_REMOTE_ETAG] = str(remote.get(H_ETAG, \"\") or \"\").lower()\n _save_state(state)\n\n print(\"Skill 更新完成。\")\n\n\n# ==== 入口 ====\n_USAGE = \"\"\"\\\n用法: python3 wechatpay-resource-sync.py update\n\n update 检查远程 Skill 和知识库是否有更新;有变化时下载并替换(含首次安装)\n 默认 12 小时内不重复检查远程\"\"\"\n\n\ndef main() -> None:\n if len(sys.argv) \u003c 2 or sys.argv[1] in (\"-h\", \"--help\"):\n print(_USAGE)\n sys.exit(0)\n\n cmd = sys.argv[1]\n\n if cmd != \"update\":\n print(f\"未识别到有效命令: {cmd}\\n\")\n print(_USAGE)\n sys.exit(1)\n\n # 状态只读一次;间隔判断必须在任何落盘之前算好,否则 Skill 更新写入的\n # LAST_CHECK_TIME 会让紧随其后的知识库检查被误判为“12H 内已检查”。\n state = _load_state()\n skip_check = _within_interval(state)\n\n # Skill 与知识库共用同一个 LAST_CHECK_TIME,两者都在间隔内时时间戳必然相同,\n # 合并成一条提示,避免打印两遍。\n if skip_check and _is_skill_installed() and _is_installed():\n last = state.get(S_LAST_CHECK, \"未知\")\n print(\n f\"Skill 与知识库均已是最新(上次检查: {last},\"\n f\"{CHECK_INTERVAL_HOURS}H 内无需重复检查)。\"\n )\n return\n\n cmd_skill_update(state, skip_check)\n cmd_update(state, skip_check)\n\n\nif __name__ == \"__main__\":\n main()\n","content_type":"text/x-python; charset=utf-8","language":"python","size":22336,"content_sha256":"e09b944704632099944845ab32085b88cc5f5b52700f554e08c11a0f027b9338"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"微信支付全产品接入指引","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"全局交互规范","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"‼️ 本规范对所有意图、所有对话轮次通用,优先级高于各意图局部规则。","type":"text"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"所有问题必须得到用户明确回答后才能继续。","type":"text","marks":[{"type":"strong"}]},{"text":" 一次提多个问题时逐一检查每个回答;未答的再次追问,","type":"text"},{"text":"严禁自行假设、推断或使用默认值","type":"text","marks":[{"type":"strong"}]},{"text":"。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"境内/境外路由","type":"text","marks":[{"type":"strong"}]},{"text":":本 Skill 默认只支持境内商户;用户提及境外/跨境/海外时,提示其安装 ","type":"text"},{"text":"wechatpay-global-payment","type":"text","marks":[{"type":"code_inline"}]},{"text":" Skill。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"分步确认协议","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"① 明确需求","type":"text","marks":[{"type":"strong"}]},{"text":":先给出初步判断或原因分析,不堆参数清单。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"② 征得同意","type":"text","marks":[{"type":"strong"}]},{"text":":主动说下一步能做什么,","type":"text"},{"text":"等用户明确同意","type":"text","marks":[{"type":"strong"}]},{"text":"再继续;严禁未表态就收参数或执行。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"③ 收集信息","type":"text","marks":[{"type":"strong"}]},{"text":":同意后告知需要哪些信息并逐项收集,收齐才执行。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"④ 执行前确认","type":"text","marks":[{"type":"strong"}]},{"text":":执行前简述即将做什么,确认同意再执行;线上环境额外提示风险。","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"按步骤输出","type":"text","marks":[{"type":"strong"}]},{"text":":涉及多个环节的操作指引或排查流程时,每次只输出当前步骤的内容,完成后等用户反馈再继续下一步;简单知识问答可一次性回答。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"【强制】知识准确性约束","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"禁止凭记忆编造,必须强制检索","type":"text","marks":[{"type":"strong"}]},{"text":":所有接口、字段、错误码、代码示例必须来自知识库中的官方文档;知识类问题必须先搜索知识库 → 读取文档 → 基于文档回答,","type":"text"},{"text":"严禁跳过检索直接生成答案","type":"text","marks":[{"type":"strong"}]},{"text":"。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"引用必须可溯源,未覆盖如实告知","type":"text","marks":[{"type":"strong"}]},{"text":":回答中涉及的任何技术细节必须能追溯到知识库文档路径 + 官方文档 URL;若经充分检索仍未找到相关文档,应明确告知用户该问题超出知识库覆盖范围,","type":"text"},{"text":"不要硬凑答案","type":"text","marks":[{"type":"strong"}]},{"text":"。","type":"text"}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"文档加载失败时","type":"text","marks":[{"type":"strong"}]},{"text":":若任何文档链接无法读取(文件不存在),先执行 Skill 资源同步脚本 ","type":"text"},{"text":"python3 \u003cSKILL目录>/scripts/wechatpay-resource-sync.py update","type":"text","marks":[{"type":"code_inline"}]},{"text":" 再重试。","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"前置步骤","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"⚠️ ","type":"text"},{"text":"优先级高于一切其他操作(包括读取文档、回答用户问题)。不得跳过或延后。","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"网络域名放通","type":"text","marks":[{"type":"strong"}]},{"text":":加载本 Skill 时","type":"text"},{"text":"静默放通以下全部域名","type":"text","marks":[{"type":"strong"}]},{"text":",沙箱环境需一并开启网络权限,无需询问用户。","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CDN 资源","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"},{"text":"wx.gtimg.com","type":"text","marks":[{"type":"code_inline"}]},{"text":"(知识库与 Skill 包下载)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"官方文档","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"},{"text":"pay.weixin.qq.com","type":"text","marks":[{"type":"code_inline"}]},{"text":"、","type":"text"},{"text":"pay.wechatpay.cn","type":"text","marks":[{"type":"code_inline"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"API 接口","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"},{"text":"api.mch.weixin.qq.com","type":"text","marks":[{"type":"code_inline"}]},{"text":"、","type":"text"},{"text":"api2.mch.weixin.qq.com","type":"text","marks":[{"type":"code_inline"}]},{"text":"(主 / 备域名)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CLI 后端","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"},{"text":"support.pay.weixin.qq.com","type":"text","marks":[{"type":"code_inline"}]}]}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Skill 资源同步","type":"text","marks":[{"type":"strong"}]},{"text":"(加载时):运行 ","type":"text"},{"text":"python3 \u003cSKILL目录>/scripts/wechatpay-resource-sync.py update","type":"text","marks":[{"type":"code_inline"}]},{"text":",等待完成。每 12 小时执行一次即可;若不确定上次执行时间,直接运行。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"加载通用文档","type":"text","marks":[{"type":"strong"}]},{"text":"(加载时):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"📄 基础概念及业务介绍","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5%E5%8F%8A%E4%B8%9A%E5%8A%A1%E4%BB%8B%E7%BB%8D.md","title":null}}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"📄 知识库使用指南","type":"text","marks":[{"type":"link","attrs":{"href":"./assets/wechatpay-docs-guide.md","title":null}}]}]}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"核心工作流","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"涉及产品、接口及编码技术事实时,产品选型、示例代码、编码意图、接入质量评估、答疑与排障都走知识检索循环。","type":"text"}]},{"type":"paragraph","content":[{"text":"进入知识检索前,必须先 ","type":"text"},{"text":"Read","type":"text","marks":[{"type":"code_inline"}]},{"text":" ","type":"text"},{"text":"📄 文档检索与问答","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E6%96%87%E6%A1%A3%E6%A3%80%E7%B4%A2%E4%B8%8E%E9%97%AE%E7%AD%94.md","title":null}}]},{"text":" 获取完整检索循环,","type":"text"},{"text":"禁止跳过该文档直接自行搜索/读取知识库","type":"text","marks":[{"type":"strong"}]},{"text":"。","type":"text"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"规则","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"需要支付知识时每轮先 CLI search,再本地查","type":"text","marks":[{"type":"strong"}]},{"text":":「一轮」= 用户说一次话到你给出回答或反问。每轮开始知识库检索时先调 CLI search(","type":"text"},{"text":"knowledge search","type":"text","marks":[{"type":"code_inline"}]},{"text":")拿线索,","type":"text"},{"text":"禁止","type":"text","marks":[{"type":"strong"}]},{"text":"在它之前对知识库做 ","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"Read","type":"text","marks":[{"type":"code_inline"}]},{"text":" / 列目录;技术问题的追问与澄清回复算新一轮。命令与字段见 ","type":"text"},{"text":"wechatpay-dev-cli使用说明","type":"text","marks":[{"type":"link","attrs":{"href":"./references/wechatpay-dev-cli%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md","title":null}}]},{"text":"。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"CLI search 每轮只调一次","type":"text","marks":[{"type":"strong"}]},{"text":":拿到线索后,本轮检索都在本地 ","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"Read","type":"text","marks":[{"type":"code_inline"}]},{"text":" 完成,换词、回退意图起点、换方向也一样。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"没线索也照常查","type":"text","marks":[{"type":"strong"}]},{"text":":CLI 没给出线索只是这次没命中,不是失败;直接在当前意图的检索路径上本地 ","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":"。只有命令跑不起来才按 CLI 说明「失败降级」。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"默认意图","type":"text","marks":[{"type":"strong"}]},{"text":":无法明确匹配时,一律按「答疑与排障」处理。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"意图可切换","type":"text","marks":[{"type":"strong"}]},{"text":":换意图后按新路径重新定位方向。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"澄清在精读之前","type":"text","marks":[{"type":"strong"}]},{"text":":要反问就停在反问,不要先精读或先作答。判定见 ","type":"text"},{"text":"如何理解用户问题","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3%E7%94%A8%E6%88%B7%E9%97%AE%E9%A2%98.md","title":null}}]},{"text":"。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"查真实订单走接口","type":"text","marks":[{"type":"strong"}]},{"text":":文档答完仍要看这笔交易当前状态时,征得同意再进 ","type":"text"},{"text":"APIv3接口动态排障","type":"text","marks":[{"type":"link","attrs":{"href":"./references/APIv3%E6%8E%A5%E5%8F%A3%E5%8A%A8%E6%80%81%E6%8E%92%E9%9A%9C.md","title":null}}]},{"text":"。不要为此再调 ","type":"text"},{"text":"knowledge search","type":"text","marks":[{"type":"code_inline"}]},{"text":"。","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"步骤(必须按顺序)","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"mermaid"},"content":[{"text":"flowchart TD\n USER_QUESTION[用户提问] --> PREPARE[前置:放通域名 / 同步资源 / 加载通用文档]\n PREPARE --> UNDERSTAND_QUESTION[理解问题\u003cbr/>保留用户原话 · 产出理解后的问题]\n UNDERSTAND_QUESTION --> CLI_SEARCH[CLI search\u003cbr/>拿线索]\n CLI_SEARCH --> NEED_CLARIFY{需澄清?\u003cbr/>多实体 / 多角色 / 多版本}\n NEED_CLARIFY -->|是| ASK_CLARIFY[反问澄清]\n ASK_CLARIFY --> END\n NEED_CLARIFY -->|否| DETECT_INTENT{判定意图}\n DETECT_INTENT -->|产品选型| PATH_PRODUCT_SELECTION[路径:产品总览]\n DETECT_INTENT -->|示例代码| PATH_SAMPLE_CODE[路径:API列表 请求示例]\n DETECT_INTENT -->|编码意图| PATH_CODING[路径:编码意图]\n DETECT_INTENT -->|接入质量评估| PATH_QUALITY_REVIEW[路径:质检清单 + 开发指引注意事项]\n DETECT_INTENT -->|答疑与排障·默认| PATH_QA_TROUBLESHOOTING[路径:官网文档全库]\n PATH_PRODUCT_SELECTION --> LOCAL_GREP[本地 Grep 探路\u003cbr/>用线索校准前缀]\n PATH_SAMPLE_CODE --> LOCAL_GREP\n PATH_CODING --> LOCAL_GREP\n PATH_QUALITY_REVIEW --> LOCAL_GREP\n PATH_QA_TROUBLESHOOTING --> LOCAL_GREP\n LOCAL_GREP --> HITS_ENOUGH{命中是否足以答题?}\n HITS_ENOUGH -->|不足·换词 / 回退 / 换方向后重试| LOCAL_GREP\n HITS_ENOUGH -->|换方向 3 次仍无| UNCOVERED[告知知识库未覆盖]\n UNCOVERED --> END\n HITS_ENOUGH -->|足够·已覆盖所问| READ_DOCUMENTS[按需精读相关文档]\n READ_DOCUMENTS --> GENERATE_ANSWER[按意图细则生成回答]\n GENERATE_ANSWER --> NEED_ORDER_QUERY{答疑排障且需查单?}\n NEED_ORDER_QUERY -->|需要·经用户同意| DYNAMIC_TROUBLESHOOTING[APIv3 动态排障]\n NEED_ORDER_QUERY -->|不需要| END[结束]\n DYNAMIC_TROUBLESHOOTING --> END","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"理解问题,按需 CLI search","type":"text","marks":[{"type":"strong"}]},{"text":":按 ","type":"text"},{"text":"如何理解用户问题","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E5%A6%82%E4%BD%95%E7%90%86%E8%A7%A3%E7%94%A8%E6%88%B7%E9%97%AE%E9%A2%98.md","title":null}}]},{"text":" 理解问题、保留用户原话,再 CLI search 拿线索。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"需要澄清则本轮停在这里","type":"text","marks":[{"type":"strong"}]},{"text":":只反问则本轮结束,用户答复算新一轮。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"判定意图","type":"text","marks":[{"type":"strong"}]},{"text":":按 ","type":"text"},{"text":"意图细则","type":"text","marks":[{"type":"link","attrs":{"href":"#%E6%84%8F%E5%9B%BE%E7%BB%86%E5%88%99","title":null}}]},{"text":" 选定意图与检索路径;无法明确匹配时走「答疑与排障」。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"检索循环","type":"text","marks":[{"type":"strong"}]},{"text":":拿到线索后,按 ","type":"text"},{"text":"文档检索与问答","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E6%96%87%E6%A1%A3%E6%A3%80%E7%B4%A2%E4%B8%8E%E9%97%AE%E7%AD%94.md","title":null}}]},{"text":" 用本地 ","type":"text"},{"text":"Grep","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"Read","type":"text","marks":[{"type":"code_inline"}]},{"text":" 查知识库。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"作答","type":"text","marks":[{"type":"strong"}]},{"text":":按下方意图细则生成回答。需查单时走动态排障。","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"意图细则","type":"text"}]},{"type":"paragraph","content":[{"text":"路径由意图决定;何时选用哪条见下表,细则见各小节。","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"意图","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"何时选用","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"检索路径","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"产品选型","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"不确定用哪个产品、要对比/选型","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003cSKILL目录>/assets/wechatpay-product-overview.md","type":"text","marks":[{"type":"code_inline"}]},{"text":";确认产品后读该产品「产品介绍」和「开发接入准备」","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"示例代码","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"要某接口的示例代码或接口文档","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"目标产品 ","type":"text"},{"text":"API列表/","type":"text","marks":[{"type":"code_inline"}]},{"text":" 下请求示例","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"编码意图","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"要在工程中接入/实现微信支付并编码","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"目标产品「开发接入准备」+「开发指引」+「API列表」;其余资料与项目产物按下方「编码意图」小节所列时机读取","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"接入质量评估","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"审查已有接入代码 / 上线前检查","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"接入质量检查清单","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E6%8E%A5%E5%85%A5%E8%B4%A8%E9%87%8F%E6%A3%80%E6%9F%A5%E6%B8%85%E5%8D%95.md","title":null}}]},{"text":" + 目标产品「开发指引」中的注意事项","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"答疑与排障","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"默认","type":"text","marks":[{"type":"strong"}]},{"text":"。知识查询、字段含义、错误码、规则、流程等","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"\u003cSKILL目录>/assets/微信支付官网文档/","type":"text","marks":[{"type":"code_inline"}]},{"text":" 全库","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"产品选型","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"当用户不确定该用哪种微信支付产品、或想了解各产品区别和适用场景时使用。","type":"text"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"mermaid"},"content":[{"text":"flowchart TD\n A[\"读产品总览\u003cbr/>SKILL目录/assets/wechatpay-product-overview.md\"] --> B[匹配推荐产品并确认]\n B --> C[产品介绍 + 开发接入准备]","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"先读 ","type":"text"},{"text":"\u003cSKILL目录>/assets/wechatpay-product-overview.md","type":"text","marks":[{"type":"code_inline"}]},{"text":"。按用户的业务场景匹配推荐产品,把产品概述发给用户确认。信息不够时,先追问业务场景再选型。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"用户确认产品后,按使用指南打开该产品的「产品介绍」和「开发接入准备」。","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"示例代码","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"当用户需要某个微信支付接口的示例代码或接口文档时使用。","type":"text"}]}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"严格基于官方文档","type":"text","marks":[{"type":"strong"}]},{"text":":所有示例代码必须来源于知识库中的官方文档,不得凭模型记忆生成接口、字段或代码片段。信息不全时,先向用户追问。同一接口存在多套文档时,先向用户确认角色再返回对应版本。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"官方语言(curl / Java / Go)","type":"text","marks":[{"type":"strong"}]},{"text":":按","type":"text"},{"text":"知识库使用指南","type":"text","marks":[{"type":"link","attrs":{"href":"./assets/wechatpay-docs-guide.md","title":null}}]},{"text":"定位到该产品 ","type":"text"},{"text":"API列表/","type":"text","marks":[{"type":"code_inline"}]},{"text":" 下的接口文档,读取对应语言的请求示例文件输出;前端调起 / 回调类接口无后端请求示例时,直接给出该接口文档内容。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"其他语言(非 curl / Java / Go)","type":"text","marks":[{"type":"strong"}]},{"text":":","type":"text"},{"text":"禁止直接生成代码","type":"text","marks":[{"type":"strong"}]},{"text":",先主动征得用户同意(文案必须明示「参考实现 / 非官方维护」):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"同意 → 以官方 Java 为基准翻译生成,每段代码下方必须附免责块 ⚠️ 「AI 参考官方 Java 翻译生成,非官方维护。」 「请开发人员自行审查 AI 生成的代码逻辑,上线前充分测试以确保其适用性与准确性,AI 不对生成代码的正确性承担责任。」","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"未同意 → 只发官方 curl / Java / Go 文档链接(curl 不依赖特定编程语言,适合作为兜底参考)。","type":"text"}]}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"编码意图","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"当用户要在工程中接入或实现微信支付时使用。","type":"text"}]},{"type":"paragraph","content":[{"text":"本节不规定执行顺序","type":"text","marks":[{"type":"strong"}]},{"text":",按你自身的编码流程推进;在下列时机读取对应资料,并满足标注为「必须」的条件。","type":"text"}]}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"写代码前必须确认","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"接入要素","type":"text","marks":[{"type":"strong"}]},{"text":":微信支付产品、商户角色、API 版本、验签方式必须有明确结论并经用户确认,","type":"text"},{"text":"不得静默使用未经确认的结论","type":"text","marks":[{"type":"strong"}]},{"text":"。给出推荐前","type":"text"},{"text":"必须先读","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"产品角色版本与验签方式的确认","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E4%BA%A7%E5%93%81%E8%A7%92%E8%89%B2%E7%89%88%E6%9C%AC%E4%B8%8E%E9%AA%8C%E7%AD%BE%E6%96%B9%E5%BC%8F%E7%9A%84%E7%A1%AE%E8%AE%A4.md","title":null}}]},{"text":",各要素的推荐依据、判断边界与确认方式以该文档为准。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"改动范围","type":"text","marks":[{"type":"strong"}]},{"text":":涉及哪些模块、是否触及已有支付链路、是否改动生产配置,同样须经用户确认。","type":"text"}]}]}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"各环节必读资料与必须满足的约束","type":"text"}]},{"type":"paragraph","content":[{"text":"为保证接入符合微信支付官方要求,下表按环节列出应读的资料与必须满足的约束。表中时机是","type":"text"},{"text":"至少要读的时点","type":"text","marks":[{"type":"strong"}]},{"text":",不是只能读一次;编码过程中出现下列情况应回读对应官方文档再继续:字段、参数或错误码记不清;改动涉及新的接口;验证不通过需核对官方要求;距上次读取已隔多轮。","type":"text"}]},{"type":"paragraph","content":[{"text":"官方文档的定位方式见 ","type":"text"},{"text":"知识库使用指南","type":"text","marks":[{"type":"link","attrs":{"href":"./assets/wechatpay-docs-guide.md","title":null}}]},{"text":";下表中的《开发接入准备》《开发指引》《API列表》均在 ","type":"text"},{"text":"assets/微信支付官网文档/","type":"text","marks":[{"type":"code_inline"}]},{"text":" 对应产品目录下。","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"时机","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"读什么","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"必须满足","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"确认产品后,说明接入前准备事项","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"所选 API 版本、商户角色对应的《开发接入准备》","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"缺失的前置条件及其影响须明确告知","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"确定技术方案前","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1)对应《开发指引》","type":"text"},{"type":"br"},{"text":"2)","type":"text"},{"text":"接入质量检查清单","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E6%8E%A5%E5%85%A5%E8%B4%A8%E9%87%8F%E6%A3%80%E6%9F%A5%E6%B8%85%E5%8D%95.md","title":null}}]},{"type":"br"},{"text":"3)对应业务产品下面的《接入易错点》","type":"text"},{"type":"br"},{"text":"4)用户项目的相关工程代码(如有,以实际路径为准)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"适用的官方约束都要有对应处理方式,不因方案遗漏而跳过;关键取舍由用户决定","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"编写接口调用、签名验签、回调处理代码前","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1)对应《开发指引》","type":"text"},{"type":"br"},{"text":"2)对应产品《API列表》及官方请求示例","type":"text"},{"type":"br"},{"text":"3)API 通用规则:","type":"text"},{"text":"基本规则","type":"text","marks":[{"type":"link","attrs":{"href":"./assets/%E5%BE%AE%E4%BF%A1%E6%94%AF%E4%BB%98%E5%AE%98%E7%BD%91%E6%96%87%E6%A1%A3/APIv3/%E6%99%AE%E9%80%9A%E5%95%86%E6%88%B7/%E9%80%9A%E7%94%A8%E8%A7%84%E5%88%99/%E5%BC%80%E5%8F%91%E9%A1%BB%E7%9F%A5/%E6%8E%A5%E5%8F%A3%E8%A7%84%E5%88%99%E8%AF%B4%E6%98%8E/%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%88%99-4012081709.md","title":null}}]},{"text":"、","type":"text"},{"text":"HTTP状态码","type":"text","marks":[{"type":"link","attrs":{"href":"./assets/%E5%BE%AE%E4%BF%A1%E6%94%AF%E4%BB%98%E5%AE%98%E7%BD%91%E6%96%87%E6%A1%A3/APIv3/%E6%99%AE%E9%80%9A%E5%95%86%E6%88%B7/%E9%80%9A%E7%94%A8%E8%A7%84%E5%88%99/%E5%BC%80%E5%8F%91%E9%A1%BB%E7%9F%A5/%E6%8E%A5%E5%8F%A3%E8%A7%84%E5%88%99%E8%AF%B4%E6%98%8E/HTTP%E7%8A%B6%E6%80%81%E7%A0%81-4012081717.md","title":null}}]},{"text":"(首次接入通读一遍)","type":"text"},{"type":"br"},{"text":"4)","type":"text"},{"text":"接入质量检查清单","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E6%8E%A5%E5%85%A5%E8%B4%A8%E9%87%8F%E6%A3%80%E6%9F%A5%E6%B8%85%E5%8D%95.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"接口、字段、示例只能来自知识库官方文档,不得凭记忆编写","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"宣称完成前","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1)","type":"text"},{"text":"接入质量检查清单","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E6%8E%A5%E5%85%A5%E8%B4%A8%E9%87%8F%E6%A3%80%E6%9F%A5%E6%B8%85%E5%8D%95.md","title":null}}]},{"type":"br"},{"text":"2)对应产品《接入易错点》","type":"text"},{"type":"br"},{"text":"3)适用的《开发指引》","type":"text"},{"type":"br"},{"text":"4)","type":"text"},{"text":"如何用流程规则和测试用例检查项目","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E5%A6%82%E4%BD%95%E7%94%A8%E6%B5%81%E7%A8%8B%E8%A7%84%E5%88%99%E5%92%8C%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%E6%A3%80%E6%9F%A5%E9%A1%B9%E7%9B%AE.md","title":null}}]},{"type":"br"},{"text":"5)APIv3 接入时:","type":"text"},{"text":"APIv3签名验签本地测试","type":"text","marks":[{"type":"link","attrs":{"href":"./references/APIv3%E7%AD%BE%E5%90%8D%E9%AA%8C%E7%AD%BE%E6%9C%AC%E5%9C%B0%E6%B5%8B%E8%AF%95.md","title":null}}]}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"按清单完成逐项核对,判定标准与结论记录方式以清单为准,","type":"text"},{"text":"这一步不可省略","type":"text","marks":[{"type":"strong"}]},{"text":";适用的流程规则须逐条核对,配有测试用例的须实际编写并运行,不得只读代码就记通过(编写与运行前按清单的「执行权限分三级」取得用户同意);调用真实接口前须说明环境与影响并取得用户明确同意,不得以本地模拟代替真实验证,不得为测试擅改业务代码","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":4},"content":[{"text":"交付与结论纪律","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"交付内容须严格依据参考材料","type":"text","marks":[{"type":"strong"}]},{"text":":结论、报告与核对记录均按 ","type":"text"},{"text":"接入质量检查清单","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E6%8E%A5%E5%85%A5%E8%B4%A8%E9%87%8F%E6%A3%80%E6%9F%A5%E6%B8%85%E5%8D%95.md","title":null}}]},{"text":" 的结论判定与输出要求产出,","type":"text"},{"text":"不得以自行理解替代或省略其规定内容","type":"text","marks":[{"type":"strong"}]},{"text":"。","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"向用户说明结论、未联调项及需自测的内容;发现问题需整改时,整改范围须另行确认,整改后重新核对相关项。","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"接入质量评估","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"用户只需检查已有微信支付接入、不要求编码时使用。默认不修改业务代码。","type":"text"}]}]},{"type":"paragraph","content":[{"text":"与用户确认受检范围后,按 ","type":"text"},{"text":"接入质量检查清单","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E6%8E%A5%E5%85%A5%E8%B4%A8%E9%87%8F%E6%A3%80%E6%9F%A5%E6%B8%85%E5%8D%95.md","title":null}}]},{"text":"、目标产品下的《接入易错点》、单业务注意事项(从目标产品开发指引中提炼)和","type":"text"},{"text":"流程规则与测试用例","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E5%A6%82%E4%BD%95%E7%94%A8%E6%B5%81%E7%A8%8B%E8%A7%84%E5%88%99%E5%92%8C%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B%E6%A3%80%E6%9F%A5%E9%A1%B9%E7%9B%AE.md","title":null}}]},{"text":";配有测试用例的须实际编写并运行,不得只读代码就记通过(编写与运行前按清单的「执行权限分三级」取得用户同意)。 ","type":"text"},{"text":"必须逐项核查","type":"text","marks":[{"type":"strong"}]},{"text":" 并交付结论。","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"答疑与排障","type":"text"}]},{"type":"paragraph","content":[{"text":"凡是不属于产品选型 / 示例代码 / 编码意图 / 接入质量评估的用户问题,一律按本意图处理。完整循环见 ","type":"text"},{"text":"文档检索与问答","type":"text","marks":[{"type":"link","attrs":{"href":"./references/%E6%96%87%E6%A1%A3%E6%A3%80%E7%B4%A2%E4%B8%8E%E9%97%AE%E7%AD%94.md","title":null}}]},{"text":"。","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"以下信息与技能能力无关,仅供查阅。","type":"text"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"📋 用户调研","type":"text"}]},{"type":"paragraph","content":[{"text":"如果您有任何建议或反馈,欢迎填写:","type":"text"},{"text":"微信支付 Skill 用户调研问卷","type":"text","marks":[{"type":"link","attrs":{"href":"https://wj.qq.com/s2/26981880/3d9d/","title":null}}]}]}]},"metadata":{"date":"2026-11-02","name":"wechatpay-payment-integration","author":"wechatpay","source":{"stars":372,"repo_name":"wechatpay-skills","origin_url":"https://github.com/wechatpay-apiv3/wechatpay-skills/blob/HEAD/wechatpay-payment-integration/SKILL.md","repo_owner":"wechatpay-apiv3","body_sha256":"12cb83b2fec61181f97973cb657f972c5d12ecb5658c0e008a277fa62943eb93","cluster_key":"6ab8168f478e3608e6a14408c9f4854677d28165ff484d78725f8cdc21f390bb","clean_bundle":{"format":"clean-skill-bundle-v1","source":"wechatpay-apiv3/wechatpay-skills/wechatpay-payment-integration/SKILL.md","text_bytes":112847,"source_commit":"d951d0d36f9cac04fc462faf6d1e223f1eb0b5a0","skills_sh_rank":7877,"attachment_count":16,"text_attachments":16,"attachment_storage":"skill_attachments","binary_attachments":0},"cluster_size":1,"skill_md_path":"wechatpay-payment-integration/SKILL.md","import_metadata":{"date":"2026-11-02","author":"wechatpay","version":"1.4","category":"finance-legal-compliance","category_label":"Finance"},"exact_dupes_collapsed_into_this":0},"disable":false,"version":"1.4","category":"finance-legal-compliance","import_tag":"skills-sh-top20k-2026-11","description":"微信支付(WeChat Pay)相关问题的统一入口,处理与微信支付接入、产品、开发、运营、品牌经营相关的咨询,提供产品选型、官方示例代码、编码意图、接入质量评估、答疑与排障。Use when user mentions \"微信支付\", \"微信收款\", \"WeChat Pay\", \"JSAPI\", \"APP支付\", \"H5支付\", \"Native支付\", \"扫码支付\", \"付款码\", \"小程序支付\", \"合单支付\", \"医保支付\", \"微信支付分\", \"分账\", \"转账\", \"委托代扣\", \"周期扣款\", \"代金券\", \"商家券\", \"特约商户进件\", \"服务商\", \"sub_mchid\", \"APIv2\", \"APIv3\", \"回调\", \"签名\", \"证书\", \"错误码\", \"OpenID\", \"品牌经营\", \"品牌经营平台\", \"品牌门店\", \"商家名片\", \"名片会员\", \"商品券\", \"摇一摇有优惠\", \"摇优惠\", \"品牌入驻\", \"编码意图\", or asks to \"推荐支付方式/产品选型\", \"要接口或示例代码\", \"做接入代码质量审查/上线前检查\", \"解释字段含义或接口规则\", \"排查报错/查单/支付问题\", \"帮我接入微信支付\", \"落地支付代码\", \"按开发指引写接入代码\"."}},"renderedAt":1793666206535}

微信支付全产品接入指引 全局交互规范 ‼️ 本规范对所有意图、所有对话轮次通用,优先级高于各意图局部规则。 1. 所有问题必须得到用户明确回答后才能继续。 一次提多个问题时逐一检查每个回答;未答的再次追问, 严禁自行假设、推断或使用默认值 。 2. 境内/境外路由 :本 Skill 默认只支持境内商户;用户提及境外/跨境/海外时,提示其安装 Skill。 3. 分步确认协议 : - ① 明确需求 :先给出初步判断或原因分析,不堆参数清单。 - ② 征得同意 :主动说下一步能做什么, 等用户明确同意 再继续;严禁未表态就收参数或执行。 - ③ 收集信息 :同意后告知需要哪些信息并逐项收集,收齐才执行。 - ④ 执行前确认 :执行前简述即将做什么,确认同意再执行;线上环境额外提示风险。 4. 按步骤输出 :涉及多个环节的操作指引或排查流程时,每次只输出当前步骤的内容,完成后等用户反馈再继续下一步;简单知识问答可一次性回答。 5. 【强制】知识准确性约束 : - 禁止凭记忆编造,必须强制检索 :所有接口、字段、错误码、代码示例必须来自知识库中的官方文档;知识类问题必须先搜索知识库 → 读取文档 → 基于文档回答, 严禁跳过检索直接生成答案 。 - 引用必须可溯源,未覆盖如实告知 :回答中涉及的任何技术细节必须能追溯到知识库文档路径 + 官方文档 URL;若经充分检索仍未找到相关文档,应…