如何避免WooCommerce购物车中捆绑产品的补贴重复计算?
问题:捆绑产品导致配送补贴重复计算
以下代码用于基于购物车商品的配送类(shipping class)和数量计算并显示补贴总额:
/** * Utility function: Get shipping class subsidy amount * * @return float */ function get_shipping_class_subsidy_amount( $shipping_class ) { // 针对'12-50'配送类返回固定补贴 if ( false !== strpos($shipping_class, '12-50') ) { return 12.5; } // 从配送类别名中提取整数作为补贴金额 else { return preg_replace('/\D/', '', $shipping_class); } } /** * Utility function: Get total subsidies amount * * @return float */ function get_total_subsidies( $cart_items ){ $total_subsidy = 0; // 初始化补贴总额 // 遍历购物车商品 foreach ( $cart_items as $item ){ $subsidy = (float) get_shipping_class_subsidy_amount( $item['data']->get_shipping_class() ); $price = get_post_meta($values['product_id'] , '_price', true); if ( $subsidy > 0 ) { $total_subsidy += $item['quantity'] * $subsidy; } } return $total_subsidy; } /** * 在购物车页和结算页显示格式化后的补贴总额 * 钩子函数 */ function display_total_subsidies() { if ( $total_subsidy = get_total_subsidies( WC()->cart->get_cart() ) ) { echo '<tr class="subsidies"> <th>' . esc_html__( '补贴', 'woocommerce' ) . '</th> <td data-title="' . esc_html__( '补贴', 'woocommerce' ) . '">' . wc_price($total_subsidy) . '</td> </tr>'; } } add_action ( 'woocommerce_cart_totals_before_shipping', 'display_total_subsidies', 10 ); // 购物车页钩子 add_action ( 'woocommerce_review_order_before_shipping', 'display_total_subsidies', 10 ); // 结算页钩子
当前问题
当购物车中包含捆绑产品时,补贴金额会被重复计算——代码同时计入了捆绑产品本身及其组件商品的补贴,但正确逻辑应该只计算捆绑产品的补贴。
补充说明
- 无补贴场景截图:

- 错误计算场景截图:

错误计算结果包含了不应计入的单个组件商品12.5补贴,以及完整捆绑产品的80补贴,原因是代码同时统计了捆绑产品的每个组件和捆绑产品本身的补贴,而正确逻辑应该只统计完整捆绑产品的补贴。
解决方案
修改get_total_subsidies函数,添加判断跳过捆绑产品的组件商品,同时修正原代码中的变量错误:
/** * Utility function: Get total subsidies amount * * @return float */ function get_total_subsidies( $cart_items ){ $total_subsidy = 0; // 初始化补贴总额 // 遍历购物车商品 foreach ( $cart_items as $item ){ // 跳过捆绑产品的组件商品(适配WooCommerce Bundles插件) if ( isset( $item['bundled_by'] ) || isset( $item['bundle_item'] ) ) { continue; } $subsidy = (float) get_shipping_class_subsidy_amount( $item['data']->get_shipping_class() ); // 修正原代码中未定义的$values变量,替换为当前购物车项$item $price = get_post_meta( $item['product_id'], '_price', true ); if ( $subsidy > 0 ) { $total_subsidy += $item['quantity'] * $subsidy; } } return $total_subsidy; }
关键修改点
- 跳过组件商品:通过检查购物车项中的
bundled_by或bundle_item字段(WooCommerce Bundles插件的标准标识),判断商品是否为捆绑产品的组件,若是则跳过补贴计算 - 修复变量错误:将原代码中未定义的
$values['product_id']替换为正确的$item['product_id']
内容的提问来源于stack exchange,提问作者Eduardo Relax
相关产品推荐
相关产品推荐

