后端、接口与数据 · 综合
和钱打交道:支付与扣款
一句话: 永远不要存卡信息、永远不要相信从客户端传来的金额,并且永远保留一份不可变的事件日志。
责任的划分
支付服务商处理卡;你处理订单。卡信息在服务商的表单或一个隔离的组件里输入,你这边只存一个标识。这能让你避开大部分沉重的合规世界。
金额在服务端根据你的价目计算。从客户端传来的金额是一个请求,不是一个事实。
用状态,不用标志位
订单要走过明确的状态:已创建、待支付、已支付、失败、已退款。每一次状态转移都带时间和原因记录下来。一个布尔型的「已支付」标志位,恰好在你需要它的时候丢掉了整个故事。
支付服务商的通知会乱序到达,有时还会到两次。按事件标识来处理,并做到可以安全地重复。
对账
建一个每日流程,把你的记录和服务商的报表做比对。差异总会出现;问题只在于是你先发现,还是客户先发现。
深入一层
金额要用最小单位的整数存储,绝不用浮点小数,并且始终带上币种代码。也要存下汇率和实际展示给用户的价格——这些是任何争议和任何报表里都会需要的数据。