WooCommerce仅收取两类最高运费的自定义函数故障排查
解决WooCommerce仅收取两类最高运费配送类别费用的问题
原函数的核心错误
你的自定义函数逻辑完全偏离需求,问题出在以下几点:
- 混淆配送方式与配送类别:
woocommerce_package_rates钩子中的$rates参数是当前配送区域下的配送方式列表(比如「标准配送」「次日达」),而非商品的配送类别运费。你错误地将其当作配送类别运费处理,试图保留两个最高的配送方式,而非修改单个配送方式的运费计算逻辑。 - 错误返回过滤数组:最后返回
$highest_rates会移除所有非最高的配送方式,同时由于对象引用的问题,in_array严格比较会匹配失败,导致所有运费被设为0。
正确解决方案
要实现「收取购物车中两类运费最高的配送类别费用」,需要修改单个配送方式的运费计算逻辑,将多个配送类别的运费总和替换为最高两类的运费之和。以下是修正后的代码:
function charge_for_two_highest_shipping_classes( $rates ) { // 遍历每个配送方式 foreach ( $rates as $rate_key => $rate ) { // 跳过免费配送方式 if ( $rate->cost == 0 ) continue; $shipping_class_costs = array(); $cart_items = WC()->cart->get_cart(); // 收集购物车中所有商品的配送类别及其对应运费(同一类别只保留一次) foreach ( $cart_items as $item ) { $product = $item['data']; $shipping_class_id = $product->get_shipping_class_id(); // 跳过无配送类别的商品 if ( empty( $shipping_class_id ) ) continue; // 获取当前配送方式下该配送类别的运费 $class_cost = $rate->get_shipping_class_cost( $shipping_class_id ); // 避免重复添加同一配送类别的运费 if ( ! isset( $shipping_class_costs[ $shipping_class_id ] ) ) { $shipping_class_costs[ $shipping_class_id ] = $class_cost; } } // 如果配送类别数量≤2,直接使用默认总和,无需修改 if ( count( $shipping_class_costs ) <= 2 ) { continue; } // 按运费从高到低排序配送类别 arsort( $shipping_class_costs ); // 取前两个最高运费相加 $top_two_costs = array_slice( $shipping_class_costs, 0, 2, true ); $total_cost = array_sum( $top_two_costs ); // 更新配送方式的运费 $rate->set_cost( $total_cost ); // 按原税费比例更新税费(可根据实际需求调整) if ( ! empty( $rate->taxes ) ) { $initial_cost = $rate->get_initial_cost(); $tax_rate = $initial_cost > 0 ? array_sum( $rate->taxes ) / $initial_cost : 0; $new_taxes = array_map( function( $tax ) use ( $tax_rate, $total_cost ) { return $total_cost * $tax_rate; }, $rate->taxes ); $rate->set_taxes( $new_taxes ); } // 标记配送方式已更新,刷新缓存 $rate->add_meta_data( 'shipping_method_updated', 'yes' ); $rate->save_meta_data(); } return $rates; } add_filter( 'woocommerce_package_rates', 'charge_for_two_highest_shipping_classes', 20, 1 );
代码说明
- 遍历配送方式:逐个处理每个配送方式,跳过免费配送。
- 收集配送类别运费:提取购物车中所有商品的配送类别,获取每个类别在当前配送方式下的运费,同一类别只保留一次。
- 计算最高两类运费:如果配送类别超过2个,按运费降序排序后取前两个求和。
- 更新运费与税费:将配送方式的运费替换为计算后的总和,并按原比例更新税费。
- 刷新缓存:标记配送方式已更新,避免WooCommerce缓存旧的运费数据。
内容的提问来源于stack exchange,提问作者Alex Banks
相关产品推荐
相关产品推荐

