以下指南,都是作为过来人,曾经踩过或者了解到身边的同事真实踩过的坑,希望对一些即将步入金融金融电商支付等相关行业,和刚刚踏入关行业的兄弟一些启示和帮助!
1.金融系统对金额的处理用bigdecimal,并指定小数位
对于有一些有金融相关经验的人会知道,在进行金额处理时,尽量不要用double,float 因为会精度丢失,可能导致计算错误,应该用bigdecimal,但这依然不能阻止你踩坑,因为你too yang too simple!
其实bigdecimal使用不当依然为精度丢失(不举例了网上搜索吧,大把大把的!),这里要告诉大家处理方法:“指定小数位”!,希望你不要再在这里踩了!
2.对接口的金额字段要反复确认金额单位
总有那么些人,不太喜欢动脑子,哈哈,拿到了接口后(比如代付接口),想都不想,就把金额传进了接口的金额字段,殊不知人家是要求传元,你给的是分啊!!! 你把500分传入接口,三方付了500元啊,用户心想(好开心呐...)
所以告诫大家,看到有金额的接口,一定要确认金额的单位(包括返回金额)!
3.对交易接口的状态,要反复确认哪个字段代码交易状态
例如有如下三方接口的返回报文
{
"success": true,
"result": {
"status": "0",
"amt": "100.00"
.....
}
}
status=0代表业务失败
如果接口对接的人不确认什么情况下代码业务成功,自以为success=true为成功,返回上文的报文为业务失败,最终有可能导致资损。
上面的返回,经与接口提供者确认,success字段仅代表,此次请求的通讯状态,不代表业务状态,如果这次的请求是一次商品申购的代扣请求,想一想,钱没有扣到用户的,商品可能已经发货了!!!
4.对会返回交易金额的接口,一定要确认交易会不会存在部分金额成功的情况
在部分的业务场景下,会存在申请金额跟确认金额不一致的情况(可以部分成功),这个时候如果我们调用三(二)方接口时,不注意接口返回的金额,直接通过接口交易状态是否成功来确定后续的处理,很容易产生资损。
如果确认交易接口不会存在部分成功,但是接口又返回了金额字段时,我们可以在业务逻辑确认业务状态成功后,再次核对申请金额,跟确认金额是是否一致,来保证交易完全成功!
5.交易接口一定要做幂等处理!
这个很很很重要!!!,如果不知道什么叫幂等性赶紧去百度(不对是Google)! 你想想如果一笔交易不做幂等处理,如果是一笔代付(提现)在并发场景下,被N次调用,结果付给用户N次,用户心想(好开心呐...)
将来不管是你调别人的api还是你要提供api给别人,请记住务必保证接口幂等,这样“你好它也好”。。。
6.异步回调接口一定要做幂等处理!
这个也很很很重要!!!, 永远不要相信,“一笔交易只会回调一次或者失败交易不会回调”这样的鬼话。因为真的会发生一笔交易回调请求多次的情况!
1).幂等要做 2).如果调用方说失败不会回调,一定要加上失败回调的逻辑 3).如果调用方说成功不会回调,一定要加上成功回调的逻辑
参考:三方支付接口之异步代扣接口的正确开发方法(线上填坑的总结)
7.异常订单的补尝机制(查询补单)
接口调用过程中,发生异常,调用超时等问题是很正常的,有些场景下我们可能做一些补尝处理,例如查询补单。
查询补单是指,订单在交易过程中发生异常,生产了交易结果未知的中间状态,这时就可以借助三方(二方)提供的查询接口,再次确认原订单的结果,跟据结果做一些补单等补尝操作。这里有一点要重点关注,就是确认,三方的查询接口有没有查询时间限制,有些三方的接口,在交易后,不能立即查询,可能需求等几分钟后可操作(可能是同步问题),如果我们提前查询,接口返回订单不存在的响应,导致后续的处理都会出错!
8.禁止在带有事务的接口中,请求三方,二方接口,或者嵌套复杂耗时的逻辑
有时事务方法中的update等操作之前会需要请求三方,用三方返回的结做update,就会发生,如果三方接口性能有问题,长时间不返回导致整个事务不能提交占着数据库连接不放,最终当请求量大的时候,导致数据库资产不够用,有可能引发系统宕机。
9.后端一定要对前端代入的金额做校验
这里讲的校验,不是讲校验前端传进来的金额的合法性(当然这也很有必要),这里说的是其它场景,我举例:
有一个申购接口,接口可以使用支付代金券,抵扣一部分支付本金,接口设计为,前端会把代金券的面值传入后端,后端就直接做了抵扣,结果因为数据被篡改或者前端传入等原因导致 ,明明代金券面值是1元,接口转入的是100元,导致本金少扣除99元,从而产生资损的严重生产事故。
正确的处理方案:
1,代金券的面值不要从接口传入,只传代金券id ,后台通过id查询面值使用。
2,代金券的面值和id都传入,后台仍要通过id查询面值,跟接口传入面值做个校验,确保一致。
10.持续更新中。。。。