支付体系设计中如何规避重复交易?
鄂西一农夫移动支付网2019/9/5 17:39:37

有一种失误,支付公司永远伤不起,那就是重复交易,尤其是重复出款。某公司因网络延迟,重复出款达4亿多元,至今还在追讨。另一家支付公司更无语,对前一年的最后一日交易进行了重复出款,金额也是大几亿元,导致元气大伤。因此,支付系统安全事关重大,不得不察!

有这么一种场景:

订单已下单成功并且正处于支付页面,用户调起支付网关进行支付。支付成功了一次,但是由于某种情况导致未接收到银行返回的【支付成功】等信号,系统此时还是认为未支付成功。用户此时又支付了一次并且成功了。

这样的结果是,用户会为次订单支付两次,甚至多次。

很多的支付公司都经常发生过重复交易,有的后果很严重,导致了大额的资金损失,带来无法挽回的后果。所以说,看似一个简单的功能,若不注意产品场景与设计细节,将会酿成大祸。

下面,结合实际场景,从以下几个方面来识别重复发生,探讨用什么方式来进行规避:

服务的设计维度

1.基于页面的产品设计

面向用户操作的产品功能设计中,最常见的就是按钮的双击会带来重复交易的可能,这个要结合实际的设计来规避,可以使用防重复点击控制,或者使用令牌机制来保障点击的有效性。

上述的缺陷相对来说简单一些,若是采用其它复制等技术手段或浏览器自带缓存回退到上一个页面等,让交易重放,若下层系统没有相应的手段进行拦截的话,也会导致重复流水的产生,从而发生重复交易。

针对于此,有些常用的规避手段,一是服务端与UI端采用令牌、时间戳等手段来进行约束控制;二是产品设计增加确认流程来进行判断。

2.基于纯接口设计

这里说的纯接口,包含对外的API调用服务,以及内部系统之间的服务调用。这就需要被调用方在设计时,一定要通过必要手段,把重复交易放在异常的第一位。

比如外部订单号做唯一索引,进行幂等性判断,保障交易的唯一性。同时,发生重复交易时,也必须很清晰的将订单的信息给反馈给调用方。

调用方在识别服务的返回结果时,除了成功与失败是最终结果时,也要特别注意失败中的“重复”异常结果,因为这种失败是不能直接做失败的,必须进行查询来再次捕获,或者再设计时,就由被调用方约定好,因为这不是单方的设计,必须是统一的设计规则。

还有一种情况会发生,就是有些功能设计,在后台会采用异步查询来捕获一些未返回订单,在进行设计时一定要规避一种情况,就是不要让查询早于交易提交,不然也会发生重复提交的风险,这个要在实际设计中对订单进行上锁来控制,切不可简单的进行分离设计。

交互过程的异常考虑

此环节比较复杂,主要是异常方面的逻辑设计:

最常发生的场景是超时,这时上层系统必须采用两种方式来处理,但这两种方式有所不同:

A:发生超时,上层系统调用下层的查询来进行捕获判断上次交易的实际情况,这是标准的处理方式;

B:发生超时,上层系统可以采用原订单进行重复提交,这时就要看整个体系的设计是否遵循了重复性判断,否则下层系统会守不住,这就是为什么技术体系会有一些设计规范来约束大家执行,从整体上来规避此种事情的发生。

发生超时,上层系统切不可直接自己做失败处理,然后重新生成订单再次提交,那么会必然产生重复交易。

由此可以看出,一个公司或技术体系越是庞大,就必须有严格的设计规范来约束不同的设计人员和研发人员,包括测试人员也要进行此种场景的模拟测试。

除了超时,可能会发生一种情况,就是下层系统设计不怎么友好时,会抛出下层的异常堆栈,这时上层系统捕获到后,也必须采用超时那样,切不可自己随意进行处理。

错误码设计

系统在进行设计时,都会对正常和异常进行相关返回码进行统一定义,以方便上层系统,以及自身知晓系统的处理情况,对于未进行错误识别的,也必须遵守这个规则。

当设计码表时,切不可过于复杂,有时候会碰到双码甚至三个返回码,这样会把系统之间的关系搞得过于复杂,一般情况只有一个返回码,结合错误描述来便于调用方理解。

我们在进行金融支付时,常用的非成功或明确的失败,就是处理中,靠查询来进行捕获,也是一种保守的设计,在一定程度上会影响到产品的体验,但也是在系统建设初期很好的保护自身不发生重复支付交易。

定时服务

在实际的场景中,有的机构也发生过因定时服务而导致的重复交易。

系统在设计之初,定时服务只是为了解决一些异步处理、补偿处理、或异常流程而设计的,但在设计后的统一性上一定要控制好,不然会带来某些功能的重复。

定时服务一定要结合订单的状态机,来对流水进行锁定,以防止与正常的业务流程并行处理,除了采用状态,另外还可以进行关键性要素的组合判断,这个要结合实际的场景进行设计,同时要与大家一起进行约束,切不可自行随意设计,这样会带来可怕的后果。

结合上述的几个方面,这里可以看出设计规范与规则很重要,一个研发体系必须有这方面的约定,让相关人员即统一,又培养良好的设计习惯。

除此之外,对于测试用例的也是必不可少的环节,让产品在设计之初,测试人员过早的介入,熟悉产品功能,和设计逻辑,利用测试的专业领域的知识,可以在重复支付上进行模拟与验证,来实现对系统的设计目标的验证与保证。

本文为作者授权发布,不代表移动支付网立场,转载请注明作者及来源,未按照规范转载者,移动支付网保留追究相应责任的权利。

展开全文
相关阅读
资讯查询取消