Magento 2 的购物车价格规则不是只比较“优惠码正确”和“金额达到”。同一规则还会受网站、客户组、生效时间、用量、商品条件、购物车地址以及是否允许与其他规则叠加影响。排查时最好复制当前购物车,逐项缩小条件,而不是不断新建规则。
先确认代码命中了哪条规则
SELECT c.coupon_id, c.code, c.rule_id, c.usage_limit, c.usage_per_customer,
r.name, r.is_active, r.from_date, r.to_date, r.sort_order, r.stop_rules_processing
FROM salesrule_coupon c
JOIN salesrule r ON r.rule_id = c.rule_id
WHERE c.code = 'TEST2025';
如果返回多行,说明存在重复或历史规则,前端看到的提示未必来自你正在编辑的那条。先记录 rule_id,再在后台直接打开对应规则核对。
建立一个最小可用购物车
使用无痕窗口和专用客户,购物车只保留一个明确符合条件的简单商品。记录 SKU、网站、客户组、数量、折扣前小计、币种、配送国家。此时清除已应用代码后重新输入,避免 quote 中残留旧规则结果。
| 字段 | 实际参与判断的值 |
|---|---|
| 网站 | 当前 store 所属 website_id |
| 客户组 | 登录客户组或 NOT LOGGED IN |
| 小计 | 规则选择的含税/未税口径 |
| 地址 | 购物车的 shipping/billing address |
| 商品属性 | 用于促销条件的索引值和 Store View 值 |
检查网站和客户组映射
SELECT * FROM salesrule_website WHERE rule_id = 42;
SELECT * FROM salesrule_customer_group WHERE rule_id = 42;
SELECT website_id, code, name FROM store_website;
SELECT customer_group_id, customer_group_code FROM customer_group;
访客结账必须包含 NOT LOGGED IN 客户组。多网站环境中,Store View 相同并不代表 website_id 相同。
用量限制要同时看总量和客户量
SELECT coupon_id, times_used FROM salesrule_coupon WHERE code='TEST2025';
SELECT customer_id, rule_id, times_used
FROM salesrule_customer
WHERE rule_id=42 AND customer_id=123;
不要直接把 times_used 改成 0。先检查是否有取消、失败或重复订单导致计数与业务期望不同,并在测试环境复现订单生命周期。生产修正需要留下审计记录。
条件树从外到内拆开
复杂规则可复制为测试规则:先保留网站、客户组和优惠码,删除所有商品/购物车条件;确认能应用后,每次只加回一层。特别注意“满足全部”与“满足任一”、SKU 是否带空格、分类条件是否针对子商品、配送国家是否在用户填写地址后才可用。
如果代码在购物车可用,进入结账选择地址后消失,问题就在地址或配送条件;若输入即失败,则优先查基础规则、客户组和用量。打开浏览器 Network,检查 coupon POST 的响应消息,同时查看:
tail -f var/log/system.log var/log/exception.log
php bin/magento indexer:status
php bin/magento cache:clean config full_page
最后至少回归访客、登录客户、两个网站、一次成功订单和一次取消订单。促销规则修复的标准不仅是“代码能用”,还要确保不符合条件的购物车仍然不能获得折扣。

