全网最易懂的微信小程序支付
背景
SpringBoot项目涉及微信小程序支付,如何通透实现支付功能?
分析
根据官方文档,要实现微信支付,先得进行微信支付的申请,这里就不多描述了。
申请后,可以得到了商户号,**,以及小程序appid。这些个参数是必不可少的。
接下来是要去理解整个支付的流程。
整个流程总体上可以分为4步:
1.后台生成预订单。
2.请求统一下单接口获取下单参数。
3.微信小程序进行调用支付。
4.后台接受微信回调服务对订单进行更新。
行动
那么有了大概的思路,让我们行动起来,一步步来实现预期。
第一步,后台生成预订单。那这一步的作用是什么呢?
我的理解是,生成out_trade_no为第二步做准备,同时在第四步触发回调的时候可以通过out_trade_no去快速进行订单的状态更新。
具体的生成预订单业务也不多说,注重点在核对产品以及产品的价格上。
第二步,是请求统一下单接口获取下单的参数。
这一步是最难的也是最重要的。
我们先把镜头拉远,从整体上去观察挖掘它。
既然是请求接口,先要关注的点应该是在请求参数的格式以及返回的格式上。
查阅文档可以清楚请求参数的格式是xml格式,必须要传的参数有:
sign参数是要对前面的参数进行按ASCII排序后进行加密函数加密,默认加密方式是MD5。
需要注意的参数notify_url:第四步回调触发的地址,这里必须要外网能够访问的且是https协议的地址,关于https可以看往期的推文。
out_trade_no,第一步生成的商户订单号,必须唯一而且不能长于32个字符。
此外若body参数含有中文,请求接口时需添加请求头:Content-Type:text/xml;charset=utf-8。否则可以会请求接口失败。
签名的话可以使用官方wxpay-sdk包里面的方法进行加密,它会把加密的sign参数也添加到xml中了。目前该sdk包并没有发布到maven仓库,可以到官网下载,后台回复【sdk】。
然后的话接口返回的内容也是xml格式的。可以使用WxPayUtil里面的方法转为map。
这是小程序调用支付接口需要的几个参数,注意的是这里也是需要进行参数的签名的。
同时需要注意的一点是package参数需要prepay_id=前缀,这是最容易忽略的地方。
第三步就比较轻松多了,直接调用api进行支付。
成功的话就可以正常支付了,有问题的话重点在签名和package格式上,当然参数大小写需要严格按照要求的。
那么第三步支付完成之后呢,微信可能会发送多次支付结果到我们后台的回调接口。
我们需要保证即便多次重复的请求也能保证数据的一致性,也就是微信发送多次请求,我也能够正确处理重复的通知。
所以在这里我会先通过返回的out_trade_no去查询是否已经处理过了,处理过就不需要处理了。
微信提到很重要的信息,就是通知没收到响应会重复发送通知,但是不会一直发送,有一定的上限,这里并不能保证支付通知到位。
因此除了被动更新订单状态之外,我们还要设计主动查询订单的策略,以防订单支付成功但订单状态没有更新到位的情况。
最后思考的一点,因为回调地址是暴露的,被伪造下单成功通知是必然会发生的。
因此,需要重签名通知的内容,得到签名再核对。以防止用户伪造订单成功通知。该重签名是要重签名所有处签名参数之外的所有参数。
思考
之前强调过,官方文档是最接近技术的途径,也是最原始的。
技术在传播的途中,会产生不同的理解,每个人的理解不同,一百个人心中有一百个哈姆雷特。
不迷途
扫描二维码
关注我们
公众号:不迷途