商品 120 元,先打了八折变成 96,再用满 100 减 20 的券,系统照样减了 20。财务对账发现这类订单一天有三十多笔,券成本超了预算。乍看像缓存或者权限的锅,追下去往往不是。

$base = $subtotal - $itemDiscount; // 折后金额
if ($base >= $coupon->threshold) {
    $discount = min($coupon->amount, $base);
}

追下去是这么回事:门槛判断取的是商品原价小计,没有扣掉前面的商品折扣。券和折扣的结算顺序没有定义清楚,各段代码各取各的金额。

「优惠券门槛计算」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

偶发问题先统计频率,一小时几次和一天一次,查法完全不同。

具体做法是,结算固定顺序为商品折扣、券、运费、积分,每一步都基于上一步的结果;门槛判断统一用扣掉商品折扣后的金额,别再用原价小计;券的配置页写清楚门槛按哪个金额算,前后端共用同一个接口返回值。

验收就看一点,同样 120 打八折的订单,券不再生效,页面提示还差 4 元可用。

作者 9823189