Диагностика задачи: зачем и когда нужна автоматическая смена цен
В WooCommerce часто возникает необходимость менять цены товаров динамически: для разных групп пользователей, при покупке определенного количества или в зависимости от времени акции. Ручное обновление цен неудобно и рискованно. Автоматизация с помощью хуков WooCommerce позволяет гибко управлять ценообразованием без сторонних плагинов.
Выбор подхода для динамического изменения цен
Существует три основных метода изменения цены в WooCommerce:
- Фильтр
woocommerce_product_get_price— изменяет цену товара при получении. Позволяет подменять цену на лету. - Фильтр
woocommerce_get_price_html— меняет отображение цены, но не влияет на расчеты. - Хуки в корзине (
woocommerce_before_calculate_totals) — изменяют цену товара в момент подсчета итогов заказа, что подходит для скидок и акций.
Таблица сравнения методов
| Метод | Влияние на цену | Подходит для | Минусы |
|---|---|---|---|
| woocommerce_product_get_price | Цена товара везде | Полная динамика цен | Сложно отследить, влияет на все запросы |
| woocommerce_get_price_html | Только отображение | Визуальные скидки, без влияния на заказ | Не меняет итоговую цену |
| woocommerce_before_calculate_totals | Цена в корзине и заказе | Скидки, акции при заказе | Цена товара в каталоге не меняется |
Пошаговое решение: пример автоматической скидки при покупке более 3-х товаров
- Подключитесь к хуку
woocommerce_before_calculate_totals. - Проверьте количество товаров в корзине.
- Измените цену каждого товара, если условие выполняется.
add_action('woocommerce_before_calculate_totals', 'custom_bulk_discount', 10, 1);
function custom_bulk_discount($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
// Минимум 3 товара в корзине для скидки
$total_qty = 0;
foreach (WC()->cart->get_cart() as $cart_item) {
$total_qty += $cart_item['quantity'];
}
if ($total_qty >= 3) {
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$original_price = $cart_item['data']->get_regular_price();
$discounted_price = $original_price * 0.9; // Скидка 10%
$cart_item['data']->set_price($discounted_price);
}
}
}
Проверка результата после внедрения
- Добавьте в корзину 3 и более товара — цена должна измениться с учетом скидки.
- Проверьте страницу товара — цена там останется без изменений, скидка применяется только в корзине и заказе.
- Оформите заказ и проверьте итоговую сумму.
Частые ошибки и их исправление
- Скидка не применяется: убедитесь, что хук добавлен с приоритетом не выше 10 и функция вызывается.
- Цена меняется в админке или AJAX: добавьте условие
if (is_admin() && !defined('DOING_AJAX')) return;для исключения. - Цена меняется в каталоге товаров: используйте хук изменения цены только на этапе корзины, не меняйте
woocommerce_product_get_priceбез условий. - Кэш мешает видеть изменения: очистите кэш сайта и браузера, отключите Object Cache при тестировании.
Практические советы по безопасности и производительности
- Избегайте выполнения тяжелых вычислений внутри хуков изменения цены.
- Не храните цены в пользовательских метаполях для динамических скидок, используйте фильтры.
- Для сложной логики используйте отдельный класс или сервис, чтобы не засорять functions.php.
- Проверяйте совместимость с кеширующими плагинами (например, Clearfy Pro может помочь с оптимизацией).