Woocommerce复杂运费规则问题:特定配送方式按需显示
WooCommerce 运费规则配置:仅在购物车含Gazebo时显示指定配送方式
背景信息
已配置的运费规则如下:
基础商品运费规则
| 消费金额 | 运费 |
|---|---|
| 低于300美元 | 30美元 |
| 300美元及以上 | 免费 |
大件商品及特殊配送规则
| 商品 | Shipping Class | 费用 |
|---|---|---|
| large box | Truck with crane | 1000美元 |
| large Box | Truck only | 200美元 |
| Gazebo(选项1:仅配送) | Delivery & Assembly | 200美元 |
| Gazebo(选项2:配送及组装) | Delivery & Assembly | 350美元 |
当前基础商品和大箱商品的运费规则正常生效,但**「Shipping With Assembly」配送方式会在购物车无对应Shipping Class商品时仍显示**,需求是仅当购物车包含Gazebo商品时才显示该配送方式。
现有未完成代码
add_filter( 'woocommerce_package_rates', 'hide_shipping_when_class_is_in_cart', 100, 2 ); function hide_shipping_when_class_is_in_cart( $rates, $package ) { $free_shipping_method = 'free_shipping:13'; $shipping_classes = array('truck-crane','large-furniture','furniture-assembly'); $class_exists = false; $cart_classes = array(); $shipping_methods = $shipping_zone->get_shipping_methods(); foreach( $package['contents'] as $cart_item ) $cart_item_class = $cart_item['data']->get_shipping_class(); if( in_array($cart_item_class , $shipping_classes ) ) {//Check if any shipping class exist array_push($cart_classes,$cart_item_class); //push cart classes to array $class_exists = true; //break; } foreach($shipping_methods as $method){ $method_classes = $method->get_shipping_classes(); //Here i want to unset shipping methods which has no avaiable class in cart items } if( $class_exists ) unset( $rates[$free_shipping_method] ); return $rates; }
修复后的代码
以下代码直接实现需求,同时保留你原有的免费运费逻辑:
add_filter( 'woocommerce_package_rates', 'hide_assembly_shipping_unless_gazebo_present', 100, 2 ); function hide_assembly_shipping_unless_gazebo_present( $rates, $package ) { // 1. 配置参数:替换为你的实际信息 $assembly_shipping_id = 'flat_rate:XX'; // 「Shipping With Assembly」配送方式ID $target_shipping_class = 'delivery-assembly'; // Gazebo对应的Shipping Class slug $free_shipping_method = 'free_shipping:13'; // 原免费配送方式ID $exclude_free_shipping_classes = array('truck-crane','large-furniture','furniture-assembly'); // 2. 检查购物车是否有Gazebo对应的Shipping Class $has_gazebo = false; foreach ( $package['contents'] as $cart_item ) { if ( $cart_item['data']->get_shipping_class() === $target_shipping_class ) { $has_gazebo = true; break; } } // 3. 无Gazebo时隐藏「Shipping With Assembly」 if ( !$has_gazebo && isset( $rates[$assembly_shipping_id] ) ) { unset( $rates[$assembly_shipping_id] ); } // 4. 保留原有逻辑:特定商品类存在时隐藏免费配送 $exclude_free_shipping = false; foreach( $package['contents'] as $cart_item ) { $item_class = $cart_item['data']->get_shipping_class(); if( in_array($item_class, $exclude_free_shipping_classes ) ) { $exclude_free_shipping = true; break; } } if( $exclude_free_shipping && isset( $rates[$free_shipping_method] ) ) { unset( $rates[$free_shipping_method] ); } return $rates; }
关键配置说明
- 获取配送方式ID:
进入WooCommerce后台 → 配送 → 配送区域,找到「Shipping With Assembly」,鼠标悬停在编辑按钮上,地址栏会显示类似post=123&action=edit,其中123是ID,配送方式ID格式为flat_rate:123(如果是固定费率)或对应类型前缀。 - 确认Shipping Class Slug:
进入产品 → 运输类别,找到「Delivery & Assembly」,查看其slug(系统内部标识,通常是小写字母加短横线),替换代码中的$target_shipping_class。 - 生效步骤:
修改代码后,进入WooCommerce后台 → 系统状态 → 工具,点击「清除WooCommerce缓存」,同时清空浏览器缓存,测试购物车场景验证效果。
内容的提问来源于stack exchange,提问作者Ibtekarlabs
相关产品推荐
相关产品推荐

