淘宝上的虚拟主机不靠谱,小站三年心血白费!阿里云重新再来,为时不晚!时间宝贵,知识无限,产品领域知识精选转载,助力大家成长..

用户在商城下完订单,进行网银支付时发生重复支付,有什么解决方案?

勿踩那些坑 九天牧人 87℃ 0评论

一个用户在一个商城下完订单,支付的时候选择工行网银支付,点开之后没有确认支付,同时招商网页没有关闭。然后回到商城,刷新订单,重新选择另外一家交行进行网银支付,支付完了,支付结果没有那么及时通知到,用户又在打开的工行页面进行支付。结果两个都支付了,发生了重复支付。有没有什么解决方案

泻药。首先,在正式回答问题前,先解释下用户网上支付流程。

一、网上支付流程

网上支付涉及 4 个环节:消费者、出售者、收款方和发行方,具体支付流程共 9 个步骤:

  • 消费者下单
  • 消费者选择第三方支付网关
  • 消费者选择发卡机构(银行、卡组织)
  • 第三方支付平台转发信息发到相关银行
  • 相关银行处理支付请求,给网管应答;相关银行处理支付请求,给消费者应答
  • 第三方支付平台应答发给网上商户
  • 商户确认交易成功后向消费者提供服务、发货等
  • 第三方支付平台根据协议向商户支付、清算等服务
  • 银行向第三方支付平台提供支付、清算等服务

(当然,这有个前提,你的第三方支付账户里没有余额。)

(图来自于网络资料)

从这张图就可以解释为什么我们在网上买东西会跳转很多网页了。

二、用户在商城下完订单,进行网银支付时发生重复支付,有什么解决方案?

通常,支付系统和交易系统是两个独立的系统,也就是说,支付成功不一定交易成功,支付状态的变更才会驱动交易状态的变更。了解这一点之后呢,现在的情况就是两种:

1. 支付成功,但交易没有成功,这种情况下,用户还是可以继续对该交易进行支付,即可能出现重复支付的问题。

解决方案:此时如果第二个交易状态推进成功,在后续第一笔支付重新推进交易时,交易系统告诉支付系统,该笔交易已经支付成功,此时支付系统需要是对之前那一笔的支付进行撤销,对电商系统来说,这是同一个单据重复支付了多次,即电商订单流水号对应多笔成功的银行/支付公司流水,一般的情况下,只要确认其中一笔,剩下的全部主动退款就行了。

2. 如果支付成功,交易成功,用户也无法进行重复支付。

以上内容是单纯的从支付和交易不同状态下的一个基本的业务逻辑的表述,我们不妨深入一下,具体聊一下这个订单系统和支付系统在业务上是怎么跑起来的。

三、货到付款的订单中商品位于不同实体仓,可否实现拆单发货,又如何向客户分批收款?

接着我开场说的,这个问题涉及到的是两个不同的系统:订单系统和支付系统。

很多人以为这是同一套系统,本人曾经参与过商城需求文档的撰写,才发现其实不是。当年的程序猿哥们儿解释给我说,订单和支付系统在开发的时候是分开设计的,订单系统有多个子订单:订单A,订单B,订单C,这个指令完了之后会合并在一起,传入支付系统,那后者看到的只有一个单号。所以,从逻辑(程序)上是不存在什么拆分支付流水的。

至于业务流程上说的子订单间的退款以及优惠活动等等,是订单系统要处理的逻辑。

1、订单设计。

订单设计包括两个内容:

  • 订单信息
  • 商品信息

这里的逻辑是:订单=主表,商品=从表。其中,订单信息会包括:订单号、金额、购买人等等,商品会记录订单号、商品信息、商品数量、商品金额等。

2、拆单。

所谓拆单一般的是指拆订单,不是拆支付流水。为什么? 很简单,你想,一个订单可以对应多个商品,这样的话,就需要把其中某个商品或者某几个商品进行分组,形成子订单,形成了一次付款对应多个订单的情况。那你得问了,啥时候才会有拆单? 个人有限的经验告诉我,有两种情况:

  • 便于结算。一个订单包含多个商家的商品,为了结算方便,拆!
  • 便于发货。一个订单包含多个仓库的商品,为了发货,拆!

所有的合并和拆分都是基于订单,那么这时候的订单结构应该需要变成:主订单、子订单、商品三个表。

3、支付流水

