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

WooCommerce 3:编程设置促销价后,购物车及结账页显示原价的解决方法

嘿,这个坑我太熟了!你之前的代码应该只是把促销价写到了产品的元数据里,但WooCommerce的购物车在加载时会重新拉取产品的默认价格计算,所以得专门给购物车加个“补丁”才行。下面给你一步步解决:

核心方案:修改购物车的价格计算逻辑

WooCommerce有个专门的钩子woocommerce_before_calculate_totals,会在购物车计算总价之前触发,刚好适合我们修改单个购物车项的价格。把下面的代码放到你的主题functions.php文件里,或者自定义插件中(别直接改WooCommerce核心文件,不然更新就没了):

add_action('woocommerce_before_calculate_totals', 'sync_custom_sale_price_to_cart', 10, 1);
function sync_custom_sale_price_to_cart($cart) {
    // 避免后台和非AJAX场景下的循环调用
    if (is_admin() && !defined('DOING_AJAX')) return;
    
    // 遍历购物车里的每一项
    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        // 这里替换成你之前存储促销价的meta键名,比如你之前用的是_custom_sale_price
        $custom_sale_price = get_post_meta($product->get_id(), '_custom_sale_price', true);
        
        // 确保促销价存在且是数字
        if (!empty($custom_sale_price) && is_numeric($custom_sale_price)) {
            // 设置购物车项的实际结算价格
            $product->set_price($custom_sale_price);
            // 同步设置促销价和原价,这样购物车会显示“划掉原价+促销价”的样式
            $product->set_regular_price($product->get_regular_price());
            $product->set_sale_price($custom_sale_price);
        }
    }
}
关键细节说明
  • 避免循环调用:代码里的is_admin() && !defined('DOING_AJAX')判断是为了防止后台操作时触发重复计算,导致报错。
  • meta键名对应:一定要把_custom_sale_price改成你之前设置促销价时用的实际键名,比如如果之前用update_post_meta($product_id, '_sale_price', $price),那这里就用_sale_price。
  • 价格样式同步:如果想要购物车显示“原价划掉+促销价”的标准样式,就必须同时设置set_regular_price和set_sale_price,不然只会显示单一价格。
额外优化:针对特定条件的促销价

如果你的促销价是针对特定用户(比如会员)、特定时间或者其他条件的,可以在代码里加上判断逻辑。比如针对会员用户的促销:

add_action('woocommerce_before_calculate_totals', 'set_member_sale_price_in_cart', 10, 1);
function set_member_sale_price_in_cart($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    
    // 只给会员用户应用促销价
    if (!current_user_can('customer')) return;
    
    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $member_sale_price = get_post_meta($product->get_id(), '_member_sale_price', true);
        
        if ($member_sale_price) {
            $product->set_price($member_sale_price);
            $product->set_sale_price($member_sale_price);
            $product->set_regular_price($product->get_regular_price());
        }
    }
}
最后检查点

如果之前你设置促销价时同时加了时间限制(比如_sale_price_dates_from和_sale_price_dates_to),记得清空这两个元数据,不然WooCommerce会优先判断时间是否在促销期内,导致自定义价格不生效:

// 清空促销时间限制,确保永久生效
update_post_meta($product_id, '_sale_price_dates_from', '');
update_post_meta($product_id, '_sale_price_dates_to', '');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:14:16