-
资损
资金损失,有多扣用户款导致用户的资金损失,也有多出金或多充值导致支付公司的资金损失的。
-
资损分析
-
跟上下游系统交互
-
2.1.1 重复请求或者被重复请求
发生在系统交互连接处,被调用方重复发起同一笔业务订单,或同一笔订单调用其他系统发起两次以上请求,如果交互双方对“同一笔订单”的认识不统一,相关联系统没有对“同一笔订单”做好防重处理,都会导致重复出金或重复入金。
2.1.2 交互结果的返回码
需要明确调用别人系统返回码的含义,区分代表的是通讯结果还是业务结果,往往会因为把不是真正的业务失败返回码映射成失败的情况居多,还有就是超时无返回结果的时候也按失败处理的话,也会造成资损。对于别人调用我们的系统时,我们尽量返回尽量少,尽量明确的返回码,对方如果处理不好的话也会出现资损。
2.1.3 并发
只在代码上判重订单还不够,如果没有控制好并发,当订单同一时刻到达时,程序会判定无历史单均进入下一步的业务处理,会发生资损。
-
内部逻辑错误
2.2.1 业务逻辑过程处理
业务处理遵循正常的业务处理过程,如果程序处理没有严格贴合标准,比如先扣金额再出金这个过程中没有先扣掉金额就去做出金业务,再或者处理过程中重要数据比如金额、收款方信息遭到更改,就会发生资损。
2.2.2 手续费
由于好些场景中的手续费扣除是跟主业务分开进行的,手续费是不是扣了,多扣少扣都不易发觉,所以此处也有资损的风险。
2.2.3 金额换算
在一些精度要求比较高的场景中,某些数据库支持的不够,需要将小数转成整数存放和读取,此时如果处理不当,会造成资损。
2.2.4 状态控制
状态在订单的流转处理中扮演着非常重要的角色,每种状态的变化是有顺序的,每个状态下能做的业务处理也是有限制的,如果在某个状态下做了不该做的事情,或者状态转换时跳过了设定的状态,就有可能会发生资损。
-
安全漏洞
2.3.1 伪造请求数据
报文被别有用心的人截取后,伪造请求报文发起出金请求,一旦安全机制薄弱的话会造成资损
2.3.2 内部人员调用系统
内部人员根据系统漏洞,模拟异步通知结果混淆当前系统,将本不该处理的订单处理状态,引发后续一系列操作,可能会造成资损。
2.3.3 人为修改数据库
如果数据库人为修改出金金额或者状态等关键信息,如果不能识别的话会造成资损
-
人工处理
人工处理异常订单时往往跟系统自动处理的逻辑不一致,导致有可能会重复处理业务,或者在人工处理时与系统自动处理并发导致资损。
-
解决方法
-
唯一商户订单号
-
防重表或数据库对商户号+商户订单号做唯一索引约束,控制请求的是否重发
-
解决并发问题
基于redis分布式锁
基于数据库排他锁
增加审核机制,人工排除并发,然后再进行后续处理
-
白名单
系统白名单,重点系统交互比如在异步通知回调接口要识别回调报文的来源,对指定的Ip断才认为是合法的。
业务白名单,重点业务对重要标识比如交易双方、业务主体等做的白名单,控制业务的影响范围。
-
风控黑名单或商户授权联动控制
通过风控系统或者商户控制中心对发现的可疑商户及时制止交易,联动业务系统,达到防止资金损失的效果。
-
订单、流水和状态
业务逻辑处理中为减少失误,需要依赖两个点,一个是订单、流水,另一个是状态。订单记录了一笔业务的详细信息,状态是订单状态,描述的是业务处理过程中的某个点,流水是资金变化的依据。处理过程中做能做哪些事情由当前和相邻状态决定,资金操作以之前的资金流水为依据判断是否可以执行。
-
防篡改
接口请求需登录,请求报文加时间戳和签名。
数据库对重要记录加签存储,做业务前判断。
结合白名单,拒绝接受不明请求。
-
预防和监控
-
事前
-
事前监控主要是功能在上生产环境前的一系列测试,包括开发人员自测测试人员测试和生产模拟环境测试,任何改动都不能不经测试直接放生产环境。
开发完成后要对做单元测试和接口测试。单元测试可以保证重点逻辑各个分支处理的准确性,接口测试可以保证整个业务大体的贯通。
测试人员结合用例进行充分的功能测试和集成测试。
生产模拟环境测试要测试通过。
-
事中
出金前检查资金链路,一旦有问题,立即熔断,标识异常,拒绝出金,后续由人工介入处理。
数据库日志监控,根据数据库日志,检测到人为变更时,做关联的检查,资金链路有问题时会触发报警提示。
-
事后
系统上下游之间的对账。正常情况下交互的系统间调用是一一对应的,对于发生异常或是由于通讯等原因双方有未完成状态的需要进行系统对账。
资金流和信息流关于出入金汇总对账。这种对账可以从宏观上把控资金往来的准确性,能够发现多入金或者多出金的情况。