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
相关产品推荐
相关产品推荐

