PHP实现根据购物车小计禁用配送方式问题排查
问题排查与解决方案
核心问题分析
你的代码在可变产品场景下失效,主要有3个关键原因:
- 小计计算未覆盖所有折扣:
get_cart_contents_total()仅计算商品级折扣,不包含购物车优惠券折扣。当可变产品搭配购物车优惠券使用时,实际折扣后小计低于99,但代码获取的数值仍高于阈值,导致判断逻辑失效。 - 配送方式缓存未更新:WooCommerce默认缓存配送方式,购物车内容变化(如添加可变产品、修改属性、使用优惠券)时,缓存不会自动清除,旧的配送方式会持续显示。
- 钩子优先级过低:如果有其他插件也在修改配送方式,你的代码(默认优先级10)可能被覆盖,导致逻辑不生效。
修正后的代码
// 根据折扣后购物车小计禁用WooCommerce配送方式 function wpsh_hide_shipping_based_on_subtotal( $rates, $package ) { // 获取包含所有折扣的不含税小计(商品折扣+购物车优惠券) $cart_subtotal = WC()->cart->get_subtotal() - WC()->cart->get_discount_total(); // 按阈值分类需要隐藏的配送方式ID $hide_below_99 = ['flat_rate:76', 'local_pickup:79']; $hide_above_99 = ['flat_rate:73', 'flat_rate:75', 'local_pickup:69']; if ( $cart_subtotal < 99 ) { foreach ( $hide_below_99 as $rate_id ) { if ( isset( $rates[$rate_id] ) ) { unset( $rates[$rate_id] ); } } } else { foreach ( $hide_above_99 as $rate_id ) { if ( isset( $rates[$rate_id] ) ) { unset( $rates[$rate_id] ); } } } return $rates; } // 提高优先级,确保在其他插件之后执行 add_filter( 'woocommerce_package_rates', 'wpsh_hide_shipping_based_on_subtotal', 20, 2 ); // 清除配送方式缓存,购物车变化时重新计算 function wpsh_clear_shipping_cache() { if ( WC()->session ) { // 清除所有包裹的配送缓存 foreach ( WC()->session->get('shipping_packages') as $key => $package ) { WC()->session->set( 'shipping_for_package_' . $key, null ); } } } add_action( 'woocommerce_cart_contents_changed', 'wpsh_clear_shipping_cache' ); add_action( 'woocommerce_applied_coupon', 'wpsh_clear_shipping_cache' ); add_action( 'woocommerce_removed_coupon', 'wpsh_clear_shipping_cache' );
额外排查点
- 多包裹场景适配:如果店铺启用多包裹配送(如可变产品不同属性来自不同仓库),请将
$cart_subtotal替换为$package['contents_cost'],确保每个包裹的配送方式判断基于自身商品成本。 - 配送方式ID验证:确认配送方式ID是否正确,可通过浏览器开发者工具查看配送选项的
value属性,或在WooCommerce后台的配送设置中查看ID。
内容的提问来源于stack exchange,提问作者pitijk
相关产品推荐
相关产品推荐

