Как настроить индивидуальные ценовые правила в WooCommerce для разных ролей пользователей

Диагностика задачи: зачем нужны ценовые правила по ролям

В интернет-магазинах на WooCommerce часто возникает необходимость устанавливать разные цены на товары в зависимости от роли пользователя. Например, оптовым покупателям нужна скидка, а новым пользователям — специальные акции. WooCommerce не поддерживает это из коробки, поэтому приходится реализовывать кастомные решения.

Пошаговое решение: как задать цены для ролей через код

1. Определение текущей роли пользователя

Для изменения цены нам нужно определить роль текущего пользователя. В WordPress роли доступны через объект WP_User:

function get_current_user_role() {
    if ( ! is_user_logged_in() ) {
        return 'guest';
    }
    $user = wp_get_current_user();
    if ( empty( $user->roles ) ) {
        return 'subscriber';
    }
    return $user->roles[0];
}

2. Фильтрация цены товара в WooCommerce

Для изменения цены используем фильтр woocommerce_product_get_price и woocommerce_product_get_regular_price, чтобы цена менялась и на странице товара, и в каталоге:

add_filter( 'woocommerce_product_get_price', 'custom_price_for_user_role', 10, 2 );
add_filter( 'woocommerce_product_get_regular_price', 'custom_price_for_user_role', 10, 2 );

function custom_price_for_user_role( $price, $product ) {
    $role = get_current_user_role();

    // Пример правил для ролей
    $discounts = array(
        'wholesale_customer' => 0.8, // 20% скидка
        'premium_customer' => 0.9,   // 10% скидка
        'guest' => 1,               // без скидки
    );

    if ( isset( $discounts[ $role ] ) ) {
        $price = $price * $discounts[ $role ];
    }

    return $price;
}

3. Обновление цены в корзине и при оформлении заказа

Чтобы цена корректно отображалась в корзине и заказе, добавим фильтр woocommerce_before_calculate_totals:

add_action( 'woocommerce_before_calculate_totals', 'custom_cart_item_price_by_role', 10, 1 );
function custom_cart_item_price_by_role( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $role = get_current_user_role();
    $discounts = array(
        'wholesale_customer' => 0.8,
        'premium_customer' => 0.9,
        'guest' => 1,
    );

    if ( ! isset( $discounts[ $role ] ) ) {
        return;
    }
    foreach ( $cart->get_cart() as $cart_item ) {
        $original_price = $cart_item['data']->get_regular_price();
        $new_price = $original_price * $discounts[ $role ];
        $cart_item['data']->set_price( $new_price );
    }
}

Проверка результата после внедрения

  • Войдите под пользователем с ролью wholesale_customer и проверьте цену товара на странице и в корзине — она должна быть на 20% ниже обычной.
  • Выйдите из аккаунта (гость) — цена должна отображаться без скидок.
  • Для других ролей проверьте соответствие скидкам.

Частые ошибки и как их исправить

  • Цена не меняется в корзине: вероятно, пропущен хук woocommerce_before_calculate_totals или функция не проверяет роль пользователя корректно.
  • Скидка применяется не к той цене: всегда используйте get_regular_price() для расчёта скидки, иначе могут возникать циклы и неверные цены.
  • Скидка видна гостям: не забывайте обрабатывать роль guest отдельно.
  • Конфликты с другими плагинами скидок: протестируйте на чистом сайте, чтобы исключить конфликты.

Практические советы по безопасности и производительности

  • Не храните скидки в опциях WordPress — лучше сделать массив в коде или использовать CPT для гибкости.
  • Кэширование страницы может мешать динамическому изменению цен. Для страниц с индивидуальными ценами отключайте кэш или используйте AJAX для обновления цены.
  • Минимизируйте нагрузку, не вызывайте wp_get_current_user() в циклах, сохраняйте роль в сессии или глобальной переменной.

Сравнение вариантов реализации ценовых правил по ролям

МетодПреимуществаНедостатки
Кодовые фильтры в functions.phpПолный контроль, бесплатно, гибкоТребует навыков, возможны ошибки
Плагины типа "Dynamic Pricing"Простота настройки, интерфейсПлатные, могут конфликтовать, нагрузка
Кастомный плагин с админкойУдобство и контроль, расширяемостьСложнее в разработке, поддержке
Как создать поддержку многоязычности в WordPress без плагинов
18.11.2025
Как отложить публикацию постов в WordPress
19.01.2026
Как создать динамические таблицы в WordPress с помощью шорткодов
05.01.2026
Как создать собственный виджет WordPress: подробное руководство
25.11.2025
Как использовать WordPress Transients для эффективного кэширования данных
07.02.2026