国外的商城系统也是这样的,不信你去看看magento的后台(个人认为,想把电商的架构搞明白,magento简直就是个超级好的教材),对于国内的电商系统,支付基本都是用第三方支付,设计的时候会把订单和支付分开。为啥?你想啊,刚刚说了这是两套系统,对应的自然是两个业务,而支付唯一影响的是订单的付款状态,那就好了,设计的时候我们就必需将订单和支付抽象,不要混在一起,这也就很好解释了为什么支付不需要管具体的拆单,要拆单只需要拆订单,而不需要拆支付流水的原因。一个支付流水对应一个主订单,其他和支付流水没有必须的关系。

订单和支付的逻辑理清楚了之后,我们再来看所谓的分仓发货这个业务简单的流程:

  • 下单:同一个商家,形成一个主订单和一个子订单,N个商家,形成一个主订单和N个子订单
  • 支付:修改主订单的支付状态
  • 发货:同一仓库同时发货,则形成一个发货单;不同仓库或者不同时间发货,则形成多个发货单。发货单需要关联发货的商品明细,修改商品的发货状态。
  • 结算:按照订单状态和商家生成结算数据,销售和退款都在同一个订单表,那么直接计就好了

当然,以上是最为简单的业务情况,实际的业务情况会更加复杂,但是整体流程就是这个样子。这里复杂的地方不是题主问的“向客户分批收款”的难度,这个是表面现象,因为我前面解释了订单和支付的关系,也就是一个订单一个订单是独立的,线下支付完统一给商城,这里不涉及使用线上支付工具,包括代金券,第三方支付等还要冲正的问题,所以不难。只要拆单的逻辑你清楚了,订单系统闭环走完了跳到支付系统,这样结算很清楚,根本就不是问题。

既然提到了收账冲正,就多说一点。

打个比方,我在购物车里有A,B两件来自2个不同商家的商品,那么当货到付款后就要开始考虑怎么分账了。

如果是货到付款,那还好办。难点在于如果我是使用了代金券支付的话,也许A店家接受代金券但是B店家不接受,这里就涉及分账了。

这个时候,在支付系统的设计上应该有个独立的分账系统来处理,是为了防止用户进行退货操作,就对分账进行冲正。比如,我A货要退,同时之前买的C活也要退,那么在冲正的时候,系统的设计上就必需有优先级,是余额支付先退,还是优惠类的支付(如:代金券,优惠券)先退,还是信用卡支付先退,要有优先级。

冲正在分账系统中走完后,是信用卡支付的还涉及到银行,得所有需要向银行提交的冲正汇总成一笔,发送到银行。(所以当量大的时候经常会造成崩溃也是可以理解的)。

以上内容是不是很眼熟,没错看老贴

不提其他,这里基于事件的管道就没做好。 场景中出现用户支付的 A 途径和 B 途径,A 打开后待命,B 打并顺利完成支付。此时 B 应该有明显的支付完成后的回调提示,提示订单已经完成支付,下一步是什么样。假定此时用户返 2,没有查看提示,直接关闭或者鱼记忆生效,切换到 A 途径。 在 A 途径中需要存在主动轮询和被动接受订单变更,如果轮询时间合适,B 支付完成后,A 已经轮询到当前订单状态变更,此时关闭 A 途径;如果处于轮询空档,此时没有轮询到结果,那么在 B 支付完成后,事件管道需要推送到 A 并关闭 A 途径。 再有后端和你说分布式会怎么怎么样啊,好,我们来说可能的情形。能到这么高并发需要使用分布式的情形,订单量已经相当大了,否则单例处理足够了,如果慢请优化后端。你可以请他看看实际生产环境中国内一线支付平台和电上平台的并发峰值,相信看了自己都会有想法的了。 分布式,不能进行订单数据实施同步,我们调整分布设计,首先按照订单统计规律就近集中划分区域服务,这是最基础的压力分担,稍稍关注一下就能知道此前微信和支付宝的流量切割操作;再往上一点,针对区域进行时间段分流负载,针对存在的系统处理延迟,给用户做前端提示,典型的就是 12306 的和小米的排队,真假我们暂且不论。 说到底,这是后端架构设计的问题。好了,我只是 PM,后端架构的东西是架构师考虑的,我懒得费脑力了。

转载请注明:GoodPM » 用户在商城下完订单,进行网银支付时发生重复支付,有什么解决方案?

喜欢 (0)

Warning: copy(/data/home/qxu1590320265/htdocs/avatar/54*.jpg) [function.copy]: failed to open stream: No such file or directory in /data/home/qxu1590320265/htdocs/wp-content/themes/Cui2.0/functions.php on line 1132

Warning: copy(/data/home/qxu1590320265/htdocs/avatar/108*.jpg) [function.copy]: failed to open stream: No such file or directory in /data/home/qxu1590320265/htdocs/wp-content/themes/Cui2.0/functions.php on line 1133
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址