回调通知-支付成功
通知规则
支付完成后,微信会把相关支付结果和订单信息发送给商户,商户需要接收处理该消息,并返回应答。
对后台通知交互时,如果微信收到商户的应答不符合规范或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。 (通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m)
注意:
- ● 同样的通知可能会多次发送给商户系统。商户系统必须能够正确处理重复的通知。
推荐的做法是,当商户系统收到通知进行处理时,先检查对应业务数据的状态,并判断该通知是否已经处理。如果未处理,则再进行处理;如果已处理,则直接返回结果成功。在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱。 - ● 如果在所有通知频率(4小时)后没有收到微信侧回调,商户应调用查询智慧零售订单接口确认订单状态。
特别提醒:商户系统对于支付成功结果通知的内容一定要做签名验证,并校验通知的信息是否与商户侧的信息一致,防止数据泄露导致出现“假通知”,造成资金损失。
接口链接
该链接是通过[商户配置] 提交pay_notify_url设置,必须为https协议。如果链接无法访问,商户将无法接收到微信通知。
通知url必须为直接可访问的url,不能携带参数。示例: “http://pay.weixin.qq.com/wxpay/pay.action”
通知报文
支付结果通知是以POST方法访问商户设置的通知url,通知的数据以XML格式通过请求主体(BODY)传输。通知的数据包括订单信息的详情。
出于安全考虑,对支付结果数据进行加密。商户需要先对通知数据进行解密,进而得到真正的订单信息。
下面详细描述对通知数据进行解密的流程
- 用商户平台上设置的APIv3密钥(微信商户平台(pay.weixin.qq.com)-账户设置-API安全-设置APIv3密钥),记为key
- 针对resource.algorithm中描述的算法(目前为AEAD_AES_256_GCM),取得对应的参数nonce和associated_data。
- 使用key、nonce和associated_data,对数据密文resource.ciphertext进行解密,得到XML形式的资源对象
注: AEAD_AES_256_GCM算法的接口细节,请参考rfc5116。微信支付使用的密钥key长度为32个字节,随机串nonce长度12个字节,associated_data长度小于16个字节并可能为空。
通知参数
字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
---|---|---|---|---|---|
商户号 |
mch_id |
是 |
String(32) |
|
请求商户号 |
公众账号 |
appid |
是 |
String(32) |
|
请求商户公众账号 |
通知ID |
event_id |
是 |
String(32) |
EV-2018022511223320873 |
通知的唯一ID,标识当前回调请求。 |
通知创建时间 |
event_create_time |
是 |
String(16) |
20180225112233 |
通知创建的时间,格式为yyyyMMddHHmmss,标识当前通知请求的首次通知时间。 |
通知类型 |
event_type |
是 |
String(32) |
TRANSACTION.SUCCESS |
通知的类型,支付成功通知的类型为TRANSACTION.SUCCESS;失败为 |
通知加密类型 |
event_algorithm |
是 |
String(32) |
AEAD_AES_256_GCM |
对订单信息数据进行加密的加密算法,目前只支持AEAD_AES_256_GCM |
通知随机串 |
event_nonce |
是 |
String(32) |
|
通知加密使用的随机串 |
通知附加数据 |
event_associated_data |
否 |
String(16) |
|
附加数据 |
通知密文 |
event_ ciphertext |
是 |
String(1048576) |
|
Base64编码后的订单信息密文 |
签名算法 |
algorithm |
是 |
String(16) |
HMAC-SHA256 |
请求包体签名算法,目前只支持HMAC-SHA256 |
随机串 |
nonce_str |
是 |
String(16) |
|
请求签名使用的随机串 |
签名 |
sign |
是 |
String(256) |
|
请求包体签名 |
通知签名
加密不能保证通知请求来自微信。微信会对发送给商户的通知进行签名,对整个包体根据签名算法以及随机串生成签名,目前只支持HMAC-SHA256算法。签名验证请参考“签名算法”章节
通知应答
商户后台在正确处理回调之后,需要返回200或者204的HTTP状态码。其他的状态码,微信支付均认为通知失败,并按照前述的策略定期发起通知。
注意,当商户后台应答失败时,微信支付将记录下应答的报文,建议商户按照以下格式返回。
<xml>
<code>ERROR_NAME</code>
<message>ERROR_DESCRIPTION</message>
</xml>
回调示例
微信发送给商户的支付成功结果通知
<xml>
<mch_id>10000100</mch_id>
<app_id>wx2134213414324</app_id>
<event_id>EV-2018022511223320873</event_id>
<event_create_time>20180225112233</event_create_time>
<event_type>TRANSACTION.SUCCESS</event_type>
<event_algorithm>AEAD_AES_256_GCM </event_algorithm>
<event_nonce>...</event_nonce>
<event_associated_data>...</event_associated_data>
<event_ciphertext>...</event_ciphertext>
<algorithm>HMAC-SHA256</algorithm>
<nonce_str>...</nonce_str>
<sign>xxxxxxx</sign>
</xml>
商户对resource对象进行解密后,得到的资源对象示例
<xml>
<state>USER_PAID</state>
<service_id>1234352342</service_id>
<out_order_no >1234352342545345454</out_order_no>
<order_id>1234352342545345454</order_id>
<goods_name>充电宝一个</goods_name>
<returned>TRUE</returned>
<start_time>20091225091010</start_time>
<deposit_amount>10000</deposit_amount>
<total_amount>200</total_amount>
<end_time>20091225091210</end_time>
<finish_transaction_id>…</finish_transaction_id>
</xml>
支付成功通知商户订单信息字段
字段名 | 变量名 | 示例 |
---|---|---|
单据状态 |
state |
USER_PAID |
服务ID |
service_id |
1234352342 |
商户服务订单号 |
out_order_no |
1234352342545345454 |
微信支付服务订单号 |
order_id |
1234352342545345454 |
商品名称 |
goods_name |
充电宝一个 |
是否归还 |
returned |
TRUE |
租用时间 |
start_time |
20091225091010 |
押金金额 |
deposit_amount |
10000 |
总金额 |
total_amount |
200 |
预计归还时间 |
end_time |
20091225091210 |
结单交易单号 |
finish_transaction_id |
124564252894372689954235 |