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

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

В стандартном WooCommerce невозможно задать разные цены на товары для разных ролей пользователей (например, для оптовиков, дилеров, зарегистрированных клиентов). Если бизнес-модель требует дифференцированного ценообразования, необходимо внедрять кастомные решения или использовать плагины. Важно понять, что именно нужно: скидка в процентах, фиксированная цена, цены по категориям или для отдельных товаров.

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

Для диагностики:

  • Проверьте, есть ли в системе кастомные функции или плагины, влияющие на цены (WooCommerce Dynamic Pricing, Wholesale Suite и пр.).
  • Протестируйте цены под разными учетными записями с разными ролями.
  • Посмотрите, есть ли в теме или функциях сайта фильтры типа woocommerce_get_price, woocommerce_product_get_price.

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

1. Создаем роли пользователей

Если нужных ролей еще нет, добавим их функцией:

function add_custom_user_roles() {
    add_role('wholesale_customer', 'Оптовый клиент', array('read' => true));
}
add_action('init', 'add_custom_user_roles');

2. Добавляем метаполе для индивидуальной цены у товара

Для каждого товара добавим поле с ценой для оптовика через Advanced Custom Fields (ACF) или вручную:

function add_wholesale_price_field() {
    woocommerce_wp_text_input(array(
        'id' => '_wholesale_price',
        'label' => 'Оптовая цена',
        'desc_tip' => 'true',
        'description' => 'Цена для оптовых клиентов',
        'type' => 'text',
    ));
}
add_action('woocommerce_product_options_pricing', 'add_wholesale_price_field');

function save_wholesale_price_field($post_id) {
    $wholesale_price = isset($_POST['_wholesale_price']) ? sanitize_text_field($_POST['_wholesale_price']) : '';
    update_post_meta($post_id, '_wholesale_price', $wholesale_price);
}
add_action('woocommerce_process_product_meta', 'save_wholesale_price_field');

3. Перекрываем цену товара для оптовиков

Добавим фильтр, который при отображении цены у пользователей с ролью 'wholesale_customer' покажет оптовую цену, если она задана:

function set_wholesale_price_for_role($price, $product) {
    if (current_user_can('wholesale_customer')) {
        $wholesale_price = get_post_meta($product->get_id(), '_wholesale_price', true);
        if (!empty($wholesale_price) && is_numeric($wholesale_price)) {
            return $wholesale_price;
        }
    }
    return $price;
}
add_filter('woocommerce_product_get_price', 'set_wholesale_price_for_role', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'set_wholesale_price_for_role', 10, 2);
add_filter('woocommerce_product_get_sale_price', 'set_wholesale_price_for_role', 10, 2);

4. Обновление цены в корзине и заказе

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

function custom_cart_item_price($cart_object) {
    if (!WC()->session->__isset('reload_checkout')) {
        foreach ($cart_object->get_cart() as $cart_item_key => $cart_item) {
            if (current_user_can('wholesale_customer')) {
                $wholesale_price = get_post_meta($cart_item['product_id'], '_wholesale_price', true);
                if (!empty($wholesale_price) && is_numeric($wholesale_price)) {
                    $cart_item['data']->set_price($wholesale_price);
                }
            }
        }
    }
}
add_action('woocommerce_before_calculate_totals', 'custom_cart_item_price', 10, 1);

Проверка результата

  • Войдите под пользователем с ролью wholesale_customer.
  • Откройте страницу товара с заполненным полем "Оптовая цена".
  • Проверьте отображаемую цену — должна быть оптовая.
  • Добавьте товар в корзину и перейдите к оформлению заказа — цена должна сохраниться.
  • Под другим пользователем с ролью покупателя цена должна быть стандартной.

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

  • Оптовая цена не отображается: проверьте, что метаполе _wholesale_price заполнено и числовое.
  • Цена в корзине не меняется: возможно, фильтр woocommerce_before_calculate_totals не сработал — убедитесь, что функция подключена и приоритет 10.
  • Пользователь неправильно получает скидку: проверьте роль пользователя через current_user_can(), возможно, роль не назначена или пользователь не авторизован.
  • Кэширование мешает увидеть изменения: очистите кэш сайта и браузера.

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

  • Не храните цены в пользовательских метаполях пользователей — для масштабируемости лучше хранить у товаров.
  • Используйте числовой тип для цен, валидируйте ввод через sanitize_text_field и floatval.
  • Для больших магазинов с множеством ролей и сложными правилами лучше использовать специализированные плагины (например, Clearfy Pro может помочь с оптимизацией и SEO).
  • Избегайте дублирования кода, используйте отдельные функции и проверяйте наличие роли через user_can() для более точной проверки.

Сравнение подходов: плагин vs код

ПодходПреимуществаНедостатки
Самописный код (как в статье)Полный контроль, легковесность, отсутствие лишних функцийТребует навыков, нужно вручную поддерживать, сложнее масштабировать
Плагин (например, WooCommerce Wholesale Prices)Быстрая настройка, поддержка разных правил, обновленияМожет нагружать сайт, не всегда гибко под задачу, зависит от разработчика
Как оценивать и оптимизировать производительность WordPress сайта
29.01.2026
Как удалить старые медиа файлы в WordPress
11.02.2026
Как удалить категории в WordPress правильно с помощью кода и плагинов
04.02.2026
Как отключить AJAX в WooCommerce для повышения производительности
24.04.2026
Как создать собственный блок в Gutenberg WordPress: практическое руководство
15.01.2026