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

WooCommerce按商品数量调整运费:拆分包裹或运费倍数计算问题

WooCommerce 按配送类别+商品数量处理配送包裹问题

已实现通过配送类别拆分WooCommerce购物车为独立配送包裹的功能,代码如下:

add_filter( 'woocommerce_cart_shipping_packages', 'split_shipping_packages_by_shipping_class' ); 
function split_shipping_packages_by_shipping_class( $packages ) { 
   $destination = $packages[0]['destination'];  
   $user = $packages[0]['user']; 
   $applied_coupons = $packages[0]['applied_coupons']; 
   $packages = array(); 
   foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {     
      $key = $cart_item['data']->get_shipping_class_id(); 
      $packages[$key]['contents'][$cart_item_key] = $cart_item; 
   } 
   foreach ( $packages as $index => $package ) { 
      $total = array_sum( wp_list_pluck( $packages[$index]['contents'], 'line_total' ) ); 
      $packages[$index]['destination'] = $destination; 
      $packages[$index]['user'] = $user; 
      $packages[$index]['applied_coupons'] = $applied_coupons; 
      $packages[$index]['contents_cost'] = $total; 
   } 
   return $packages; 
}

现在需要额外实现将多数量商品拆分为独立包裹,或按商品总数量乘以运费费率的功能。尝试的代码无法正确获取包裹内商品总数量,仅当硬编码数量时生效。


问题原因

之前的代码中$numer_of_items = (int) sizeof($package['contents']);获取的是包裹内的商品条目数(即不同购物车项的数量),而非商品总数量。比如一个商品购买3件,这个值会是1,但实际总数量是3,导致计算错误。


方案一:按商品总数量乘以运费费率

修改woocommerce_package_rates钩子的代码,正确计算包裹内的商品总数量:

add_filter( 'woocommerce_package_rates', 'shipping_cost_based_on_total_item_quantity', 10, 2 ); 
function shipping_cost_based_on_total_item_quantity( $rates, $package ) { 
    // 计算包裹内商品总数量
    $total_quantity = 0;
    foreach ( $package['contents'] as $cart_item ) {
        $total_quantity += $cart_item['quantity'];
    }

    // 避免数量为0的异常情况
    if ( $total_quantity <= 0 ) {
        return $rates;
    }

    // 遍历所有配送费率,按总数量计算费用
    foreach ( $rates as $rate_key => $rate ){
        $has_taxes = false;
        $taxes = array();

        // 更新配送成本
        $rates[$rate_key]->cost = $rate->cost * $total_quantity;

        // 更新税费(如果有)
        foreach ( $rate->taxes as $key => $tax ){
            if( $tax > 0 ){
                $taxes[$key] = $tax * $total_quantity;
                $has_taxes = true;
            }
        }

        if( $has_taxes ){
            $rates[$rate_key]->taxes = $taxes;
        }
   } 
   return $rates; 
}

方案二:将多数量商品拆分为独立包裹

修改woocommerce_cart_shipping_packages钩子的代码,在按配送类别拆分的基础上,把多数量的商品拆成单个包裹:

add_filter( 'woocommerce_cart_shipping_packages', 'split_shipping_packages_by_shipping_class_and_quantity' ); 
function split_shipping_packages_by_shipping_class_and_quantity( $packages ) { 
   $destination = $packages[0]['destination'];  
   $user = $packages[0]['user']; 
   $applied_coupons = $packages[0]['applied_coupons']; 
   $packages = array(); 

   foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {     
      $shipping_class_id = $cart_item['data']->get_shipping_class_id();
      $quantity = $cart_item['quantity'];

      // 按商品数量拆分,每个数量对应一个包裹
      for ( $i = 0; $i < $quantity; $i++ ) {
          // 复制购物车项,数量改为1
          $single_item = $cart_item;
          $single_item['quantity'] = 1;
          // 计算单个商品的金额
          $single_item['line_total'] = $cart_item['line_total'] / $cart_item['quantity'];
          $single_item['line_subtotal'] = $cart_item['line_subtotal'] / $cart_item['quantity'];

          // 用配送类别ID+索引作为包裹键,避免冲突
          $package_key = $shipping_class_id . '_' . $i;
          $packages[$package_key]['contents'][$cart_item_key . '_' . $i] = $single_item;
      }
   } 

   foreach ( $packages as $index => $package ) { 
      $total = array_sum( wp_list_pluck( $packages[$index]['contents'], 'line_total' ) ); 
      $packages[$index]['destination'] = $destination; 
      $packages[$index]['user'] = $user; 
      $packages[$index]['applied_coupons'] = $applied_coupons; 
      $packages[$index]['contents_cost'] = $total; 
   } 

   return $packages; 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 12:52:42