1. 前言
最近是有做关于支付通知相关逻辑的优化,而这些优化点提出之后,我去看了下WX支付的产品文档,关于支付通知的逻辑,就想着记录一下。
支付这件事情,作为支付网关,承担的是和商户以及银行/其他金融机构的交互,最后将结果通知回商户/用户。从用户的角度而言,我们要支付的时候,在国内无非是我们扫码或者我们被扫码(当然还有其他的支付场景,这里只以主流的支付场景为例),实际都是触发支付的一个过程,只是我们扫码是我们主动触发,而我们被扫码是扫了你的码的对应机器帮助你触发唤起支付的过程。
这里参考WX支付的文档,来聊一聊支付的通知机制。
2. 支付如何产生?
以WX的JSAPI支付为例,支付的产生过程如下:
- 用户通过平台下单,发起支付
- 商户系统后台平台生成订单号
- 商户系统后台请求WX支付系统下单接口,创建订单
- WX支付系统接收到商户系统后台的创建订单请求,生成预付单
- WX支付系统向商户系统后台返回预付单标识
- 商户系统后台生成带签名的支付信息
- 用户通过点击确认支付发起支付
- 商户系统后台调起WX客户端支付
- WX客户端向WX支付系统后台发起支付请求
- WX支付系统验证支付授权权限
- WX支付系统返回支付授权
- 用户确认支付,输入密码
- WX客户端向WX支付系统后台提交授权
- WX支付系统验证授权
- WX支付系统会异步通知支付结果给平台
- 平台保存支付结果
- 平台返回告知WX支付系统通知结果接收处理响应(这里如果返回是失败,WX支付系统会不断重试通知)
- WX支付系统向WX客户端返回支付结果,并发微信消息提醒用户
- WX客户端向商户系统后台进行支付状态查询(这里感觉是画错了,应该是向WX支付系统后台发起支付状态查询请求)
- 平台如果未收到支付回调通知,需要主动调用查询订单API查询支付结果
- WX支付系统向商户系统后台返回支付结果
- 最后商户系统后台向用户展示支付消息
上面是一整个微信支付的全流程,其中结果的通知出现在第15~17步,而这几步就涵盖了支付通知的全过程。
3. 支付通知
这一节可参考:支付通知
对于支付通知而言,WX支付在文档中明确提出了关于支付通知的解释:
WX支付通过支付通知接口将用户支付成功消息通知给商户。
这里明确了支付通知的消息类型,是用户支付成功的消息(而支付失败的消息,WX应该做了逻辑闭环,或通过用户重试,或采用其他逻辑进行处理了。)
而具体的通知规则描述如下:
用户支付完成后,微信会把相关支付结果和用户信息发送给商户,商户需要接收处理该消息,并返回应答。
对后台通知交互时,如果WX收到商户的应答不符合规范或超时,WX认为通知失败,WX会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但WX不保证通知最终能成功。(通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h - 总计 24h4m)
也就是如果商户系统后台没有及时的响应或者响应报文有误,则会触发WX的不断重试通知,直至超过重试的策略限制。
通知的路径是由商户系统后台通过notify_url提供给WX支付系统后台的,所以在支付成功后,WX支付后台就按照这个地址给用户通知,而通知的接口参数都是由WX支付系统后台定义好的,在商户系统后台接入WX支付的时候,就需要按照产品的API文档进行对应的接口逻辑适配。
另外,支付通知到商户系统后台后,商户系统后台同样需要按照WX支付文档中所规定的通知应答的响应报文格式给出应答,否则会被视为通知失败,启动重试策略。
按照文档给出的,这个通知应答的格式很简单:
- 接收成功:HTTP应答状态码需返回200或204,无需返回应答报文。
- 接收失败: HTTP应答状态码需返回5XX或4XX,同时需返回应答报文,这里需要返回错误code和message(标识错误的原因)
所以是WX给接入的商户定义了一套响应的规范,而这个规范则十分简单,就是成功或者失败,不存在中间的状态(未知)这一类的错误码。
4. 聊一聊
我们设想一下,如果你是一个支付网关,最开始你有3个商户,他们都要求你对他们的接口响应进行识别,需要对某一些信息做特定逻辑的处理。
或许这个时候,商户数量少,我们可以接受对他们的响应进行特定逻辑的处理。
但随着支付网关接入的商户数量越来越多,我们还能够一个一个的接口响应进行识别,一个一个的去对响应信息进行特定逻辑的处理吗?答案肯定是不能,因为这样维护的成本巨大,只要有逻辑变动,就会导致你也跟着受影响。
所以为了规避对每一个商户的支付结果通知响应的差异,最好的办法就是定义规范,只允许商户返回接收成功和接收失败的响应,而不允许返回任何带有业务性质的一些非约定字段数据,这样就可以统一了,接入的商户再多也不会影响网关和商户的逻辑。
5. 小结
从WX支付的支付通知看对应的商户接入的设计,约定规范可以帮助规避很多问题,同时可以屏蔽很多不必要的逻辑,从而使得支付网关更符合网关的设计。
6. 参考
- https://pay.weixin.qq.com/docs/merchant/products/jsapi-payment/introduction.html