关于java:服务端如何防止订单重复支付

53次阅读

共计 872 个字符,预计需要花费 3 分钟才能阅读完成。


如图是一个简化的下单流程,首先是提交订单,而后是领取。

领取的话,个别是走领取网关(领取核心),而后领取核心与第三方领取渠道(微信、支付宝、银联)交互,领取胜利当前,异步告诉领取核心,领取核心更新本身领取订单状态,再告诉业务利用,各业务再更新各自订单状态。

这个过程中常常可能遇到的问题是掉单,无论是超时未收到回调告诉也好,还是程序本身报错也好,总之因为各种各样的起因,没有如期收到告诉并正确的解决后续逻辑等等,都会造成用户领取胜利了,然而服务端这边订单状态没更新,这个时候有可能产生投诉,或者用户反复领取。

因为③⑤造成的掉单称之为内部掉单,由④⑥造成的掉单咱们称之为外部掉单

为了避免掉单,这里能够这样解决:

1、领取订单减少一个中间状态“领取中”,当同一个订单去领取的时候,先查看有没有状态为“领取中”的领取流水,当然领取(prepay)的时候要加个锁。领取实现当前更新领取流水状态的时候再讲其改成“领取胜利”状态。

2、领取核心这边要本人定义一个超时工夫(比方:30 秒),在此工夫范畴内如果没有收到领取胜利回调,则应调用接口被动查问领取后果,比方 10s、20s、30s 查一次,如果在最大查问次数内没有查到后果,应做异样解决

3、领取核心收到领取后果当前,将后果同步给业务零碎,能够发 MQ,也能够间接调用,间接调用的话要减轻试(比方:SpringBoot Retry)

4、无论是领取核心,还是业务利用,在接管领取后果告诉时都要思考接口幂等性,音讯只解决一次,其余的疏忽

5、业务利用也应做超时被动查问领取后果

对于下面说的超时被动查问能够在发动领取的时候将这些领取订单放到一张表中,用定时工作去扫

为了避免订单反复提交,能够这样解决:

1、创立订单的时候,用订单信息计算一个哈希值,判断 redis 中是否有 key,有则不容许反复提交,没有则生成一个新 key,放到 redis 中设置个过期工夫,而后创立订单。其实就是在一段时间内不可反复雷同的操作

附上微信领取最佳实际:

起源:废物大师兄
地址:www.cnblogs.com/cjsblog/p/14516909.html

正文完
 0