如何在WooCommerce中将自定义折扣价设为购物车实际售价
如何让WooCommerce加入购物车时使用自定义计算的折扣价(price2 newprice中的金额)
我通过jQuery基于总金额计算出了商品折扣价,已经更新了前端显示,但点击“加入购物车”时,系统没有使用带有price2 newprice类的span里的金额(比如示例中的398.52)作为实际售价。尝试修改data-product-price属性无效,求解决办法。
自定义HTML结构
<div class="woocommerce-variation-price"> <span class="price-incvat" style="text-decoration:line-through;"> <span class="woocommerce-Price-amount amount"> <bdi> <span class="woocommerce-Price-currencySymbol">£</span> 531.36 </bdi> </span> Inc. VAT </span><br> <span class="price2" style="text-decoration:line-through;"> <span class="woocommerce-Price-amount amount"> <bdi> <span class="woocommerce-Price-currencySymbol">£</span> 442.80 </bdi> </span> Exc. VAT </span><br> <span class="price-incvat newprice"> <span class="woocommerce-Price-amount amount"> <bdi> <span class="woocommerce-Price-currencySymbol">£</span> 478.22 </bdi> </span> Inc. VAT </span><br> <span class="price2 newprice"> <span class="woocommerce-Price-amount amount"> <bdi> <span class="woocommerce-Price-currencySymbol">£</span> 398.52 </bdi> </span> Exc. VAT </span> </div>
WooCommerce默认HTML结构
<div class="yith_wapo_group_total " data-product-price="442.8" data-product-id="205692"> <table> <tbody><tr class="ywapo_tr_product_base_price"> <td data-nosnippet="">Product price</td> <td data-nosnippet=""><div class="yith_wapo_group_product_price_total"><span class="price amount">£442.80</span></div></td> </tr> <tr class="ywapo_tr_additional_options"> <td data-nosnippet="">Additional options total:</td> <td data-nosnippet=""><div class="yith_wapo_group_option_total"><span class="price amount">£0.00</span></div></td> </tr> <tr class="ywapo_tr_order_totals"> <td data-nosnippet="">Order total:</td> <td data-nosnippet=""><div class="yith_wapo_group_final_total"><span class="price amount">£442.80</span></div></td> </tr> </tbody></table> </div>
当前折扣价计算的jQuery代码
jQuery(function ($) { $('.yith_wapo_group_final_total .price.amount').on("DOMSubtreeModified", function () { var price_ele = jQuery(".woocommerce-variation.single_variation .woocommerce-variation-price"); var price_ele_simp = jQuery(".new-price-simple"); var add_price1 = jQuery(".yith_wapo_group_final_total .price.amount").text().replace(/£/g, ""); var add_price = add_price1.replace(/,/g, ""); var inc = (add_price * 20) / 100; var inc_price = parseFloat(add_price) + parseFloat(inc); if(bundleproduct != '') { var bundleExcVatFinalPrice = parseFloat(add_price) - (add_price * bundleproduct); var bundleIncVatFinalPrice = parseFloat(bundleExcVatFinalPrice) + (bundleExcVatFinalPrice * 0.20); if (add_price1 != 0 && price_ele.text() != "") { price_ele.html('<span class="price-incvat" style="text-decoration:line-through;"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">£</span>' + numberWithCommas(inc_price.toFixed(2)) + '</bdi></span> Inc. VAT</span></span><br><span class="price2" style="text-decoration:line-through;"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">£</span>' + numberWithCommas(add_price) + '</bdi></span> Exc. VAT</span><br><span class="price-incvat"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">£</span>' + numberWithCommas(bundleIncVatFinalPrice.toFixed(2)) + '</bdi></span> Inc. VAT</span></span><br><span class="price2"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">£</span>' + numberWithCommas(bundleExcVatFinalPrice.toFixed(2)) + '</bdi></span> Exc. VAT</span>'); } else if (price_ele.text() == "") { price_ele.html('<span class="price-incvat" style="text-decoration:line-through;"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">£</span>' + numberWithCommas(inc_price.toFixed(2)) + '</bdi></span> Inc. VAT</span></span><br><span class="price2" style="text-decoration:line-through;"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">£</span>' + numberWithCommas(add_price) + '</bdi></span> Exc. VAT</span><br><span class="price-incvat"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">£</span>' + numberWithCommas(bundleIncVatFinalPrice.toFixed(2)) + '</bdi></span> Inc. VAT</span></span><br><span class="price2"><span class="woocommerce-Price-amount amount"><bdi><span class="woocommerce-Price-currencySymbol">£</span>' + numberWithCommas(bundleExcVatFinalPrice.toFixed(2)) + '</bdi></span> Exc. VAT</span>'); } } }, 350); }); });
尝试过的无效代码
$('.yith_wapo_group_total').attr('data-product-price', bundleExcVatFinalPrice); $('.yith_wapo_group_final_total .price amount').attr('data-product-price', bundleExcVatFinalPrice);
解决方案
要让WooCommerce在加入购物车时正确读取折扣价,需要从前端属性修改+提交拦截两个层面处理:
修正前端属性修改逻辑
之前的代码存在变量作用域或时机问题,需将属性修改代码放在bundleExcVatFinalPrice计算完成的代码块内,同时修正选择器:// 在if(bundleproduct != '')的代码块末尾添加 $('.yith_wapo_group_total').attr('data-product-price', bundleExcVatFinalPrice.toFixed(2)); // 同时更新变体商品的隐藏价格输入框(如果是变体商品) $('.single_variation_wrap input[name="price"]').val(bundleExcVatFinalPrice.toFixed(2));拦截加入购物车提交动作,强制传递正确价格
部分场景下WooCommerce会从后端拉取原始价格,因此需要拦截表单提交,手动注入正确价格:$('form.cart').on('submit', function(e) { // 提取目标折扣价 var finalPrice = $('.price2.newprice .woocommerce-Price-amount.amount').text().replace(/£|,/g, ''); // 添加隐藏字段传递自定义价格 $(this).append('<input type="hidden" name="custom_final_price" value="' + finalPrice + '">'); // 更新变体商品的价格字段 var variationPriceInput = $(this).find('input[name="price"]'); if(variationPriceInput.length > 0) { variationPriceInput.val(finalPrice); } });后端验证与价格生效(推荐)
为避免前端篡改,需在后端添加钩子强制使用自定义价格:// 存储自定义价格到购物车项 add_filter('woocommerce_add_cart_item_data', 'store_custom_cart_price', 10, 3); function store_custom_cart_price($cart_item_data, $product_id, $variation_id) { if(isset($_POST['custom_final_price']) && is_numeric($_POST['custom_final_price'])) { $cart_item_data['custom_price'] = floatval($_POST['custom_final_price']); $cart_item_data['unique_key'] = md5(microtime().rand()); // 确保商品条目唯一 } return $cart_item_data; } // 应用自定义价格到购物车计算 add_action('woocommerce_before_calculate_totals', 'apply_custom_cart_price'); function apply_custom_cart_price($cart) { if(is_admin() && !defined('DOING_AJAX')) return; foreach($cart->get_cart() as $cart_item) { if(isset($cart_item['custom_price'])) { $cart_item['data']->set_price($cart_item['custom_price']); } } }
内容的提问来源于stack exchange,提问作者Sabir
相关产品推荐
相关产品推荐

