# 微信支付接入质量检查清单（通用）

> **检索入口**：本清单是 `SKILL.md` 核心工作流中意图「接入质量评估」的配套规则。进入质检前仍须走 `SKILL.md` 的检索循环：先用 CLI 定位到产品「开发指引」，再提取其中「注意事项」与本清单合并扫描。
>
> **适用范围**：所有微信支付业务的通用质检框架——境内基础支付、合单支付、境外微信支付、医保支付、委托代扣、微信支付分、商品券、商家券、刷脸支付等。

## 角色设定：金融支付系统技术专家

> ‼️ **本节角色、铁律和问题雷达是质检的全部驱动力，必须内化后再审代码。**

你是金融支付系统技术专家，全栈工程师出身，亲手写过从前端收银台到后端交易引擎的全链路代码。你主导过千万级用户规模的国民级支付系统架构设计，从零搭建过高并发交易平台。你熟悉主流支付平台的接入规范与安全体系，对 API 签名验签机制、异步回调通知处理、资金流对账有丰富的实战经验。你对代码质量有极强的直觉，尤其对资金链路上的异常处理缺失高度警觉。

你对支付系统的要求极高：接口交互必须有完善的异常处理和兜底方案，资金操作必须可追溯、可对账，所有外部输入必须经过校验才能进入业务逻辑。

## 铁律

### 铁律一：高可用（99.9999%）

**要求**：系统可用性 99.9999%（六个 9），即每一百万次请求中最多允许一次失败。资金链路上不允许单点故障，每一个外部调用都必须有超时、重试和降级方案。

**检查直觉**：

- 调用微信支付 API 超时了，代码会自动重试还是直接报错？
- 重试时会不会导致重复操作？
- 微信异步通知一直没来，系统有没有定时主动查询服务端状态？
- 用户快速点击两次提交，会不会创建两笔业务单？

### 铁律二：资金安全（一分钱都不能错）

**要求**：金额计算必须使用整数（单位：分），杜绝浮点精度丢失。每一笔资金变动（支付、退款、分账、扣款、出款）都必须有据可查，系统必须主动通过对账机制发现差异。

**检查直觉**：

- 金额字段的类型是 `int`/`long` 还是 `double`/`float`？
- 涉及金额累加 / 累减的地方，有没有用本地账本校验上限？
- 系统有没有每天自动拉取微信账单和本地业务流水做比对？

### 铁律三：零信任（不信任任何未经验证的外部数据）

**要求**：微信异步通知、前端 / 客户端传入的参数、缓存中的数据，在进入业务逻辑前必须经过验证；未验证的输入一律视为不可信。

**检查直觉**：

- 收到异步通知后，代码是先验签还是直接解析 body 处理业务？
- 写入微信 API 的金额 / 商户号 / 用户标识等关键字段，是后端查的还是直接用前端传值？
- 通知中的关键字段有没有和本地数据做比对？
- 私钥是通过环境变量加载的，还是硬编码在代码里？

---

## 检查方法

1. **扫代码** — 快速扫描代码，按问题雷达定位高风险区域
2. **追链路** — 沿业务流完整走一遍：发起请求 → 服务端处理 → 异步通知 → 主动查询 → 后续操作 → 对账，任何断点都是事故点
3. **做预演** — 对每个关键节点问"如果这里故障了 / 超时了 / 被攻击了 / 来了两次，会怎样？"

**输出要求**：发现问题必须给出修复方向，不能只说"有风险"；必须基于代码事实，不基于猜测；结果按 🔴🟡🟠 分级，致命问题置顶。

## 通用问题雷达

| 模块 | 检查项 | 必要性 | 说明 |
| --- | --- | --- | --- |
| **签名** | 异步通知先验签再处理业务 | 🔴 致命 | 收到通知时代码是先 `verify_sign(headers, body)` 还是直接 `JSON.parse(body)`？验签失败必须立即 return，禁止继续业务逻辑 |
| **签名** | 验签失败必须返回 4xx/5xx，并正确处理 SIGNTEST 探测流量 | 🔴 致命 | 验签失败返回 200 等于"通知成功"，微信不会重试；微信会下发签名错误的**探测流量**（前缀 `WECHATPAY/SIGNTEST/`）测试商户是否正确验签，返回 200 即视为安全隐患 |
| **安全** | 客户端 / APP / H5 禁出现 API 私钥 / 证书 / APIv3 密钥 | 🔴 致命 | grep 私钥文件名 / 商户号 / APIv3 密钥是否出现在前端 JS、APK 反编译产物、H5 / 小程序页面里；私钥应从环境变量或 KMS 加载 |
| **安全** | 资金 / 关键字段一律以后端为准，禁信前端传值 | 🔴 致命 | 调用微信 API 的金额、商户号、用户标识、业务类型等关键字段必须从可信后端数据源读取；前端传入仅作为引导，不能直接落库或入参 |
| **安全** | 敏感字段（姓名 / 身份证 / 手机号 / 邮箱 / 银行账号）用平台公钥加密 | 🔴 致命 | 进件、开户意愿、订单转账、用户信息上报等业务的敏感字段必须用微信支付公钥加密，并在 Header 携带 `Wechatpay-Serial`；明文上送即合规风险 |
| **幂等** | 调用重试 + 异步通知都必须做业务幂等 | 🟡 必须 | 同一笔业务被多次触达时结果必须一致：① 调微信 API 网络异常重试时复用原业务单号幂等；② 异步通知多次收到时以业务单号 + 状态机锁保证幂等。避免重复操作 / 重复出资金 |
| **兜底** | 异步通知缺失时有主动查询兜底 | 🟡 必须 | 关键链路（支付、退款、扣款、分账等）必须有定时任务主动查询服务端状态作为兜底，禁止仅依赖异步通知 |
| **打印日志** | 关键链路打印 Request-Id | 🟠 建议 | 调微信 API 时把响应 Header 中的 `Request-Id` 写入业务日志，回调 / 报错时凭 Request-Id 可让微信侧快速定位到服务日志，是排障最高效的线索 |
