在WooCommerce中按分类及商品数量添加复选框触发的可选费用
解决WooCommerce结账页面按商品分类添加自定义件费的问题
问题分析
你的现有代码存在两个核心问题导致无法按分类筛选商品:
- 循环遍历购物车商品时,每次都会覆盖
$quantity变量,最终只计算最后一件商品的数量 - 缺少商品分类判断逻辑,没有筛选出目标分类的商品
修改后的完整代码
// Add a custom checkbox fields after billing fields add_action( 'woocommerce_after_checkout_billing_form', 'add_custom_checkout_checkbox', 20 ); function add_custom_checkout_checkbox(){ // Add a custom checkbox field woocommerce_form_field( 'installment_fee', array( 'type' => 'checkbox', 'label' => __(' Faster ship'), 'class' => array( 'form-row-wide' ), ), '' ); } // Remove "(optional)" label on "Installement checkbox" field add_filter( 'woocommerce_form_field' , 'remove_order_comments_optional_fields_label', 10, 4 ); function remove_order_comments_optional_fields_label( $field, $key, $args, $value ) { // Only on checkout page for Order notes field if( 'installment_fee' === $key && is_checkout() ) { $optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>'; $field = str_replace( $optional, '', $field ); } return $field; } // jQuery - Ajax script add_action( 'wp_footer', 'checkout_fee_script' ); function checkout_fee_script() { // Only on Checkout if( is_checkout() && ! is_wc_endpoint_url() ) : if( WC()->session->__isset('enable_fee') ) WC()->session->__unset('enable_fee'); ?> <script type="text/javascript"> jQuery( function($){ if (typeof wc_checkout_params === 'undefined') return false; $('form.checkout').on('change', 'input[name=installment_fee]', function(e){ var fee = $(this).prop('checked') === true ? '1' : ''; $.ajax({ type: 'POST', url: wc_checkout_params.ajax_url, data: { 'action': 'enable_fee', 'enable_fee': fee, }, success: function (result) { $('body').trigger('update_checkout'); }, }); }); }); </script> <?php endif; } // Get Ajax request and saving to WC session add_action( 'wp_ajax_enable_fee', 'get_enable_fee' ); add_action( 'wp_ajax_nopriv_enable_fee', 'get_enable_fee' ); function get_enable_fee() { if ( isset($_POST['enable_fee']) ) { WC()->session->set('enable_fee', ($_POST['enable_fee'] ? true : false) ); } die(); } // Add a custom dynamic per-item fee for specific product categories add_action('woocommerce_cart_calculate_fees', 'custom_per_category_per_item_fee', 20, 1); function custom_per_category_per_item_fee($cart) { // Only on checkout if ((is_admin() && !defined('DOING_AJAX')) || !is_checkout()) return; // 1. 设置需要生效的商品分类slug(可自行修改) $target_categories = array('electronics', 'accessories'); $per_item_fee = 5; // 单件费用 $total_qualified_qty = 0; // 2. 遍历购物车商品,筛选目标分类的商品并累加数量 foreach ($cart->get_cart_contents() as $cart_item) { $product = $cart_item['data']; // 检查商品是否属于目标分类(支持父分类) if (has_term($target_categories, 'product_cat', $product->get_id())) { $total_qualified_qty += $cart_item['quantity']; } } // 3. 如果勾选了复选框且有符合条件的商品,添加费用 if (WC()->session->get('enable_fee') && $total_qualified_qty > 0) { $cart->add_fee( __('Make shipping faster', 'woocommerce') . " ($per_item_fee usd. per item)", $total_qualified_qty * $per_item_fee, false // 不需要含税,如需含税改为true ); } }
关键修改说明
- 目标分类设置:在函数开头定义
$target_categories数组,替换成你需要生效的商品分类slug,支持多个分类 - 分类判断逻辑:使用
has_term()函数检查商品是否属于目标分类(支持检测父分类) - 数量累加:初始化
$total_qualified_qty变量,遍历中累加符合条件的商品总数量 - 费用计算:根据累加的总数量乘以单件费用,生成最终费用
- 代码优化:修复了原代码中循环变量覆盖的问题,同时给函数重命名更贴合功能
内容的提问来源于stack exchange,提问作者Dmitry Suslenko
相关产品推荐
相关产品推荐

