项目开发中安全问题及解决方法-----资金处理一定要幂等

任何资金操作都需要在平台侧生成业务属性的订单,可以是优惠券发放订单,可以是返现订单,也可以是借款订单,一定是先有订单再去做资金操作。 一定要做好防重,也就是实现幂等处理,并且幂等处理必须是全链路的。

//错误:每次使用UUID作为订单号
@GetMapping("wrong")
public void wrong(@RequestParam("orderId") String orderId) {
 PayChannel.pay(UUID.randomUUID().toString(), "123", new BigDecimal("100"));
}
//正确:使用相同的业务订单号
@GetMapping("right")
public void right(@RequestParam("orderId") String orderId) {
 PayChannel.pay(orderId, "123", new BigDecimal("100"));
}
//三方支付通道
public class PayChannel {
 public static void pay(String orderId, String account, BigDecimal amount) {
 ...
 }
}

对于支付操作,我们一定是调用三方支付公司的接口或银行接口进行处理的。一般而言,这些接口都会有商户订单号的概念,对于相同的商户订单号,无 法进行重复的资金处理,所以三方公司的接口可以实现唯一订单号的幂等处理。但是,业务系统在实现资金操作时容易犯的错是,没有自始至终地使用一 个订单号作为商户订单号,透传给三方支付接口。出现这个问题的原因是,比较大的互联网公司一般会把支付独立一个部门。支付部门可能会针对支付做 聚合操作,内部会维护一个支付订单号,然后使用支付订单号和三方支付接口交互。最终虽然商品订单是一个,但支付订单是多个,相同的商品订单因为 产生多个支付订单导致多次支付。如果说,支付出现了重复扣款,我们可以给用户进行退款操作,但给用户付款的操作一旦出现重复付款,就很难把钱追 回来了,所以更要小心。这,就是全链路的意义,从一开始就需要先有业务订单产生,然后使用相同的业务订单号一直贯穿到最后的资金通路,才能真正 避免重复资金操作。 总之,对于涉及到的资金业务我们必须要做到防刷、限量和防重

你可能感兴趣的:(分布式项目调优,前端)