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

在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 = '&nbsp;<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
        );
    }
}

关键修改说明

  1. 目标分类设置:在函数开头定义$target_categories数组,替换成你需要生效的商品分类slug,支持多个分类
  2. 分类判断逻辑:使用has_term()函数检查商品是否属于目标分类(支持检测父分类)
  3. 数量累加:初始化$total_qualified_qty变量,遍历中累加符合条件的商品总数量
  4. 费用计算:根据累加的总数量乘以单件费用,生成最终费用
  5. 代码优化:修复了原代码中循环变量覆盖的问题,同时给函数重命名更贴合功能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 21:15:36