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

为WooCommerce简单产品添加自定义角色定价选项

为WooCommerce简单产品实现基于用户角色的自定义定价

我已经为WooCommerce可变产品搭建了基于用户角色的自定义定价功能,当前效果是在产品变体的定价选项区域添加了三个自定义价格字段:General、Food、Hot Food,对应不同用户角色的专属定价。

实现该功能的代码如下:

// Add custom fields to variations option pricing
add_action( 'woocommerce_variation_options_pricing', 'add_variation_options_pricing', 20, 3 );
function add_variation_options_pricing( $loop, $variation_data, $post_variation )
{
    $value1  = get_post_meta( $post_variation->ID, '_food_price', true );
    $value2  = get_post_meta( $post_variation->ID, '_hot_food_price', true );
    $value3  = get_post_meta( $post_variation->ID, '_general_price', true );

    $symbol = ' (' . get_woocommerce_currency_symbol() . ')';

    $key_1 = '_food_price[' . $loop . ']';
    $key_2 = '_hot_food_price[' . $loop . ']';
    $key_3 = '_general_price[' . $loop . ']';

    // General
    echo '<div class="variable_general-price"><p class="form-row form-row-first">
        <label>' . __( "General", "woocommerce" ) . $symbol . '</label>
        <input type="text" size="5" name="' . $key_3 .'" value="' . esc_attr( $value3 ) . '" />
    </p></div>';

    // Food
    echo '<div class="variable_food-price"><p class="form-row form-row-first">
        <label>' . __( "Food", "woocommerce" ) . $symbol . '</label>
        <input type="text" size="5" name="' . $key_1 .'" value="' . esc_attr( $value1 ) . '" />
    </p></div>';

    // Hot Food
    echo '<div class="variable_hot-food-price"><p class="form-row form-row-first">
        <label>' . __( "Hot Food", "woocommerce" ) . $symbol . '</label>
        <input type="text" size="5" name="' . $key_2 .'" value="' . esc_attr( $value2 ) . '" />
    </p></div>';
}

// Save variations prices custom fields values
add_action( 'woocommerce_save_product_variation', 'save_product_variation_price', 20, 2 );
function save_product_variation_price( $variation_id, $i )
{
    if ( isset( $_POST['_food_price'][$i] ) )
    {
        update_post_meta( $variation_id, '_food_price', floatval( $_POST['_food_price'][$i] ) );
    }

    if ( isset( $_POST['_hot_food_price'][$i] ) )
    {
        update_post_meta( $variation_id, '_hot_food_price', floatval( $_POST['_hot_food_price'][$i] ) );
    }

    if ( isset( $_POST['_general_price'][$i] ) )
    {
        update_post_meta( $variation_id, '_general_price', floatval( $_POST['_general_price'][$i] ) );
    }
}

// Variable product price range
add_filter('woocommerce_variation_prices_price', 'variation_price', 900, 2 );

// Product variations (of a variable product)
add_filter('woocommerce_product_variation_get_price', 'variation_price', 900, 2 );
function variation_price( $price, $object )
{
    if( is_user_logged_in() ) {
        // Hot Food User
        if ( current_user_can( 'stallholder') && current_user_can( 'hot_food' ) ) {
            $new_price = (float) get_post_meta( $object->get_id(), '_hot_food_price', true );
            $price     = empty($new_price) ? $price : $new_price;
        }
        // Food User
        elseif ( current_user_can( 'stallholder') && current_user_can( 'food' ) ){
            $new_price = (float) get_post_meta( $object->get_id(), '_food_price', true );
            $price     = empty($new_price) ? $price : $new_price;
        }
        // General User
        else {
            $new_price = (float) get_post_meta( $object->get_id(), '_general_price', true );
            $price     = empty($new_price) ? $price : $new_price;
        }
    }
    return $price;
}

现在需要为WooCommerce简单产品实现相同功能,将这三个自定义定价字段添加到简单产品的定价选项区域(常规价格/销售价格下方)。

解决方案代码

