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

WooCommerce:如何让产品变体支持自定义计算价格的动态设置

嘿,我懂你现在的需求——之前的代码只能给非变体产品加动态加价,现在要让变体产品也能用上这个功能对吧?我之前帮不少人处理过类似的WooCommerce定制需求,给你整理一套完整的解决方案,你可以照着改:

核心思路

变体产品的价格逻辑和普通产品不一样,它本身有自己的基础价格,所以我们得先获取用户选中的变体价格,再叠加用户输入对应的加价金额。而且必须前后端配合:前端负责实时显示价格和传递加价数据,后端负责验证和计算最终价格(防止前端篡改)。

修改后的完整代码示例

1. 前端产品页面交互代码(JS)

把这段代码加到你的产品页面模板里,或者通过主题的自定义JS功能添加:

document.addEventListener('DOMContentLoaded', function() {
    // 替换成你主题对应的选择器
    const variantSelector = document.querySelector('.single_variation_wrap');
    const userInputField = document.getElementById('custom-input'); // 用户输入的自定义字段ID
    const addToCartBtn = document.querySelector('.single_add_to_cart_button');

    let currentVariantPrice = 0; // 存储当前选中变体的基础价格

    // 监听变体选择事件,获取选中变体的价格
    if (variantSelector) {
        variantSelector.addEventListener('show_variation', function(event) {
            // 提取变体的纯数字价格
            currentVariantPrice = parseFloat(event.variation.display_price);
            // 实时更新页面显示的价格
            updateDisplayedPrice(currentVariantPrice);
        });
    }

    // 监听用户输入变化,实时更新价格
    userInputField.addEventListener('input', function() {
        updateDisplayedPrice(currentVariantPrice);
    });

    // 计算并更新页面显示的总价
    function updateDisplayedPrice(basePrice) {
        const inputValue = userInputField.value;
        const extraCharge = calculateExtraCharge(inputValue); // 你的加价计算逻辑
        const totalPrice = basePrice + extraCharge;
        // 更新价格显示元素(替换成你主题的价格选择器)
        const priceElement = document.querySelector('.woocommerce-Price-amount');
        if (priceElement) {
            priceElement.textContent = wc_price(totalPrice); // 用WooCommerce内置函数格式化价格
        }
    }

    // 点击加购时,把加价数据传递给购物车
    addToCartBtn.addEventListener('click', function(e) {
        const inputValue = userInputField.value;
        const extraCharge = calculateExtraCharge(inputValue);
        if (extraCharge > 0) {
            // 创建隐藏输入框传递数据
            const hiddenInput = document.createElement('input');
            hiddenInput.type = 'hidden';
            hiddenInput.name = 'custom_extra_charge';
            hiddenInput.value = extraCharge;
            document.querySelector('form.cart').appendChild(hiddenInput);
        }
    });

    // 这里替换成你原来的加价计算逻辑
    function calculateExtraCharge(inputValue) {
        // 示例:输入每1个字符加1美元
        if (!inputValue) return 0;
        return inputValue.length * 1;
    }
});

2. 后端价格处理代码(PHP)

把这段代码加到你的主题functions.php文件里,或者自定义插件中:

// 1. 将自定义加价数据添加到购物车项目
add_filter('woocommerce_add_cart_item_data', 'add_custom_extra_charge_to_cart_item', 10, 3);
function add_custom_extra_charge_to_cart_item($cart_item_data, $product_id, $variation_id) {
    if (isset($_POST['custom_extra_charge']) && !empty($_POST['custom_extra_charge'])) {
        $extra_charge = floatval($_POST['custom_extra_charge']);
        $cart_item_data['custom_extra_charge'] = $extra_charge;
        // 添加唯一键,确保不同输入的同变体产品在购物车中是独立项
        $cart_item_data['unique_key'] = md5(microtime() . rand());
    }
    return $cart_item_data;
}

// 2. 在购物车中显示自定义加价
add_filter('woocommerce_get_item_data', 'display_custom_extra_charge_in_cart', 10, 2);
function display_custom_extra_charge_in_cart($item_data, $cart_item) {
    if (isset($cart_item['custom_extra_charge']) && $cart_item['custom_extra_charge'] > 0) {
        $item_data[] = array(
            'key' => __('自定义加价', 'text-domain'),
            'value' => wc_price($cart_item['custom_extra_charge']),
            'display' => '',
        );
    }
    return $item_data;
}

// 3. 计算购物车和结账页的最终价格
add_action('woocommerce_before_calculate_totals', 'calculate_custom_extra_charge_in_cart', 10, 1);
function calculate_custom_extra_charge_in_cart($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    if (did_action('woocommerce_before_calculate_totals') >= 2) return;

    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        if (isset($cart_item['custom_extra_charge'])) {
            $extra_charge = $cart_item['custom_extra_charge'];
            // 给当前购物车项目叠加加价
            $cart_item['data']->set_price($cart_item['data']->get_price() + $extra_charge);
        }
    }
}

// 4. 将加价数据保存到订单,方便后续查看
add_action('woocommerce_checkout_create_order_line_item', 'save_custom_extra_charge_to_order', 10, 4);
function save_custom_extra_charge_to_order($item, $cart_item_key, $cart_item, $order) {
    if (isset($cart_item['custom_extra_charge']) && $cart_item['custom_extra_charge'] > 0) {
        $item->add_meta_data(__('自定义加价', 'text-domain'), wc_price($cart_item['custom_extra_charge']), true);
    }
}
关键注意事项
  • 选择器适配:代码中的DOM选择器(比如.single_variation_wrap、.woocommerce-Price-amount)需要根据你使用的WooCommerce主题调整,确保能正确获取到元素。
  • 价格格式:用parseFloat(event.variation.display_price)获取变体的纯数字价格,避免货币符号和千分位干扰计算。
  • 后端验证:绝对不能只依赖前端计算价格——前端数据可以被篡改,后端重新计算才能保证价格准确。
  • 文本域替换:把代码中的text-domain替换成你主题的文本域,或者直接留空''也可以正常使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:18:42