一笔订单,可是误付了两笔钱!这种重复付款异常到底该如何解决?|原创

封面送给我狗哥~html

Hello,你们好,我是楼下小黑哥~浏览器

今天的文章咱们接着上次的话题,继续聊聊支付系统异常解决办法。微信

在上篇文章中「支付掉单异常解决方案」,咱们主要提到的是支付过程当中掉单的场景,用户明明付款成功,银行卡都扣款了,可是订单却还显示待付款。网络

而在今天的文章中,咱们将聊到重复付款的异常,即同一笔订单,扣了用户两笔钱。架构

另外咱们还将会提到另一种异常,用户扣款成功,可是订单却支付失败的场景。异步

以上两种异常对于被扣款的用户来说,使用体验极差,本身多付了钱,订单却还不成功。因此若是不及时处理这两类异常,那就真的等着被投诉吧。ide

欢迎关注个人公众号:程序通事,得到平常干货推送。若是您对个人专题内容感兴趣,也能够关注个人博客: studyidea.cn

重复付款异常

异常场景

重复付款异常通常常见于网银支付,微信支付,支付宝等这类须要跳转到一个支付网关页(网银支付),或者跳转到钱包 APP(支付宝、微信),从而异步完成扣款的支付场景。微信支付

网银支付流程

这种支付场景下,只能经过接受异步通知才能知道支付结果,咱们通常将其称为异步支付。优化

PS:有了异步支付,那么同步支付是什么?

其实同步支付指的就是调用支付接口以后,就能够马上返回支付结果的,好比银行卡类快捷/代扣等支付就是同步支付。网站

固然也有一些奇葩的银行卡支付渠道,同步支付结果为受理成功,只能接受异步通知或者查询返回支付结果。

因为银行卡支付须要返回明确支付结果,对于这类渠道只能内部设计将异步转为同步,感兴趣能够看下以前历史文章:

架构设计|异步请求如何同步处理?

后台支付流程以下:

图片来自以前的文章: 银行卡支付原理

网关支付

为何会发生重复付款?

主要缘由其实跟上次内部掉单异常同样,跟业务表设计有关。

上次咱们提到,支付系统主要表结构以下:

在这个表结构下,只要支付订单未成功,商户就能够重复使用其内部同一订单号调用支付接口。

假设这样一个场景,用户在收银台支付时选择招行进行网银支付,当他点击支付以后,商户系统将会调用支付公司的网银接口。

这时支付系统内部将会建立一笔支付单以及关联的渠道订单,而且调用招行系统的接口。

而后用户的浏览器页面将会打开一个新页面,而后跳转到招行网站。

这时若是此时用户再次在收银台点击支付,将会再次调用支付系统接口。这时候因为支付单已存在,因此仅仅会再建立一条渠道订单记录,而且调用招行系统的接口。这时用户的浏览器将会再次打开一个招行的网站。

若是用户在两个招行网银页都完成支付,这时就发生了重复付款。

上面这种场景看起来有点傻,可是真实用户操做真的会发生。除了这种,博客园上的小伙伴还提到这么下面这种状况:

解决办法

重复付款异常的主要的解决办法有两种,分为事前与过后。

事前主要的目是尽量防止用户重复付款,主要解决办法为优化付款页面,尽量作好提示。

第一种优化方式,付款页面直接跳转到第三方/银行的网银页面,不要打开新的页面去跳转。

网银同步跳转

这种方式能够防止用户误打开两个网银付款的页面,从而致使重复付款。

可是这里会有一个问题,银行网银页面付款成功以后,用户如何知道其在商户侧订单状态也成功了?

其实很简单,如今网银支付接口,通常都会有一个参数 return_url:同步跳转地址

来自支付宝开发文档

只要在接口传入这个地址,当支付成功以后,页面最终就会跳转到这个传入的地址,商户侧就能够在地址显示订单是否支付成功。

支付系统异常处理-同步跳转

上面咱们提到,用户有可能会使用浏览器回退功能,跳转到支付页,从而致使重复付款。

对于这种状况,咱们能够在其回退支付页时,首先向后台查询这笔订单支付结果,若是已支付成功,那就直接显示成功页面。

第二种优化,对于这种从新打开一个页面跳转到银行网站,咱们能够在页面加入弹窗提示,询问用户是否已支付完成。

好比上面这种处理方式,当用户点击确认完成充值,能够立刻向后台发起查询订单状态。

下面来聊聊过后的解决办法,其实解决办法很简单,发起内部退款,将多余支付的一笔反向退款回去

支付系统内部能够有个定时任务,定时扫描支付单下有多条成功渠道订单的记录,而后选择将重复支付渠道订单发起退款。

这种方式是支付公司系统内部的操做,不须要商户侧发起指令。

订单失效异常

异常场景

这种场景通常常见于电商购物,秒杀等购物场景。当用户下单以后,页面将会开始倒计时,用户须要在有效期内支付成功。

假设用户点击跳转到支付宝,可是其没有马上支付,而是停留了好久,在订单最后一秒时间内完成了支付,可是这个时候订单早已由于时间到期而被自动取消。

这样就发生用户扣款已经成功,可是订单倒是失败或关闭的场景的。

另外还有一种状况,用户在有效期内支付成功,可是由于网络、内部应用等问题,支付结果的异步通知过了好久才收到,这时内部订单的早由于时间到期而被取消。

解决办法

第一种解决办法,上送有效期给支付渠道。

通常支付接口都会有一个支付有效期的字段,代表这笔支付最晚能够支付的时间。若是超时未支付,这笔支付将会被关闭。

来自支付宝开发文档

固然通常状况下,若是未上送,这个字段内部通常会有个默认的有效期,好比 3 天,这个时间就比较长了。

因此当调用支付接口时,能够将订单剩余有效期传入支付接口。这样用户若是在超时时间内未完成支付,支付将会失败。

第二种解决办法,内部发起退款。

这个解决办法依然过后托底的解决办法,对于支付订单已关闭,可是支付却成功的状况,发起内部退款,将钱退给用户。

内部能够有个定时任务,定时扫描支付订单已关闭可是支付却成功的状况,而后发起退款指令。

最后

最后用思惟导图方式帮你们总结一下支付系统可能会碰到的异常。

历史支付系统相关文章

  1. 收款神器!解读聚合收款码背后的原理|原创
  2. 手机没网了,却还能支付,这是什么原理?|原创
  3. 轻轻一扫,马上扣款,付款码背后的原理你不想知道吗?|原创
  4. 支付渠道路由系统进化史
  5. 从零开始设计对帐系统