以下代码可在简单产品的定价面板添加对应字段,并实现保存和前端价格替换逻辑,同时兼容已有的可变产品功能:

// 1. 为简单产品添加自定义定价字段
add_action( 'woocommerce_product_options_pricing', 'add_simple_product_custom_pricing_fields' );
function add_simple_product_custom_pricing_fields() {
    global $post;

    $symbol = ' (' . get_woocommerce_currency_symbol() . ')';

    // General 价格字段
    echo '<div class="simple_general-price">
        <p class="form-row form-row-first">
            <label>' . __( "General", "woocommerce" ) . $symbol . '</label>
            <input type="text" size="5" name="_general_price" value="' . esc_attr( get_post_meta( $post->ID, '_general_price', true ) ) . '" />
        </p>
    </div>';

    // Food 价格字段
    echo '<div class="simple_food-price">
        <p class="form-row form-row-first">
            <label>' . __( "Food", "woocommerce" ) . $symbol . '</label>
            <input type="text" size="5" name="_food_price" value="' . esc_attr( get_post_meta( $post->ID, '_food_price', true ) ) . '" />
        </p>
    </div>';

    // Hot Food 价格字段
    echo '<div class="simple_hot-food-price">
        <p class="form-row form-row-first">
            <label>' . __( "Hot Food", "woocommerce" ) . $symbol . '</label>
            <input type="text" size="5" name="_hot_food_price" value="' . esc_attr( get_post_meta( $post->ID, '_hot_food_price', true ) ) . '" />
        </p>
    </div>';
}

// 2. 保存简单产品的自定义定价字段值
add_action( 'woocommerce_process_product_meta', 'save_simple_product_custom_pricing_fields' );
function save_simple_product_custom_pricing_fields( $post_id ) {
    if ( isset( $_POST['_food_price'] ) ) {
        update_post_meta( $post_id, '_food_price', floatval( $_POST['_food_price'] ) );
    }

    if ( isset( $_POST['_hot_food_price'] ) ) {
        update_post_meta( $post_id, '_hot_food_price', floatval( $_POST['_hot_food_price'] ) );
    }

    if ( isset( $_POST['_general_price'] ) ) {
        update_post_meta( $post_id, '_general_price', floatval( $_POST['_general_price'] ) );
    }
}

// 3. 替换简单产品的前端显示价格
add_filter( 'woocommerce_product_get_price', 'simple_product_role_based_pricing', 900, 2 );
add_filter( 'woocommerce_product_get_regular_price', 'simple_product_role_based_pricing', 900, 2 );
function simple_product_role_based_pricing( $price, $product ) {
    if ( ! $product->is_type( 'simple' ) || ! is_user_logged_in() ) {
        return $price;
    }

    // Hot Food 用户角色
    if ( current_user_can( 'stallholder' ) && current_user_can( 'hot_food' ) ) {
        $new_price = (float) get_post_meta( $product->get_id(), '_hot_food_price', true );
        $price = empty( $new_price ) ? $price : $new_price;
    }
    // Food 用户角色
    elseif ( current_user_can( 'stallholder' ) && current_user_can( 'food' ) ) {
        $new_price = (float) get_post_meta( $product->get_id(), '_food_price', true );
        $price = empty( $new_price ) ? $price : $new_price;
    }
    // 普通用户
    else {
        $new_price = (float) get_post_meta( $product->get_id(), '_general_price', true );
        $price = empty( $new_price ) ? $price : $new_price;
    }

    return $price;
}

代码说明

  • 字段添加:使用woocommerce_product_options_pricing钩子,在简单产品的定价面板下方插入三个自定义价格字段,样式和可变产品的字段保持一致。
  • 字段保存:通过woocommerce_process_product_meta钩子处理简单产品的字段保存逻辑,将值存储为产品元数据。
  • 价格替换:利用woocommerce_product_get_price和woocommerce_product_get_regular_price钩子,根据当前登录用户的角色替换显示价格,逻辑和可变产品完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 00:24:54