目前微信支付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加密
本文章主要协助开发者定位重复接收到微信支付回调的问题,开发者可根据以下步骤逐步排查。
情况一、HTTP应答状态码不正确
商户应答不规范时,该情况微信会判定本次通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。商户需要按照以下说明做规范应答。
V2版本:
接收成功时:
<xml>
<return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
</xml>
接收失败时:
<xml>
<return_code><![CDATA[FAIL]]></return_code>
<return_msg><![CDATA[验签不通过,处理失败]]></return_msg>
</xml>
V3版本:
接收成功时:HTTP应答状态码需返回200或204,无需返回应答报文。
接收失败时:HTTP应答状态码需返回5XX或4XX,同时需返回应答报文,格式如下:
{ "code": "FAIL", "message": "失败" }
情况二、商户应答超时
商户在收到微信支付的通知时未在3S内处理并完成应答,此种情况下,微信侧会认为超时响应,并会通过一定的策略定期重新发起通知。
情况三、微信侧重复发起通知
3.1、微信侧同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。 推荐的做法是,当商户系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。如果未处理,则再进行处理;如果已处理,则直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。
3.2、如果在所有通知频率后没有收到微信侧回调,商户应调用查询订单接口确认订单状态。
情况四、此次回调为微信的签名探测流量
为了确保商户系统的安全,微信支付会在极少数应答或通知回调中生成错误签名,以探测商户系统是否正确地验证了签名。
商户系统不应对探测流量进行特殊处理,而应将其视为正常的应答或通知回调,并对其签名进行验证。 在排查问题时,您可以通过查看签名值中的 WECHATPAY/SIGNTEST/ 前缀快速判断是否为探测流量。所有用于探测目的的签名值都会包含此前缀。
在验签失败的情况下,我们建议商户系统采取以下措施:
- 如果应答的签名验证失败,商户系统应舍弃该应答。为了提高用户体验,商户系统可以适当地重试,或者让用户重新发起请求。微信支付不会针对重试请求发起探测。
- 若通知回调的签名验证失败,商户系统应返回失败(即应答 4xx 或 5xx 的状态码),等待微信支付携带正确签名重新发送通知回调。
good.