Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何防止订单二次重复支付?

如何防止订单二次重复支付?

原创
作者头像
JavaEdge
修改于 2024-07-23 09:32:41
修改于 2024-07-23 09:32:41
3170
举报
文章被收录于专栏:JavaEdgeJavaEdge

1 背景

用户第一次点击下单操作时,会弹出支付页面待支付。但可能存在用户在支付时发现账户金额不够,后续选择:

  • 其他渠道支付(如微信支付转为支付宝支付)
  • 或采用不同终端来支付(如由电脑端支付转为app端支付)

这时就面临二次支付场景。

2 方案1

由于用户支付的时候的支付页面是html文件或是一个支付二维码,可将支付页面先存储一份在数据库中,用户二次支付时通过查询数据库来重新返回用户原来的支付页面。

2.1 缺点

需注意支付页面是否过期,若支付页面过期,需二次调用第三方支付

  • 后台需维护用户第一次调用时的支付页面,增加开发成本
  • 需要注意幂等性,即能唯一标识用户的多次请求

2.2 优点

规定时间内,不论用户多少次调用,后台只需要调用一次第三方支付。

2.3 流程图

3 方案2

用户第二次支付的时,继续调用第三方支付,让第三方根据是否超时等情况判断是:

  • 返回原来的支付页面
  • or生成一个新的支付页面返回

3.1 优点

便于实现,减轻自己后台下单的维护成本。【推荐】

用户二次支付时,订单微服务中存储了用户第一次下单支付的基本信息。因此第二次支付时,可通过查询第一次支付的一些基本信息来调用第三方支付。这样设计可告诉第三方支付平台这是一个订单,尤其是该订单的【剩余过期时间】。

剩余过期时间

后台调用第三方支付,第三方支付从收到请求信息->处理请求信息->响应请求信息是存在一定的时延的,因此一定不能死死卡住过期时间来调用第三方支付。需要预留一些时间给第三方支付处理。如支付过期时间是30分钟,当用户二次支付到达我们下单服务的时候是29分钟那么就拒绝支付。

用户超时支付的拒绝策略

策略一

前端显示订单30分钟内需要支付,后端中对第三方支付实际上是31分钟内不能支付 【预留时间给后端和第三方支付交互】

策略二

前端显示订单30分钟内需要支付,后端对第三方的支付实际上是当用户支付请求在地29分钟到后端就不给支付了。

