Диагностика проблемы: зачем нужно менять цену автоматически
В WooCommerce часто требуется динамически изменять стоимость товаров в зависимости от разных условий: акции, остатка на складе, категории товара, даты или пользовательских ролей. Ручное обновление цен на сотни товаров неудобно и приводит к ошибкам. Автоматизация этого процесса позволяет поддерживать актуальные цены и управлять маркетинговыми кампаниями без постоянного контроля.
Как реализовать автоматическое изменение цены через хуки WooCommerce
WooCommerce предоставляет фильтр woocommerce_product_get_price и похожие хуки для изменения цены товара на лету. Основная идея — перехватить запрос цены и подставить новую в зависимости от заданных условий.
Пример: снижение цены на 10% для товаров категории «Распродажа»
add_filter('woocommerce_product_get_price', 'custom_dynamic_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_dynamic_price', 10, 2);
add_filter('woocommerce_product_get_sale_price', 'custom_dynamic_price', 10, 2);
function custom_dynamic_price($price, $product) {
if (has_term('rasprodazha', 'product_cat', $product->get_id())) {
$new_price = $price * 0.9; // скидка 10%
return round($new_price, 2);
}
return $price;
}Этот код подключается к фильтру получения цены и возвращает цену со скидкой, если товар принадлежит категории «rasprodazha».
Пошаговое решение для условий по дате и пользовательской роли
Задача:
- Снизить цену на 15% только в период с 1 по 10 число каждого месяца.
- Применять скидку только для пользователей с ролью «subscriber».
Код решения:
add_filter('woocommerce_product_get_price', 'conditional_price_change', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'conditional_price_change', 10, 2);
function conditional_price_change($price, $product) {
if (!is_user_logged_in()) return $price; // для гостей не меняем
$user = wp_get_current_user();
if (!in_array('subscriber', (array) $user->roles)) return $price; // только подписчики
$day = date('j');
if ($day < 1 || $day > 10) return $price; // не в нужный период
$new_price = $price * 0.85; // скидка 15%
return round($new_price, 2);
}Проверка результата после внедрения
- Авторизуйтесь под пользователем с ролью
subscriberи перейдите на страницу товара из нужной категории или с нужными условиями. - Проверьте отображаемую цену — она должна быть снижена согласно логике.
- Выйдите из аккаунта или войдите под пользователем без соответствующей роли — цена должна быть исходной.
- Измените дату сервера (или подождите нужный период) и проверьте изменение цены.
Частые ошибки и как их исправить
- Цена не меняется на страницах корзины и оформления заказа. По умолчанию фильтры на получение цены влияют на отображение, но в корзине и заказе нужно дополнительно применять
woocommerce_before_calculate_totalsдля обновления стоимости позиций. - Кэширование делает видимой старую цену. Отключите кэш страниц или настройте исключения для страниц магазина и товара.
- Использование неправильных хуков. Для изменения цены товара используйте именно
woocommerce_product_get_priceиwoocommerce_product_get_regular_price, а не устаревшие фильтры. - Цена становится равна 0 или отрицательная. Добавьте проверку, чтобы цена не опускалась ниже минимально допустимой.
Дополнение: изменение цены в корзине и на этапе оформления заказа
Чтобы цена обновлялась корректно в корзине и заказах, добавьте следующий код:
add_action('woocommerce_before_calculate_totals', 'update_cart_item_prices');
function update_cart_item_prices($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
foreach ($cart->get_cart() as $cart_item) {
$product = $cart_item['data'];
$price = $product->get_price();
// Ваша логика изменения цены, например:
if (has_term('rasprodazha', 'product_cat', $product->get_id())) {
$new_price = $price * 0.9;
$cart_item['data']->set_price(round($new_price, 2));
}
}
}Сравнение вариантов реализации изменения цены
| Метод | Плюсы | Минусы | Применение |
|---|---|---|---|
Фильтры woocommerce_product_get_price | Легко применить, изменяет цену везде на сайте | Не меняет цену в корзине без дополнительного кода | Динамическое отображение цены |
Хук woocommerce_before_calculate_totals | Изменяет цену в корзине и заказах | Нужно отдельно реализовать логику | Обновление цены при оформлении заказа |
| Плагины скидок/акций | Готовые решения с интерфейсом | Могут быть тяжелыми, ограниченная гибкость | Маркетинговые акции |
Практические советы по производительности и безопасности
- Кэширование: исключите страницы магазина и корзины из кэширования, чтобы динамические цены обновлялись корректно.
- Тестирование: проверяйте изменения цены на разных ролях пользователей и в разных браузерах.
- Минимальная цена: добавьте проверку, чтобы цена не стала ниже себестоимости или нуля.
- Обновление WooCommerce и темы: убедитесь, что код совместим с текущей версией плагина.