后台某个 Source 显示还有 20 件,客户加入 1 件却提示 The requested qty is not available。Magento 2 的可购买判断使用当前 Website 所属 Stock 的 Salable Quantity,并结合购物车中已存在数量、最小/最大销售数量和库存阈值;它并不直接读取某一行 Source Quantity。

确认报错针对哪个 SKU

可配置、Bundle 和 Grouped 商品在页面上显示父 SKU,但库存校验可能发生在关联简单商品。记录选中的颜色、尺码或 Bundle 选项,找出最终 simple SKU。只有某个组合失败时,不要只检查父商品。

查看当前销售渠道的 Salable Quantity

先确认 Website 绑定的 Stock,以及 Stock 包含哪些 Source。可使用 Magento 库存命令或读取对应的库存索引:

bin/magento inventory:reservation:list-inconsistencies
SELECT sku, quantity, is_salable
FROM inventory_stock_1
WHERE sku='TEST-SKU';

inventory_stock_1 只是示例,实际表后缀应使用当前 Stock ID。索引 quantity 已经小于请求数量时,继续查 reservation、阈值和来源分配;索引正确而仍报错,再查购物车与插件。

购物车里的旧数量也会参与校验

客户购物车可能已经有同一 SKU,页面再次加入 1 件时,系统校验的是合并后的数量。迷你购物车缓存没有刷新,会让用户以为购物车为空。检查 active quote:

SELECT item_id, sku, qty, parent_item_id
FROM quote_item
WHERE quote_id=12345;

可配置父子行不能重复相加。自定义 Add to Cart 接口如果没有正确合并 buy request,可能创建多个行或传入异常小数数量。

Min/Max Sale Qty 与数量增量容易被忽略

Inventory 配置可以限定最小销售数量、最大销售数量和 Qty Increments。例如库存 20,但最大购买数为 5,购物车已有 5,再加 1 就会失败;商品要求每次按 6 的倍数购买,输入 1 同样不合法。配置可能按客户组生效,因此访客与批发客户结果不同。

Out-of-Stock Threshold 会预留安全库存

物理数量 5,阈值为 5 时,Salable Quantity 可能已经是 0。启用 Backorders 后计算又会不同。不要为了让商品可买就把阈值随意设成负数,这会改变全站超卖策略。

Reservation 不一致要按订单处理

取消、退款、导入订单或第三方 ERP 绕过标准流程,可能留下未补偿 reservation。先列出不一致并关联具体订单,再生成官方补偿。直接删除 reservation 会破坏其他未发货订单的预留。

修复后清空测试 Quote,分别加入简单商品、可配置子项和达到最大数量的商品;完成下单与取消,再观察 Source Quantity、Reservation 和 Salable Quantity 的变化。只有完整生命周期正确,错误才不会过几天再次出现。