$rate = 7.123456; $cny = (int) ceil(19.99 * $rate * 100); // 单位分 // 落库 14233,页面展示 142.33
标价 19.99 美元的订单,按 7.12 的汇率算出来 142.3288,落库时被四舍五入成 142.32。渠道按 142.33 扣款,两边差一分,一个月累计差了三块多。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,换算只做了一次,且在不同环节各算一遍,PHP 的 round 和渠道的进位规则不一致。汇率有小数点后四位,先舍入汇率再相乘,误差会被放大。
围绕「多币种换算精度」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。备份不是备了就行,恢复一次才算数,很多备份文件打开才发现是空的。
接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。
处理上按这个顺序:汇率保留六位小数,换算后统一进位到分,规则和渠道文档写的一致;换算结果落库保存,退款和对账都用这个值,不再重新乘汇率;下单页把汇率和最终扣款金额一起展示给用户。
改完只确认一件事:同一笔 19.99 美元订单,页面显示、渠道扣款、订单表金额三者都是 142.33。