代码语言:java
AI代码解释
复制
@Override
@Transactional
public JsonData repay(RepayOrderRequest repayOrderRequest) {
    LoginUser loginUser = LoginInterceptor.threadLocal.get();
    // 根据订单流水号查询第一次支付的订单信息
    ProductOrderDO productOrderDO = productOrderMapper.selectOne(new QueryWrapper<ProductOrderDO>().eq("out_trade_no",repayOrderRequest.getOutTradeNo()).eq("user_id",loginUser.getId()));

    log.info("订单状态:{}",productOrderDO);

    if(productOrderDO==null){
        return JsonData.buildResult(BizCodeEnum.PAY_ORDER_NOT_EXIST);
    }

    // 订单状态不对,不是NEW状态
    if(!productOrderDO.getState().equalsIgnoreCase(ProductOrderStateEnum.NEW.name())){
        return JsonData.buildResult(BizCodeEnum.PAY_ORDER_STATE_ERROR);
    }else {
        //订单创建到现在的存活时间
        long orderLiveTime = CommonUtil.getCurrentTimestamp() - productOrderDO.getCreateTime().getTime();
        //创建订单是临界点在预留一分钟时间,比如订单实际已经存活了28分钟了,我们就对外说订单已经存活了29分钟。
        orderLiveTime = orderLiveTime + 60*1000;

        //大于订单超时时间,则失效
        if(orderLiveTime>TimeConstant.ORDER_PAY_TIMEOUT_MILLS){
            return JsonData.buildResult(BizCodeEnum.PAY_ORDER_PAY_TIMEOUT);
        }else {

            //记得更新DB订单支付参数 payType,还可以增加订单支付信息日志  TODO
            //总时间-存活的时间 = 剩下的有效时间
            long timeout = TimeConstant.ORDER_PAY_TIMEOUT_MILLS - orderLiveTime;
            //创建支付
            PayInfoVO payInfoVO = new PayInfoVO(productOrderDO.getOutTradeNo(),
                    productOrderDO.getPayAmount(),repayOrderRequest.getPayType(),
                    repayOrderRequest.getClientType(), productOrderDO.getOutTradeNo(),"",timeout);

            log.info("payInfoVO={}",payInfoVO);
            //调用第三方支付
            String payResult = payFactory.pay(payInfoVO);
            if(StringUtils.isNotBlank(payResult)){
                log.info("创建二次支付订单成功:payInfoVO={},payResult={}",payInfoVO,payResult);
                return JsonData.buildSuccess(payResult);
            }else {
                log.error("创建二次支付订单失败:payInfoVO={},payResult={}",payInfoVO,payResult);
                return JsonData.buildResult(BizCodeEnum.PAY_ORDER_FAIL);
            }
        }
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
springcloudAlibaba&rancher【后端专题】
DevOps即Development和Operations的组合词,是一组过程、方法与系统的统称,用于促进开发应用程序或软件工程、技术运营和质量保障QA部门之间的沟通、协作与整合。
高大北
2022/12/20
2.4K0
springcloudAlibaba&rancher【后端专题】
7.Android常用第三方支付
移动支付 用户使用移动的终端完成对所购买商品或者服务的支付功能;分为近场支付(蓝牙支付,刷卡,滴卡),和远程支付(网上支付,短信支付) app支付模块 常见的支付厂商-->常见的支付方式 支付宝:阿
六月的雨
2018/05/14
1.8K0
支付宝接入(8)-1024电商平台项目技术选择和创 建聚合工程项目【工业级PaaS云平台+SpringCloudAlibaba+JDK11综合项目实战】
https://opendocs.alipay.com/open/54/cyz7do
高大北
2022/09/21
1.1K0
支付宝接入(8)-1024电商平台项目技术选择和创 建聚合工程项目【工业级PaaS云平台+SpringCloudAlibaba+JDK11综合项目实战】
订单服务以及优惠券服务及rabbitmq(7)-1024电商平台项目技术选择和创 建聚合工程项目【工业级PaaS云平台+SpringCloudAlibaba+JDK11综合项目实战】
第二十七章 新版消息队列RabbitMQ回顾和容器化安装部署 第1集 基于Linux服务器安装RabbitMQ容器化部署 简介:Docker安装RabbitMQ消息队列 阿里云安装RabbitMQ 最少 2核4g或者推荐 2核8g(用家人账号购买,接近1折,初次买1年或者3年) 登录个人的Linux服务器 ssh root@8.129.113.233 Docker安装RabbitMQ 地址:https://hub.docker.com/_/rabbitmq/ #拉取镜像 docker pull ra
高大北
2022/09/16
1.7K0
订单服务以及优惠券服务及rabbitmq(7)-1024电商平台项目技术选择和创 建聚合工程项目【工业级PaaS云平台+SpringCloudAlibaba+JDK11综合项目实战】
订单视角看支付
支付是指为清偿商品交换和劳务活动所引起的债权债务,货币债权从付款人向收付人的转移的过程。支付能力是电商产品的核心能力之一,作为订单同学,有必要了解关联域支付的流程以及基本概念,同时支付领域的很多设计思路与资损防控经验对订单域的系统设计也很有借鉴意义。本文将从支付系统的历史、基本概念、系统设计、资损防控与订单与支付交互等方面予以介绍。
得物技术
2024/02/28
5250
订单视角看支付
一个小小逻辑符的错误使用,资损几万块?
这是一个真实事件,三年前老猫负责公司的支付资产业务。为了响应上级号召,加强国央企之间的合作,公司新谈了一个支付对接的渠道(当然这个支付渠道其实很冷门的,也是为了对接而对接,具体哪个渠道也不方便透露),由于原始支付系统的第三方支付可拓展性设计得还不错的,所以老猫对接的也是比较快的,熟悉对方的对接文档之后对着编码就好了,差不多花了三天的时间就完成联调了。一切看似很顺利地上线了。
程序员老猫
2024/04/15
1390
一个小小逻辑符的错误使用,资损几万块?
springcloudAlibaba+devops
springcloudAlibaba&rancher【后端专题】 简介:用户增长的数据分析模型AARRR
高大北
2022/12/20
1.4K0
springcloudAlibaba+devops
Android开发笔记(一百零六)支付缴费SDK
第三方支付指的是第三方平台与各银行签约,在买方与卖方之间实现中介担保,从而增强了支付交易的安全性。国内常用的支付平台主要是支付宝和微信支付,其中支付宝的市场份额为71.5%,微信支付的市场份额为15.99%,也就是说这两家垄断了八分之七的支付市场(2015年数据)。除此之外,还有几个app开发会用到的支付平台,包括:银联支付,主要用于公共事业缴费,如水电煤、有线电视、移动电信等等的充值;易宝支付,主要用于各种报名考试的缴费,特别是公务员与事业单位招考;快钱,被万达收购,主要用于航空旅行、教育培训、游戏娱乐等网站的支付;京东支付,主要用于京东商城的支付;百度钱包,主要用于百度系的电商平台。 因为第三方支付只是个中介,交易流程要多次确认,所以app若要集成支付sdk,得进行以下处理: 1、除了作为买方的用户自己拥有支付账号,开发者还得申请作为卖方的商户账号。 2、支付过程中,虽然允许app直接与第三方支付平台通信,但是最好app要有自己的后台服务器,由自己的后台与第三方平台进行通信。这样做的好处是,一方面自己后台掌握了用户交易记录,做账有依据,管理也方便;另一方面,关键交易在自己后台处理,也减少了恶意篡改的风险。 3、为保证信息安全,需对关键数据进行加密处理,如支付宝采用RSA+BASE64算法,微信支付采用MD5算法,银联支付采用RSA算法。有关数据加密算法的说明参见《Android开发笔记(七十二)数据加密算法》。
aqi00
2019/01/18
2K0
支付宝服务端是如何防止重复支付的
过程是一笔订单已经支付了,在无结果返回的时候,又允许支付了下一笔订单,造成扣款多次。
架构狂人
2023/08/16
9730
支付宝服务端是如何防止重复支付的
一般电商应用的订单队列架构思想
其中,订单信息持久化,就是存储数据到数据库中。而最终客户端完成支付后的更新订单状态的操作是由第三方支付平台进行回调设置好的回调链接 NotifyUrl,来进行的。
林冠宏-指尖下的幽灵
2019/07/10
1.2K0
一般电商应用的订单队列架构思想
实战,一般电商应用的订单队列架构思想
其中,订单信息持久化,就是存储数据到数据库中。而最终客户端完成支付后的更新订单状态的操作是由第三方支付平台进行回调设置好的回调链接 NotifyUrl,来进行的。
芋道源码
2019/08/06
1.1K0
实战,一般电商应用的订单队列架构思想
千万级支付对账系统是怎么设计的?
今天给大家分享一篇关于对账系统设计的文章,出自在支付行业摸爬滚打好几年的小黑哥之手。
架构之家
2022/09/01
3.6K0
千万级支付对账系统是怎么设计的?
服务端防止订单重复支付
上图是一个简化的下单流程,首先是提交订单,然后是支付。支付的话,一般是走支付网关(支付中心),然后支付中心与第三方支付渠道(微信、支付宝、银联)交互,支付成功以后,异步通知支付中心,支付中心更新自身支付订单状态,再通知业务应用,各业务再更新各自订单状态。
Ant丶
2022/03/01
7400
服务端防止订单重复支付
干货!各支付场景下前后端交互流程
支付有多种渠道,在不同的宿主环境下,可能都不一样,比如APP内的支付、微信内支付、小程序支付、浏览器内h5支付等等。这篇文章主要理清常见场景下各个支付的流程和api,后续一旦有新业务接入支付,能起到一个引导作用,少走弯路。
前端森林
2021/09/10
2.2K0
干货!各支付场景下前后端交互流程
支付宝扫码支付关闭订单功能实现
前段时间做了支付宝的扫码支付,奈何当时demo中没找到退款API,AlipayTradeService接口里面只有预下单和退款的方法,然后就忙别的事情。 今天查看了一下支付宝的支付API,alipay.trade.close (统一收单交易关闭接口),详细说明:用于交易创建后,用户在一定时间内未进行支付,可调用该接口直接将未付款的交易进行关闭。 实现方法如下: @Override public String aliCloseorder(Product product) {
小柒2012
2018/04/13
8.3K1
基于 flink 的电商用户行为数据分析【8】| 订单支付实时监控
本篇是flink 的「电商用户行为数据分析」的第 8 篇文章,为大家带来的是市场营销商业指标统计分析之订单支付实时监控的内容!通过本期内容,我们可以实现通过使用CEP和Process Function来实现订单支付实时监控的功能,还能学会通过connect 和 join来实现flink双流join的功能,可谓干货满满!受益的朋友记得三连支持一下 ~
大数据梦想家
2021/01/27
3.1K0
基于 flink 的电商用户行为数据分析【8】| 订单支付实时监控
码云上不错的几个支付相关的项目
网上支付相关的额业务场景无处不在,如果能掌握支付相关的核心技术,对于升职涨薪有莫大的好处。目前国内支付以支付宝和微信这两种支付为首,其他支付则可以忽略不计。有些网友以这两种支付为基础开源了不少相当不错的项目。
BUG弄潮儿
2020/06/12
2.2K0
码云上不错的几个支付相关的项目
支付系统就该这么设计(万能通用),稳的一批!!!
支付中心系统对内为各个业务线提供统一的支付、退款等服务,对外对接三方支付或银行服务实现资金的流转。如下图:
沉默王二
2023/03/06
1.6K0
支付系统就该这么设计(万能通用),稳的一批!!!
服务端如何防止重复支付
如图是一个简化的下单流程,首先是提交订单,然后是支付。支付的话,一般是走支付网关(支付中心),然后支付中心与第三方支付渠道(微信、支付宝、银联)交互,支付成功以后,异步通知支付中心,支付中心更新自身支付订单状态,再通知业务应用,各业务再更新各自订单状态。
良月柒
2021/04/20
9040
如何防止订单二次重复支付?
在电商平台和支付系统中,防止订单二次重复支付是一个至关重要的功能。以下是一些常见的策略和技术手段,用于确保订单支付的幂等性和一致性。
用户11397231
2024/12/18
1810
如何防止订单二次重复支付?
推荐阅读
相关推荐
springcloudAlibaba&rancher【后端专题】
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档