三个单价 9.99 的商品,购物车税额显示 2.10,支付平台明细加起来却是 2.09。订单能创建,但支付端拒绝,因为 line items 合计与总金额不一致。“只差一分钱”如果靠强行修改 grand_total,会让发票、退款和财务对账继续错下去。
先保留未经格式化的原始金额
页面通常只显示两位小数,数据库和计算过程中可能保留更多精度。记录 quote 与 order 的 base_subtotal、discount、shipping、tax、grand_total 及对应非 base 字段,同时保存商品 qty、税率和是否含税。用相同数据在表格中逐行重算,找出第一次舍入的位置。
Unit Price、Row Total 与 Total 算法结果本来就可能不同
按单价计算会先对每个单件税额舍入,再乘数量;按行计算先乘数量,再对行税额舍入;按总计计算又在更高层聚合。多商品、多数量时差一分钱并不意外,关键是购物车、订单、发票和外部支付使用同一种事实。
后台 Tax Calculation Method、Catalog Prices 是否含税、Shipping Prices 是否含税、Apply Customer Tax 与折扣先后顺序都要按 Website 作用域核对。不要只截图一个配置项。
折扣分摊与多币种会再增加一次舍入
购物车折扣按比例分到每个 item 时,尾差必须落到明确行。base currency 换算为 order currency 后又会舍入。支付模块如果重新用显示金额计算明细,而不是使用订单已计算字段,就可能得到另一套结果。
外部支付明细必须可回算到订单总额
构建 line items 后,在发送前程序化断言:商品、运费、税、折扣合计等于请求总金额。若支付服务要求每行两位小数,设计明确的尾差分配规则,通常把差额落在最后一条合适项目,而不是悄悄修改订单。
用矩阵而不是单个订单验收
测试单件、多数量、多个税率、优惠券、含税价、运费税、多币种、部分发票和部分退款。每一步比较 quote、order、invoice、credit memo 与支付平台。允许的显示差异要有解释,提交和结算金额必须完全对得上。税额问题真正的终点是全生命周期可对账。

