服务端如何防止重复支付

简介: 服务端如何防止重复支付

概述

image.png

如图是一个简化的下单流程,首先是提交订单,然后是支付。支付的话,一般是走支付网关(支付中心),然后支付中心与第三方支付渠道(微信、支付宝、银联)交互,支付成功以后,异步通知支付中心,支付中心更新自身支付订单状态,再通知业务应用,各业务再更新各自订单状态。

这个过程中经常可能遇到的问题是掉单,无论是超时未收到回调通知也好,还是程序自身报错也好,总之由于各种各样的原因,没有如期收到通知并正确的处理后续逻辑等等,都会造成用户支付成功了,但是服务端这边订单状态没更新,这个时候有可能产生投诉,或者用户重复支付。

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

为了防止掉单,这里可以这样处理:

1、支付订单增加一个中间状态“支付中”,当同一个订单去支付的时候,先检查有没有状态为“支付中”的支付流水,当然支付(prepay)的时候要加个锁。支付完成以后更新支付流水状态的时候再讲其改成“支付成功”状态。

2、支付中心这边要自己定义一个超时时间(比如:30秒),在此时间范围内如果没有收到支付成功回调,则应调用接口主动查询支付结果,比如10s、20s、30s查一次,如果在最大查询次数内没有查到结果,应做异常处理

3、支付中心收到支付结果以后,将结果同步给业务系统,可以发MQ,也可以直接调用,直接调用的话要加重试(比如:SpringBoot Retry)

4、无论是支付中心,还是业务应用,在接收支付结果通知时都要考虑接口幂等性,消息只处理一次,其余的忽略

5、业务应用也应做超时主动查询支付结果

对于上面说的超时主动查询可以在发起支付的时候将这些支付订单放到一张表中,用定时任务去扫

为了防止订单重复提交,可以这样处理:

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

附上微信支付最佳实践:

image.png


目录
相关文章
|
程序员 Linux Ruby
Mac安装并使用telnet命令操作
Mac安装并使用telnet命令操作
16853 1
Mac安装并使用telnet命令操作
|
运维 NoSQL 测试技术
从一个事故中理解Redis(几乎)所有知识点
作者从一个事故中总结了Redis(几乎)所有的知识点,供大家学习。
384 12
|
存储 数据采集 安全
各种系统架构图与详细说明
原文:各种系统架构图与详细说明 共享平台逻辑架构设计 如上图所示为本次共享资源平台逻辑架构图,上图整体展现说明包括以下几个方面: 1 应用系统建设 本次项目的一项重点就是实现原有应用系统的全面升级以及新的应用系统的开发,从而建立行业的全面的应用系统架构群。
26615 1
|
缓存 关系型数据库 MySQL
Mac安装brew
Mac安装brew
1536 6
|
Docker 容器
Docker下安装memcached
Docker下安装memcached
323 0
|
JSON Java 数据格式
Java将json中key值下划线转为驼峰格式
Java将json中key值下划线转为驼峰格式
1455 1
|
测试技术 Android开发 移动开发
SoloPi:支付宝 Android 专项测试工具 | 开源
本文主要介绍支付宝在移动端上实现的一套无线化、非侵入、免 Root 的 Android 专项测试方案 SoloPi。直接操控手机,即可实现自动化的功能、性能、兼容性、以及稳定性测试等工作。
3184 0
|
SQL
淘东电商项目(55) -支付系统核心表设计
淘东电商项目(55) -支付系统核心表设计
441 0
|
Java 测试技术 Spring
|
Linux iOS开发 MacOS
mac安装brew(国内地址,可成功安装!)
Brew全称叫Homebrew,是Mac系统上的软件包管理工具。这里的软件并不是指从AppStore或从网上下载的dmg文件,而是开发所需要用的一些工具软件,如gawk等。 只需要一个命令, 安装和卸载它们非常方便。
1029 0
mac安装brew(国内地址,可成功安装!)
下一篇
开通oss服务