Диагностика задачи: зачем менять цену в зависимости от роли пользователя
В WooCommerce часто возникает задача предоставлять разные цены для разных групп клиентов — например, специальные цены для оптовиков, сотрудников или подписчиков. Стандартный функционал WooCommerce этого не предусматривает, и требуется кастомизация с помощью кода или плагинов.
Чтобы точно понять, нужна ли вам именно динамическая замена цены по роли, проверьте следующие моменты:
- Роли созданы и корректно назначены пользователям
- Вы хотите менять цену именно на витрине и в корзине, а не только отображать скидку
- Изменения должны распространяться на все товары или только на определённые категории
Пошаговое решение: динамическое изменение цены товара по роли пользователя
Шаг 1. Определяем роли и цены
Допустим, у вас есть роль wholesale_customer для оптовиков, которым нужно давать скидку 20% на все товары.
Шаг 2. Добавляем фильтр для изменения цены
Добавьте следующий код в файл functions.php вашей темы или в кастомный плагин:
add_filter('woocommerce_product_get_price', 'custom_price_by_user_role', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_price_by_user_role', 10, 2);
function custom_price_by_user_role($price, $product) {
if (is_admin()) return $price; // не изменяем в админке
if (is_user_logged_in()) {
$user = wp_get_current_user();
if (in_array('wholesale_customer', $user->roles)) {
$discount = 0.8; // скидка 20%
$price = $price * $discount;
}
}
return $price;
}Этот код снижает цену всех товаров на 20% для пользователей с ролью wholesale_customer.
Шаг 3. Обновляем цену в корзине и на странице оформления заказа
Чтобы итоговая цена в корзине и заказе соответствовала, добавьте:
add_action('woocommerce_before_calculate_totals', 'custom_cart_price_by_user_role', 10);
function custom_cart_price_by_user_role($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
if (is_user_logged_in()) {
$user = wp_get_current_user();
if (in_array('wholesale_customer', $user->roles)) {
foreach ($cart->get_cart() as $cart_item) {
$original_price = $cart_item['data']->get_regular_price();
$discount = 0.8;
$cart_item['data']->set_price($original_price * $discount);
}
}
}
}Проверка результата после внедрения
1. Войдите под пользователем с ролью wholesale_customer и зайдите на страницу товара — цена должна отображаться с 20%-й скидкой.
2. Добавьте товар в корзину и проверьте, что цена там тоже изменена.
3. Выйдите из аккаунта или войдите под пользователем без роли wholesale_customer, убедитесь, что цена возвращается к стандартной.
Частые ошибки и как их исправить
- Цена не меняется в корзине: забыли добавить фильтр
woocommerce_before_calculate_totals. Без него скидка не применяется к товарам в корзине. - Изменения видны в админке: добавьте проверку
is_admin()в начале функции, чтобы не портить цены в админке. - Цена меняется, но итоговая сумма заказа неверна: возможно, конфликт с другими плагинами, которые кешируют цену. Попробуйте отключить кеш или совместить с хуком
woocommerce_cart_calculate_fees. - Пользователь не получает скидку: проверьте корректность ролей и что пользователь действительно залогинен.
Практические советы по безопасности и производительности
- Не храните изменённые цены в базе, используйте динамический пересчёт через хуки, чтобы избежать рассинхронизации и проблем с обновлениями.
- Добавьте кэширование результатов вычисления цены в сессии пользователя, если нагрузка высокая.
- Ограничьте применение скидок только на фронтенде, не трогайте цены в админке, чтобы не сбивать отчёты и аналитику.
- Проверяйте совместимость с WooCommerce и основными плагинами кэширования, так как динамические цены могут конфликтовать.
Сравнение вариантов реализации
| Метод | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| Кодовое изменение через хуки (как в статье) | Гибкость, бесплатно, не требует плагинов | Требует навыков, возможные конфликты, нужно тестировать | Если нужно простое правило и вы умеете работать с кодом |
| Плагины для динамических цен (например, WooCommerce Dynamic Pricing) | Простота настройки, много функций | Платно, может нагружать сайт | Если нужны сложные правила и готовое решение |
| Изменение цен через пользовательские поля товаров | Точная настройка цен для каждого товара | Трудоёмко, требует ручного ввода | Когда нужно индивидуальное ценообразование на товары |