微信支付(商户 APIv3) Skill
覆盖直连商户的 JSAPI、小程序、Native、H5、APP 下单,以及查单关单、退款、回调和账单。重点讲清楚按 v2 经验必然写错的几件事:RSA 请求签名、微信支付公钥验签、AES-GCM 回调解密。
安装
选你用的 Agent,复制命令。
npx -y skills add fxp/skillify --skill wechatpay --agent claude-code --yes装到项目的 .claude/skills/;加 -g 装到全局。装完需要你手动执行 /reload-plugins,这一步 Agent 代劳不了。
npx -y skills add fxp/skillify --skill wechatpay --agent codex --yes装到项目的 .agents/skills/;加 -g 装到全局。
npx -y skills add fxp/skillify --skill wechatpay --agent cursor --yes装到项目的 .agents/skills/;加 -g 装到全局。
npx -y skills add fxp/skillify --skill wechatpay --agent opencode --yes装到项目的 .agents/skills/;加 -g 装到全局。
npx -y skills add fxp/skillify --skill wechatpay --agent gemini-cli --yes装到项目的 .agents/skills/;加 -g 装到全局。
npx -y skills add fxp/skillify --skill wechatpay --agent github-copilot --yes装到项目的 .agents/skills/;加 -g 装到全局。
npx -y skills add fxp/skillify --skill wechatpay --agent trae --yes装到项目的 .trae/skills/;加 -g 装到全局。
npx -y skills add fxp/skillify --skill wechatpay --agent windsurf --yes装到项目的 .windsurf/skills/;加 -g 装到全局。
npx -y skills add fxp/skillify --skill wechatpay --agent qwen-code --yes把 --agent 换成你用的 Agent 标识,可以一次写多个。skills CLI 1.5.25 共支持 79 个,例如 qwen-code、kimi-code-cli、trae-cn、qoder、lingma、cline、roo。
或者让 Agent 自己装
读 https://github.com/fxp/skillify/blob/main/skills/wechatpay/prompt.md 并照它执行装对了的标志:references/ 下有 7 份文档,里面 grep '<!-- Gap:' 能搜到 2 处。
装好后,可以这样问你的 Agent
这份 Skill 覆盖的典型任务。点一下复制。
7 类能力
每类能力对应一份 reference,Agent 按任务只打开需要的那份。
签名与验签
Authorization 头、5 行签名串、在微信支付公钥和平台证书之间选择、敏感字段 RSA-OAEP 加密;另附用文档测试向量离线复算的结果
下单与调起支付
五种产品怎么选、下单参数、JSAPI / 小程序 / APP 调起签名、H5 与 Native 的注意事项
查单与关单
订单状态机、两种查单方式、关单返回 204、没收到回调时的轮询方案
退款
申请退款、查询退款、异常退款、退款状态机,以及唯一安全的重试写法
回调通知
支付成功和退款结果回调:验签、AEAD_AES_256_GCM 解密、应答规则、重试节奏、IP 白名单
账单与对账
交易账单和资金账单的申请、带签名下载、SHA1 校验、CSV 解析,以及元和分的换算
错误码与重试
HTTP 状态码、业务错误码总表、能否重试的决策表、频率限制、v2 与 v3 错误模型的区别
当前事实
整理自官方文档(抓取于 2026-09-11),还没有用真实凭证验证。
| 项 | 值 |
|---|---|
| Base URL | https://api.mch.weixin.qq.com(备用 api2),路径都在 /v3/ 下,没有沙箱 |
| 请求鉴权 | Authorization: WECHATPAY2-SHA256-RSA2048 mchid=…,nonce_str=…,signature=…,timestamp=…,serial_no=…,签名串共 5 行 |
| 验签 | 根据 Wechatpay-Serial 选择微信支付公钥(PUB_KEY_ID_…)或平台证书,时间戳偏差不超过 ±5 分钟 |
| 金额 | 整数分(100 就是 1 元);账单文件里的金额是元 |
| 回调解密 | AEAD_AES_256_GCM,key 是 32 字符的 APIv3 密钥,nonce 和 associated_data 都用原串 |
照通用经验写容易错的 6 件事
来自官方文档,还没有用真实凭证验证。
- 签名用的 body 必须和发出去的字节完全一样。先序列化成字符串再签名、再发送;GET 请求的
?mchid=…也要算进签名串。 serial_no和Wechatpay-Serial对应的是两套不同的密钥。前者是商户 API 证书序列号,后者是微信支付公钥 ID 或平台证书序列号。- 调起支付要后端再签一次名,三端格式不一样。JSAPI 和小程序签
prepay_id=xxx;APP 只签 prepay_id 本身,并且要传Sign=WXPay。 - 回调的顺序:先用原始 body 验签,再解密,5 秒内回 200 或 204(不带 body)。不要回 v2 的 XML;微信支付会故意发
WECHATPAY/SIGNTEST/开头的错误签名来做探测。 - 退款超时时,先查询再重试,永远用原来的
out_refund_no。如果没传notify_url,可能会收到 v2 XML 格式的退款通知。 - v2 和 v3 不能混用。v2 失败时也返回 HTTP 200 加 XML 的
return_code=FAIL;v3 用 HTTP 4xx 加 JSON 的code。
无凭证探测
- 不带 Authorization:返回 401
SIGN_ERROR,而交易类接口和其他接口的 message 不一样 - 去掉 User-Agent:
/v3/certificates、/v3/refund/*直接返回 400INVALID_REQUEST(先于鉴权);交易类/v3/pay/transactions/*去掉 UA 仍返回 401,所以一律带上 UA - 时间戳偏差超过 5 分钟:返回 401,而且这个检查在签名校验之前
- 4xx 应答不带任何
Wechatpay-*签名头;交易类接口的 401 连Request-ID都没有 - 备用域名
api2可用;不存在的路径返回 404、请求方法错误返回 405,body 都是空的 - v2 接口失败时也返回 HTTP 200,body 是 XML 的
return_code=FAIL