Диагностика задачи: зачем менять цены автоматически по акциям
В интернет-магазинах на WooCommerce часто требуется менять цены товаров в зависимости от акций: скидка на категорию, скидка на товар при достижении определенного количества в корзине, или временные промо-акции. Ручное изменение цен неэффективно и приводит к ошибкам, если акций много или они часто меняются.
Основная задача — реализовать автоматическое изменение стоимости товаров по кастомным правилам, при этом сохранив корректное отображение цены для пользователя и правильное поведение корзины и заказов.
Обзор проблем при автоматическом изменении цены в WooCommerce
- Изменение цены напрямую в базе данных ведет к потере оригинальной цены и проблемам с отчетами.
- Изменение цены через хуки должно учитываться в корзине, на странице товара, в заказах и уведомлениях.
- Нужно избегать конфликтов с другими плагинами, например, скидочными или кеширующими.
- Важна производительность — цена рассчитывается на лету, без лишних запросов.
Как реализовать автоматическую скидку по кастомным правилам через хуки WooCommerce
Самый правильный способ — использовать хук woocommerce_get_price или woocommerce_product_get_price для изменения цены товара при выводе, а для корзины — woocommerce_before_calculate_totals.
Пример: скидка 20% на все товары категории «Распродажа»
add_action('woocommerce_before_calculate_totals', 'custom_discount_on_sale_category', 10, 1);
function custom_discount_on_sale_category($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
if (did_action('woocommerce_before_calculate_totals') >= 2) return;
foreach ($cart->get_cart() as $cart_item) {
$product = $cart_item['data'];
if (has_term('sale', 'product_cat', $product->get_id())) {
$regular_price = $product->get_regular_price();
$discounted_price = $regular_price * 0.8; // 20% скидка
$product->set_price($discounted_price);
}
}
}Этот код применит скидку в корзине и на странице оформления заказа. Чтобы цена на странице товара тоже менялась, добавим фильтр:
add_filter('woocommerce_product_get_price', 'custom_price_on_product_page', 10, 2);
function custom_price_on_product_page($price, $product) {
if (has_term('sale', 'product_cat', $product->get_id())) {
$regular_price = $product->get_regular_price();
return $regular_price * 0.8; // 20% скидка
}
return $price;
}Пошаговое решение для кастомных правил изменения цены
- Определите правило: например, 10% скидка на категорию «Акции» с 1 по 10 число месяца.
- Добавьте проверку даты и категории в функции изменения цены.
- Используйте хуки
woocommerce_before_calculate_totalsдля корзины иwoocommerce_product_get_priceдля страницы товара. - Проверьте, что цена меняется на всех этапах: страница товара, корзина, оформление заказа, email уведомления.
- Если используется кеширование, добавьте исключения для страниц корзины и оформления заказа.
Проверка результата после внедрения
- Откройте страницу товара из категории акции – должна показываться сниженная цена.
- Добавьте товар в корзину – в корзине цена должна быть со скидкой.
- Перейдите к оформлению заказа – скидка сохраняется.
- Оформите заказ и проверьте в админке, что цена заказа соответствует скидке.
- Проверьте email уведомления, чтобы цена была корректной.
Частые ошибки при автоматическом изменении цен и как их исправить
- Цена меняется только на странице товара, но не в корзине. Решение: обязательно использовать
woocommerce_before_calculate_totalsдля изменения цены в корзине. - Цена в заказах не совпадает с отображаемой. Нужно сохранять оригинальную цену и скидку отдельно, не перезаписывать цену товара в базе.
- Проблемы с кешированием страниц. Исключайте страницы корзины и оформления заказа из кеша, либо используйте AJAX обновление корзины.
- Фильтры не вызываются для вариативных товаров. Обрабатывайте цены вариаций отдельно с помощью
woocommerce_variation_get_price.
Практические советы по безопасности и производительности
- Не записывайте изменённые цены в базу, используйте только хуки для динамического изменения.
- Оптимизируйте проверки, например, кэшируйте результат has_term, чтобы не нагружать БД.
- Добавьте проверку
is_admin()иDOING_AJAX, чтобы исключить ненужное выполнение в админке. - Используйте точные условия даты и времени для временных акций, чтобы избежать ошибок.
Сравнение способов реализации автоматической скидки
| Способ | Плюсы | Минусы |
|---|---|---|
| Прямое изменение цены в базе | Простота реализации | Потеря истории, проблемы с отчетами, баги в заказах |
| Использование хуков (рекомендуется) | Динамичность, безопасность, совместимость | Требует точного кода, может конфликтовать с кешем |
| Плагины скидок | Удобство, поддержка, гибкость | Нагрузка на сайт, стоимость, ограниченная кастомизация |