Диагностика задачи: зачем и когда менять цены товаров программно
В WooCommerce часто возникает необходимость динамически изменять цену товара: скидки по событию, цена для определённой роли пользователя, корректировка стоимости в зависимости от атрибутов или параметров заказа. Ручное изменение неудобно и не масштабируемо. Автоматизация через хуки — наиболее надёжный и гибкий способ.
Обзор ключевых хуков для изменения цены товара
WooCommerce предоставляет несколько фильтров для изменения цены «на лету», без изменения данных в базе:
woocommerce_get_price— возвращает цену товара;woocommerce_product_get_price— цена конкретного объекта продукта;woocommerce_product_get_sale_price— цена распродажи;woocommerce_get_sale_price— альтернатива фильтра для распродаж;woocommerce_variation_prices_price— цена вариации;woocommerce_variation_prices_sale_price— цена вариации по распродаже.
Для большинства задач подходит woocommerce_product_get_price, он срабатывает при вызове метода $product->get_price().
Пошаговое решение: пример динамического изменения цены по роли пользователя
Задача: для пользователей с ролью wholesale_customer сделать скидку 20% на все товары.
Добавьте следующий код в файл темы functions.php или в кастомный плагин:
add_filter('woocommerce_product_get_price', 'change_price_for_wholesale_role', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'change_price_for_wholesale_role', 10, 2);
function change_price_for_wholesale_role($price, $product) {
if (is_admin()) {
return $price; // Не менять цену в админке
}
if (is_user_logged_in()) {
$user = wp_get_current_user();
if (in_array('wholesale_customer', (array) $user->roles)) {
$price = $price * 0.8; // Скидка 20%
}
}
return $price;
}Обратите внимание, что фильтр применяется и для обычной, и для регулярной цены, чтобы корректно отображалось и на витрине, и в корзине.
Проверка результата после внедрения кода
- Залогиньтесь под пользователем с ролью
wholesale_customer. - Откройте страницу товара на фронтенде — цена должна быть уменьшена на 20%.
- Для пользователя без этой роли цена должна отображаться без изменений.
- Добавьте товар в корзину — в корзине и на странице оформления заказа цена должна соответствовать изменённой.
Если есть кэширование, очистите кэш браузера и плагинов кэширования.
Частые ошибки при использовании хуков для изменения цены
- Изменение цены в админке: если не добавить проверку
is_admin(), цены в панели управления также изменятся, что приведёт к путанице и ошибкам. - Применение фильтра не ко всем типам цен: меняя только
woocommerce_product_get_price, можно пропустить регулярную или распродажную цену, из-за чего цены будут отображаться неконсистентно. - Неправильное использование ролей: если роль пользователя не добавлена или проверяется по неправильному названию, скидка не сработает.
- Кэширование: кэширование страниц и объектов WooCommerce может мешать мгновенному отображению изменений цен.
Советы по безопасности и производительности при динамическом изменении цен
- Всегда минимизируйте количество запросов и условий в фильтрах — чем проще код, тем быстрее отрабатывает изменение цены.
- Используйте
is_admin(), чтобы не влиять на админскую часть. - Если используете сложные условия (например, проверка метаданных пользователя или сложных правил), кешируйте результаты проверки в сессии или transients.
- При большом каталоге лучше использовать сторонние решения для управления ценами по ролям, чтобы избежать замедления.
Сравнение методов изменения цены в WooCommerce
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Фильтры (хуки) woocommerce_product_get_price | Динамическое изменение цены на лету без изменений в БД | Гибко, не меняет данные, быстро | Нужно тщательно тестировать совместимость с другими плагинами |
| Изменение цены в мета-данных продукта | Запись новой цены в БД | Постоянное изменение, видно в админке | Менее гибко, сложнее откатить |
| Плагины для управления ценами по ролям | Готовые решения со множеством настроек | Простота настройки, поддержка | Могут нагрузить сайт, платные |
Дополнительный пример: изменение цены вариаций
Для вариаций используйте фильтр woocommerce_variation_prices_price:
add_filter('woocommerce_variation_prices_price', 'wholesale_price_variation', 10, 3);
add_filter('woocommerce_variation_prices_regular_price', 'wholesale_price_variation', 10, 3);
function wholesale_price_variation($price, $variation, $product) {
if (is_admin()) {
return $price;
}
if (is_user_logged_in()) {
$user = wp_get_current_user();
if (in_array('wholesale_customer', (array) $user->roles)) {
$price = $price * 0.8;
}
}
return $price;
}Этот код применит скидку к вариативным товарам для выбранной роли.