You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce仅收取两类最高运费的自定义函数故障排查

解决WooCommerce仅收取两类最高运费配送类别费用的问题

原函数的核心错误

你的自定义函数逻辑完全偏离需求,问题出在以下几点:

  1. 混淆配送方式与配送类别:woocommerce_package_rates钩子中的$rates参数是当前配送区域下的配送方式列表(比如「标准配送」「次日达」),而非商品的配送类别运费。你错误地将其当作配送类别运费处理,试图保留两个最高的配送方式,而非修改单个配送方式的运费计算逻辑。
  2. 错误返回过滤数组:最后返回$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 );

代码说明

  1. 遍历配送方式:逐个处理每个配送方式,跳过免费配送。
  2. 收集配送类别运费:提取购物车中所有商品的配送类别,获取每个类别在当前配送方式下的运费,同一类别只保留一次。
  3. 计算最高两类运费:如果配送类别超过2个,按运费降序排序后取前两个求和。
  4. 更新运费与税费:将配送方式的运费替换为计算后的总和,并按原比例更新税费。
  5. 刷新缓存:标记配送方式已更新,避免WooCommerce缓存旧的运费数据。

内容的提问来源于stack exchange,提问作者Alex Banks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 15:20:22