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

基于商品ID隐藏WooCommerce结账页面自定义复选框

WooCommerce:特定商品加入购物车时无法隐藏自定义结账复选框

现有功能代码(结账页添加复选框并添加额外费用)

这段代码用于在WooCommerce结账页面添加一个复选框,勾选后会为订单增加30₾的包装费用:

add_action('woocommerce_after_checkout_billing_form', 'checkout_shipping_form_packing_addition', 20);
function checkout_shipping_form_packing_addition()
{
    $domain = 'woocommerce';

    echo '<tr class="packing-select"><th>' . __('სამაჯური', $domain) . '</th><td>';

    $chosen   = WC()->session->get('chosen_packing');

    // 添加自定义复选框字段
    woocommerce_form_field('chosen_packing', array(
        'type'      => 'checkbox',
        'class'     => array('form-row-wide packing'),
        'label'     => __('სამაჯურის ღირებულება 30₾', 'woocommerce'),
        'description' => __('აღნიშნული სერვისით სარგებლობისთვის საჭიროა სამაჯურის შეძენა, თუ გსურთ შეძენა, მონიშნეთ ეს ველი, თუ უკვე გაქვთ სამაჯური ან ადგილზე გადაიხდით სამაჯურის ღირებულებას დატოვეთ მონიშვნის გარეშე'),
        'required'  => false,
    ), $chosen);

    echo '</td></tr>';
}

// jQuery - Ajax 脚本
add_action('wp_footer', 'checkout_shipping_packing_script');
function checkout_shipping_packing_script()
{
    // 仅在结账页执行
    if (is_checkout() && !is_wc_endpoint_url()) :
    ?>
    <script type="text/javascript">
        jQuery(function($) {
            $('form.checkout').on('change', 'input#chosen_packing', function() {
                $.ajax({
                    type: 'POST',
                    url: wc_checkout_params.ajax_url,
                    data: {
                        'action': 'woo_get_ajax_data',
                        'packing': $(this).prop('checked') ? 1 : 0,
                    },
                    success: function(result) {
                        $('body').trigger('update_checkout');
                        console.log('response: ' + result); // 测试用,可删除
                    },
                    error: function(error) {
                        console.log(error); // 测试用,可删除
                    }
                });
            });
        });
    </script>
    <?php
    else:
    WC()->session->__unset('chosen_packing');
    endif;
}

// PHP Ajax(接收请求并保存到WC会话)
add_action('wp_ajax_woo_get_ajax_data', 'woo_get_ajax_data');
add_action('wp_ajax_nopriv_woo_get_ajax_data', 'woo_get_ajax_data');
function woo_get_ajax_data()
{
    if (isset($_POST['packing'])) {
        $packing = sanitize_key($_POST['packing']);
        WC()->session->set('chosen_packing', $packing);
        echo json_encode($packing);
    }
    die(); // 必须放在最后,避免500错误
}

// 添加自定义动态包装费用
add_action('woocommerce_cart_calculate_fees', 'add_packaging_fee', 20, 1);
function add_packaging_fee($cart)
{
    if (is_admin() && !defined('DOING_AJAX'))
        return;

    if( WC()->session->get('chosen_packing') ){
        $label = __('სამაჯური', 'woocommerce');
        $cost = 30;
        $cart->add_fee($label, $cost);
    }
}

尝试的无效代码(隐藏复选框)

尝试用以下代码在商品ID为15163的商品加入购物车时隐藏该复选框,但无效(该方法对标准账单字段有效,但对这个自定义复选框无效):

add_filter( 'woocommerce_checkout_fields' , 'disabling' );

function disabling($fields){
    $product_id = array(15163); // 触发隐藏的商品ID
    $in_cart = false;
    foreach( WC()->cart->get_cart() as $cart_item ) {
       $product_in_cart = $cart_item['product_id'];
       if ( $product_in_cart === $product_id ) $in_cart = true; // 检查商品是否在购物车中
    }
    if ( $in_cart ){
      unset($fields['billing']['chosen_packing']);
      unset($fields['shipping']['chosen_packing']);
  
      return $fields;
    }
    else {
      return $fields;
    }
}

问题原因及解决方案

问题原因

你尝试的代码无效,是因为这个自定义复选框并非通过woocommerce_checkout_fields过滤器注册的标准字段,而是直接通过woocommerce_after_checkout_billing_form钩子输出到页面的,所以无法通过unset($fields['billing']['chosen_packing'])来移除它。

解决方案

修改原来的checkout_shipping_form_packing_addition函数,先判断购物车中是否包含指定商品,再决定是否输出复选框:

add_action('woocommerce_after_checkout_billing_form', 'checkout_shipping_form_packing_addition', 20);
function checkout_shipping_form_packing_addition()
{
    // 检查购物车是否包含ID为15163的商品
    $target_product_id = 15163;
    $in_cart = false;
    foreach( WC()->cart->get_cart() as $cart_item ) {
        if ( $cart_item['product_id'] === $target_product_id ) {
            $in_cart = true;
            break;
        }
    }

    // 如果包含目标商品,直接返回,不输出复选框
    if ($in_cart) {
        return;
    }

    // 原有的复选框输出代码
    $domain = 'woocommerce';

    echo '<tr class="packing-select"><th>' . __('სამაჯური', $domain) . '</th><td>';

    $chosen   = WC()->session->get('chosen_packing');

    woocommerce_form_field('chosen_packing', array(
        'type'      => 'checkbox',
        'class'     => array('form-row-wide packing'),
        'label'     => __('სამაჯურის ღირებულება 30₾', 'woocommerce'),
        'description' => __('აღნიშნული სერვისით სარგებლობისთვის საჭიროა სამაჯურის შეძენა, თუ გსურთ შეძენა, მონიშნეთ ეს ველი, თუ უკვე გაქვთ სამაჯური ან ადგილზე გადაიხდით სამაჯურის ღირებულებას დატოვეთ მონიშვნის გარეშე'),
        'required'  => false,
    ), $chosen);

    echo '</td></tr>';
}

同时,为了避免用户在添加目标商品前已经勾选了复选框,还需要修改add_packaging_fee函数,确保购物车中有目标商品时不添加包装费用:

// 添加自定义动态包装费用
add_action('woocommerce_cart_calculate_fees', 'add_packaging_fee', 20, 1);
function add_packaging_fee($cart)
{
    if (is_admin() && !defined('DOING_AJAX'))
        return;

    // 检查购物车是否包含目标商品
    $target_product_id = 15163;
    $in_cart = false;
    foreach( $cart->get_cart() as $cart_item ) {
        if ( $cart_item['product_id'] === $target_product_id ) {
            $in_cart = true;
            break;
        }
    }

    // 如果没有目标商品且勾选了复选框,才添加费用
    if( !$in_cart && WC()->session->get('chosen_packing') ){
        $label = __('სამაჯური', 'woocommerce');
        $cost = 30;
        $cart->add_fee($label, $cost);
    }
}

这样修改后,当购物车中加入ID为15163的商品时,结账页的包装复选框会被隐藏,同时也不会再添加对应的包装费用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 03:54:54