WooCommerce中基于单选按钮的商品阶梯折扣总计错误问题
WooCommerce阶梯折扣结账总计错误修复方案
问题根源
你的代码存在几个关键问题导致结账总计计算错误:
- AJAX改价范围错误:遍历整个购物车修改所有商品价格,而非仅针对含"Hydrogel"的目标商品
- 价格修改方式不可靠:直接调用
set_price()修改商品对象价格,WooCommerce结账时重新计算总计会覆盖这个临时修改 - HTML语法错误:单选按钮的
data-price属性缺少闭合引号,可能导致JS读取价格失败 - AJAX未传递商品标识:无法精准定位需要修改价格的购物车项
修复后的完整代码
function display_quantity_discount_message() { global $product; // 仅针对名称含"Hydrogel"的商品 if (strpos($product->get_name(), 'Hydrogel') !== false) { $discounts = array( 2 => 60, // 2件总价60 Lei 3 => 85, // 3件总价85 Lei ); echo '<div class="quantity-discount-message">'; echo '<p>Reducere:</p>'; echo '<ul>'; foreach ($discounts as $quantity => $total_price) { $original_total = $quantity * $product->get_price(); // 修复HTML引号闭合问题 echo '<li>'; echo '<input type="radio" name="quantity_discount" value="' . esc_attr($quantity) . '" data-total="' . esc_attr($total_price) . '"> '; echo 'Cumpără <span style="color:green; font-weight:bold;">' . $quantity . '</span> pentru doar <span style="text-decoration: line-through; color:red; font-weight:bold;">' . $original_total . '</span> <span style="color:red; font-weight:bold;">' . $total_price . ' Lei</span>'; echo '</li>'; } echo '</ul>'; echo '</div>'; wc_enqueue_js(' jQuery(document).ready(function($) { $("input[name=\'quantity_discount\']").change(function() { var selectedQty = parseInt($(this).val()); var selectedTotal = parseInt($(this).data("total")); $("input[name=\'quantity\']").val(selectedQty); $(" .single_add_to_cart_button").html("Adaugă în coș - " + selectedTotal + " Lei"); // 传递商品ID到AJAX,确保只修改目标商品 $.post(wc_cart_params.ajax_url, { action: "update_hydrogel_discount", product_id: ' . $product->get_id() . ', total_price: selectedTotal, quantity: selectedQty }, function(response) { $("body").trigger("update_checkout"); }); }); }); '); } } add_action('woocommerce_before_add_to_cart_button', 'display_quantity_discount_message'); // AJAX处理函数:存储折扣元数据到购物车项 add_action('wp_ajax_update_hydrogel_discount', 'update_hydrogel_discount'); add_action('wp_ajax_nopriv_update_hydrogel_discount', 'update_hydrogel_discount'); function update_hydrogel_discount() { if (isset($_POST['product_id'], $_POST['total_price'], $_POST['quantity']) && !empty(WC()->cart)) { $product_id = intval($_POST['product_id']); $total_price = floatval($_POST['total_price']); $quantity = intval($_POST['quantity']); // 遍历购物车,找到目标商品并更新 foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) { if ($cart_item['product_id'] == $product_id) { // 存储折扣总价和数量元数据 $cart_item['data']->add_meta_data('_hydrogel_discount_total', $total_price, true); // 更新购物车项数量 WC()->cart->set_quantity($cart_item_key, $quantity); break; } } WC()->cart->calculate_totals(); echo json_encode(['success' => true]); } wp_die(); } // 动态调整价格钩子:确保结账时正确计算总计 add_action('woocommerce_before_calculate_totals', 'apply_hydrogel_discount_to_cart'); function apply_hydrogel_discount_to_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) { // 检查商品名称和折扣元数据 if (strpos($cart_item['data']->get_name(), 'Hydrogel') !== false && $cart_item['data']->get_meta('_hydrogel_discount_total')) { $discount_total = floatval($cart_item['data']->get_meta('_hydrogel_discount_total')); // 计算单件折扣价(适配WooCommerce按单件计算总计的逻辑) $unit_price = $discount_total / $cart_item['quantity']; $cart_item['data']->set_price($unit_price); } } }
关键修复点说明
- 精准定位商品:AJAX请求传递商品ID,只修改目标Hydrogel商品的购物车项
- 持久化折扣数据:用
add_meta_data存储折扣总价,避免结账时被原始价格覆盖 - 动态价格计算:使用
woocommerce_before_calculate_totals钩子,在每次购物车计算总计时自动应用折扣价,确保结账页显示正确 - 修复HTML语法:补全单选按钮属性的闭合引号,避免JS读取数据异常
- 适配WooCommerce逻辑:将阶梯折扣的总价转换为单件价格,匹配平台按单件计算总计的规则
内容的提问来源于stack exchange,提问作者GFT
相关产品推荐
相关产品推荐

