支付系统风险总结

造成资金损失风险原因

网络异常问题

当支付系统调用银行系统后,接口因网络原因发生异常,支付系统未到达最终状态,
使用try catch处理后一般会走失败分支。
但银行侧的最终状态可能是成功、失败、或处理中、但是商户侧走失败分支后,可能会触发重试机制造成重复出款。
网络异常包括(Connection Reset 、Connection Refuse、The target server failed to respond、Connection Timed Out、Socket Read Timed Out等)
当遇到这些异常后,将订单设置为处理中的状态,然后等待设置的定时轮询或者通知机制查询这些订单的最终状态即可。

查询和通知问题

支付接口一般包括交易接口、主动查询接口、异步通知接口
用于查询非实时返回的订单最终状态的接口、或者核对查询

订单结果查询失败或者查询异常

代表查询操作失败而不是交易失败

查询频率过快

为了保证订单快速的得到支付结果,请求后立即主动查询交易结果,第三方系统返回无此订单导致补偿机制重复付款,需要将查询请求推后。

被查询接口幂等性问题

需注意银行侧查询接口是否为幂等性接口,不能保证银行侧幂等性的情况下、需要在商户侧系统设置想应处理。

通知问题

当前后两次通知情况不一致时,以第一次结果为准、出现不一样的情况后、人为进行干预。

接口幂等性问题

重试机制需要严格保证接口幂等性的情况下才能设置,后端对于重复提交的情况一般以订单流水号作为唯一索引做幂等,例如数据库出现重复订单号抛出异常、在请求入口处用Redis做防重复。

状态同步问题

支付系统依赖于下游系统、支付订单的最终状态也依赖于下游系统,但是每家系统返回的报文都有差异,需要注意

  1. 对于查询接口返回订单不存在的情况,需要单独设置响应码,做特殊报警处理,付款类的交易不可以直接设置为失败状态,避免重复支付。
  2. 资金类的订单设置的状态是根据第三方响应码来设置的,订单的状态要采用保守策略,对于不确定的状态,不可以直接设置为失败状态、避免重复支付。
  3. 系统崩溃后,redis或者MQ丢失瞬时处理的数据,可能也会导致重复支付

重复提交问题

  • 多线程、集群、定时器、手工操作的情况下,都可能导致并发问题
  • 表单重复提交,连续点击、网速过慢时点击了两次提交按钮都会导致重复提交问题
  • 重试机制导致的重复支付问题,Dubbo、Nginx、Http、中间件的retry都有重试机制,需要做好接口幂等性

重复提交解决方案

  • 禁提交按钮
  • 数据库加索引
  • redis加锁
  • token校验
    最有效最简单的方法:数据库乐观锁 + 有限状态机 + 白名单

有限状态机

又称为自动机,表示在有限个状态中转移的和动作的数学模型。
例如:成功的状态不能再变更为处理中、已发送的订单不允许再被支付
当支付的成功的订单避免被人工支付和定时任务同时处理需要做如下处理:
数据库乐观锁:通过版本号控制不被其他线程修改。
白名单 + 状态机:只有订单状态处于白名单允许的状态,才允许变更为要变更的状态。

其他风险点

  • 运营人员配置线上生产数据
  • 运维人员修改系统参数或者配置文件
    为避免这些问题,还需要机制流程、实时监控系统,做到事前的避免和事中的拦截,还需要事后止损机制。

你可能感兴趣的:(java基础)