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

WooCommerce:为特定用户角色基于产品自定义字段设置并显示折扣

解决方案:针对Clubmember角色显示自定义折扣价与原价

实现思路

要同时满足三个核心需求:

  • 仅对clubmember角色用户生效
  • 读取产品自定义字段clubmember_price的折扣百分比计算实际售价
  • 在产品页、购物车、结账页同时展示原价和折扣价

需要结合WooCommerce的价格过滤钩子与显示控制钩子,既修改实际结算价格,又保留原价的显示逻辑,让用户能直观看到优惠对比。

完整代码实现

// 1. 为Clubmember角色计算自定义折扣价(保留原价用于显示)
add_filter('woocommerce_product_get_price', 'clubmember_custom_price', 10, 2);
add_filter('woocommerce_product_variation_get_price', 'clubmember_custom_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'clubmember_custom_price', 10, 2);
add_filter('woocommerce_product_variation_get_regular_price', 'clubmember_custom_price', 10, 2);

function clubmember_custom_price($price, $product) {
    // 仅对clubmember角色且产品有有效折扣字段的情况生效
    if (!current_user_can('clubmember') || !$discount_percent = $product->get_meta('clubmember_price')) {
        return $price;
    }

    // 校验折扣百分比的有效性
    $discount_percent = absint($discount_percent);
    if ($discount_percent < 1 || $discount_percent > 99) {
        return $price;
    }

    // 基于原价计算折扣价,保留原价字段用于显示对比
    $original_price = $product->get_regular_price() ?: $price;
    return round($original_price * (100 - $discount_percent) / 100, wc_get_price_decimals());
}

// 2. 强制在产品页显示原价与折扣价对比
add_filter('woocommerce_show_sale_price', '__return_true');
add_filter('woocommerce_product_is_on_sale', 'clubmember_force_sale_badge', 10, 2);

function clubmember_force_sale_badge($is_sale, $product) {
    if (current_user_can('clubmember') && $product->get_meta('clubmember_price')) {
        return true;
    }
    return $is_sale;
}

// 3. 在购物车/结账页显示原价与折扣价对比
add_filter('woocommerce_cart_item_price', 'clubmember_cart_price_display', 10, 3);
add_filter('woocommerce_cart_item_subtotal', 'clubmember_cart_price_display', 10, 3);

function clubmember_cart_price_display($display_price, $cart_item, $cart_item_key) {
    if (!current_user_can('clubmember')) {
        return $display_price;
    }

    $product = $cart_item['data'];
    $discount_percent = $product->get_meta('clubmember_price');
    if (!$discount_percent) {
        return $display_price;
    }

    $original_price = wc_get_price_to_display($product, array('price' => $product->get_regular_price() ?: $product->get_price()));
    $discounted_price = wc_get_price_to_display($product);

    // 调用WooCommerce原生函数生成规范的价格对比格式
    return wc_format_sale_price($original_price, $discounted_price);
}

代码原理拆解

1. 价格计算逻辑

  • 使用woocommerce_product_get_price等系列钩子,为目标角色计算专属折扣价,但不修改产品原始原价字段,让WooCommerce原生的价格显示逻辑能识别出“原价”与“折扣价”的差异。
  • 先校验用户角色和自定义字段的有效性,避免非目标用户触发逻辑错误。
  • 用wc_get_price_decimals()保证价格小数位数与商店全局设置一致。

2. 产品页显示控制

  • 通过woocommerce_show_sale_price强制显示销售价格,woocommerce_product_is_on_sale让产品自动带上促销标识(不需要可移除该钩子)。
  • 复用WooCommerce原生的销售价格显示模板,自动生成“原价划掉+折扣价”的样式,无需手写HTML。

3. 购物车/结账页显示

  • 重写woocommerce_cart_item_price和woocommerce_cart_item_subtotal钩子,替换默认价格显示,添加原价对比。
  • 使用wc_format_sale_price()调用内置格式化函数,确保显示样式与商店全局设置统一。

注意事项

  • 产品自定义字段clubmember_price仅需填写纯数字(如10代表10%折扣)。
  • 若使用缓存插件,需针对用户角色做缓存隔离,避免不同角色看到相同价格。
  • 代码已兼容变量产品(Variation),可直接测试多规格产品的显示效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 06:47:41