目前微信支付API v2 版本的SDK已停止维护,为了在保证支付安全的前提下,带给商户简单、一致且易用的开发体验,微信支付官方推出了全新的微信支付API v3。并且提供了Java、php、go语言的相关业务SDK,该SDK已支持回调验签,接收解析回调通知的功能,若你有SDK需求,建议使用API v3版本,根据自己的需要选择对应的SDK使用,具体可参考:微信支付APIv3 SDK 介绍
V2版接口和V3版接口规则差异说明:
- 参数格式:V2接口为XML,V3接口为JSON
- 签名方式:V2接口为MD5或HMAC-SHA256,V3接口为非对称密钥SHA256-RSA
- 回调加密:V2接口无需加密,V3接口为AES-256-GCM加密
本文章主要协助开发者定位接收不到微信支付回调的问题,开发者可根据以下步骤逐步排查。
V2版本排查步骤:
情况一、使用了错误的密钥
V2版本的应答和回调的签名验证使用的是 APIv2密钥,不是APIv3密钥。使用了错误的APIv2密钥或使用了APIv3密钥是验证不过的。APIv2密钥设置路径:微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全-->设置API密钥
情况二、验证签名时的参数不正确
验证返回或回调签名验证时,微信返回的sign参数不需要参与签名。
注意:微信接口可能增加字段,建议商户在处理验证签名时必须支持增加的扩展字段,避免后续微信支付有新增字段导致商户验签不过。
情况三、验证签名时的顺序不正确
需要将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序)
V3版本排查步骤:
情况一、使用了错误的证书信息
V3版本的应答和回调的签名验证使用的是 微信支付平台证书,不是商户API证书。使用商户API证书是验证不过的。微信支付的平台证书序列号位于HTTP头Wechatpay-Serial。验证签名前,请商户先检查序列号是否跟商户当前所持有的微信支付平台证书的序列号一致。如果不一致,请重新获取证书。否则,签名的私钥和证书不匹配,将无法成功验证签名。
获取平台证书有两种方式:
1、可通过微信支付平台证书下载工具下载
2、通过获取平台证书列表接口下载
情况二、构造的验证签名串不正确
首先需要从应答或通知回调中获取以下信息:
2.1、HTTP 头 Wechatpay-Timestamp 中的应答时间戳
2.2、HTTP 头 Wechatpay-Nonce 中的应答随机串
2.3、应答报文主体(Response Body),请使用原始报文主体执行验签。如果您使用了某个框架,要确保它不会篡改报文主体。对报文主体的任何篡改都会导致验证失败。
然后,请按照以下规则构造应答的验签名串。签名串共有三行,行尾以 \n 结束,包括最后一行。\n 为换行符(ASCII 编码值为 0x0A)。若应答报文主体为空(如 HTTP 状态码为 204 No Content),最后一行仅为一个 \n 换行符。
正确的格式示例:
情况三、应答主体(response Body)顺序不正确
应答主体(response Body),需要按照微信支付应答中的应答报文主体顺序进行验签,错误的顺序将导致验签失败
情况四、此次回调为微信的签名探测流量
为了确保商户系统的安全,微信支付会在极少数应答或通知回调中生成错误签名,以探测商户系统是否正确地验证了签名。
商户系统不应对探测流量进行特殊处理,而应将其视为正常的应答或通知回调,并对其签名进行验证。 在排查问题时,您可以通过查看签名值中的 WECHATPAY/SIGNTEST/ 前缀快速判断是否为探测流量。所有用于探测目的的签名值都会包含此前缀。
在验签失败的情况下,我们建议商户系统采取以下措施:
- 如果应答的签名验证失败,商户系统应舍弃该应答。为了提高用户体验,商户系统可以适当地重试,或者让用户重新发起请求。微信支付不会针对重试请求发起探测。
- 若通知回调的签名验证失败,商户系统应返回失败(即应答 4xx 或 5xx 的状态码),等待微信支付携带正确签名重新发送通知回调。
附录
- 微信支付API v3 SDK介绍
- 重复收到回调问题排查指引
- 回调解密失败问题排查指引
- 接收不到回调问题排查指引
- 支付回调和查单实现指引及注意事项说明
- 微信支付平台证书下载工具
- 获取平台证书列表接口
- V2版本签名验证规则介绍
- V3版本签名验证规则介绍