Как изменить стоимость товара в WooCommerce в зависимости от роли пользователя

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

В WooCommerce стандартно нет возможности назначать разные цены для одного и того же товара для различных групп пользователей. Однако в реальных проектах часто требуется: оптовые покупатели видят скидки, партнеры получают особые цены, а простые посетители — обычные. Без такого функционала сложно гибко управлять ценообразованием и маркетингом.

Если вы столкнулись с этим, проверьте, что у вас есть несколько ролей пользователей с четко настроенными правами и что цены надо менять именно на уровне вывода и добавления в корзину, а не просто для отображения.

Пошаговое решение: как реализовать изменение цены товара по роли

1. Добавляем фильтр для изменения цены перед выводом

Используем хук woocommerce_product_get_price и woocommerce_product_get_regular_price, чтобы менять цену товара при получении.

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

function change_price_by_user_role($price, $product) {
    if (!is_user_logged_in()) {
        return $price; // гость видит стандартную цену
    }

    $user = wp_get_current_user();
    $roles = $user->roles;

    // Пример: для роли wholesale - скидка 20%
    if (in_array('wholesale', $roles)) {
        $price = $price * 0.8;
    } elseif (in_array('vip_customer', $roles)) {
        $price = $price * 0.9; // скидка 10%
    }

    return $price;
}

2. Изменяем цену при добавлении товара в корзину

Важно также менять цену при добавлении товара в корзину, иначе в корзине и на странице товара цены будут отличаться.

add_action('woocommerce_before_calculate_totals', 'change_cart_item_price_by_role', 10, 1);

function change_cart_item_price_by_role($cart) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }

    if (!is_user_logged_in()) {
        return;
    }

    $user = wp_get_current_user();
    $roles = $user->roles;

    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $price = $product->get_price();

        if (in_array('wholesale', $roles)) {
            $new_price = $price * 0.8;
        } elseif (in_array('vip_customer', $roles)) {
            $new_price = $price * 0.9;
        } else {
            $new_price = $price;
        }

        if ($new_price != $price) {
            $cart_item['data']->set_price($new_price);
        }
    }
}

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

  • Залогиньтесь под пользователем с ролью wholesale и проверьте, что цена на странице товара и в корзине на 20% ниже базовой.
  • Залогиньтесь под пользователем с ролью vip_customer — цена должна быть ниже на 10%.
  • Выйдите из системы или используйте аккаунт без специальных ролей — цены должны оставаться базовыми.
  • Добавьте товар в корзину, проверьте итоговую сумму и цены в заказе.
  • Для более точной проверки можно использовать плагин Query Monitor, чтобы отследить, что фильтры срабатывают.

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

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

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

  • Не храните изменённые цены в базе — меняйте их динамически через фильтры, чтобы избежать рассинхронизации и сложностей с отчетами.
  • Минимизируйте количество запросов в функцию изменения цены — кэшируйте роль пользователя в сессии или глобальной переменной.
  • Если требуется сложная логика ценообразования, рассмотрите кастомные метаданные товара для разных групп, но тогда потребуется расширять админку.
  • Обязательно тестируйте код на тестовом сайте, чтобы избежать ошибок ценообразования в продакшене.
  • Для более удобного управления ролями и скидками можно использовать плагин Clearfy Pro с функциями оптимизации WooCommerce — https://wpshop.ru/plugins/clearfy?utm_source=wpqa.ru&utm_medium=article&utm_campaign=izmenit-stoimost-tovara-woocommerce-v-zavisimosti-ot-rolli-polzovatelya

Сравнение вариантов реализации

МетодПлюсыМинусыПример использования
Фильтры WooCommerce (код) Гибкость, не требует сторонних плагинов, легко кастомизируется Требует навыков программирования, возможны конфликты с другими плагинами Пример кода выше
Плагины для ценообразования (например, WooCommerce Role Based Pricing) Простота настройки через UI, поддержка сложных правил Платные, могут создавать нагрузку, меньше гибкости в кастомизации Использование готового решения
Кастомные метаполя с отдельным ценовым уровнем Высокая точность настройки, можно иметь несколько уровней цен Сложно реализовать без сторонних плагинов, требует доработки админки Комбинирование кода и ACF (Advanced Custom Fields)
WooCommerce: как изменить стоимость товара в зависимости от суммы в корзине
19.07.2026
Как настроить и кастомизировать колонки в админке WordPress
27.03.2026
Как создать динамические формы регистрации в WordPress с помощью AJAX
18.01.2026
WooCommerce: автоматическое изменение стоимости товара по условиям корзины
09.07.2026
WooCommerce: как изменить стоимость товара в зависимости от введённого промокода
23.06.2026