微信支付平台证书切换公钥:回调七天灰度,应答比例卡在 0% 的原因
微信支付 APIv3 支持两种签名验签模式:平台证书、微信支付公钥。平台证书有效期 5 年,每 5 年需要商户主动更换一次;为了避开更换不及时或过程中的系统风险,可以把商户号从平台证书模式切换为微信支付公钥模式。
官方文档:
切换流程
第一步:请求头带上公钥 ID
在 HTTP 请求中增加 Wechatpay-Serial 请求头,告诉微信支付本次请求使用微信支付公钥验签,值为公钥 ID。公钥 ID 带 PUB_KEY_ID_ 前缀。
curl -X GET https://api.mch.weixin.qq.com/v3/xxx \
-H "Authorization: WECHATPAY2-SHA256-RSA2048 mchid=\"1900000001\",..." \
-H "Accept: application/json" \
-H "Wechatpay-Serial: PUB_KEY_ID_00000000000000000000000000000000"
第二步:验签方式
微信支付收到带公钥 ID 的请求头后,会用微信支付私钥生成签名,商户需要用对应的微信支付公钥验证签名。
第三步:回调按 Wechatpay-Serial 分流
回调场景下,微信支付会按比例使用微信支付私钥或平台证书生成签名发送回调。因此回调侧必须按回调请求头 Wechatpay-Serial 判断本次用平台证书验签还是微信支付公钥验签,不能只实现一种。
回调灰度:由微信支付控制,七天到全量
回调使用公钥的比例由微信支付自动灰度,商户不可操作:
| 天数 | 比例 |
|---|---|
| 第 1 天 | 0.1% |
| 第 2 天 | 1% |
| 第 3 天 | 5% |
| 第 4 天 | 10% |
| 第 5 天 | 20% |
| 第 6 天 | 50% |
| 第 7 天 | 100% |
灰度期间,按比例使用公钥签名,剩余比例仍用平台证书签名,所以按 wechatpay-serial 头判断是硬性要求。
应答比例:由商户请求头控制
应答使用公钥比例的计算方式:
近 7 天用微信支付公钥调接口次数 / 近 7 天 v3 接口总调用次数
数据更新频率是 1 小时。全量切到公钥后还需要再等 7 天,比例才会到 100%。
应答比例由商户自己通过请求头 Wechatpay-Serial 控制——请求带了公钥 ID,这次调用才计入分子。
确认切换
当所有业务场景的请求都已带公钥 ID,且回调七天灰度完成后,商户平台上的【回调使用公钥比例】和【应答使用公钥比例】都会显示 100%。确认业务覆盖完整,点击「确认切换」,变更完成。
确认切换后,除敏感字段加解密场景外,回调与应答的 HTTP 请求头可以不携带 Wechatpay-Serial,微信支付默认使用微信支付私钥签名。
常见坑
回调进度 100% 但应答还是 0%
应答比例由商户请求头控制。确认请求都加了 Wechatpay-Serial 且正确传入公钥 ID(带 PUB_KEY_ID_ 前缀)。
已全部切到公钥,但应答进度不是 100%
两种情况:
- 数据按 1 小时更新,且全量切换后还需等 7 天。
- 官方
wechatpay-java中的RSACombinedNotificationConfig会自动调用下载平台证书接口。回调比例到 100% 时应改为RSAPublicKeyNotificationConfig,否则自动下载平台证书的流量会让应答比例到不了 100%。
公钥怎么获取
商户平台 → 账户中心 → API安全 → 微信支付公钥 → 管理公钥,可下载 pem 文件并查询公钥 ID。
不能和其他流程并行
平台证书切换微信支付公钥,和更换平台证书的流程不能同时进行,需要先停止新平台证书的灰度更换。
传了公钥 ID,应答仍用平台证书
申请公钥后默认不开启公钥切换,需要在商户平台点击「开启公钥切换」按钮后才可用。
切换粒度
以商户号为单位,有多个商户号的需要分别完成。
Source: https://pay.wechatpay.cn/doc/v3/merchant/4012154180 and https://pay.wechatpay.cn/doc/v3/merchant/4013038816