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