Диагностика проблемы: необходимость автоматического изменения цены при скидках в WooCommerce
Часто в WooCommerce возникает задача не просто установить скидку, а динамически изменять цены товаров при определённых условиях — например, при распродаже, по времени или в зависимости от категории. В стандартном функционале WooCommerce можно задать фиксированную скидку или процент, но для более сложных сценариев требуется программирование.
Проверить, что текущий функционал не подходит, можно, если:
- нельзя задать скидку с нужной логикой через стандартные купоны или правила ценообразования;
- нужно комплексно менять цену в зависимости от нескольких параметров;
- нужно отображать изменённую цену в корзине и на странице товара без плагинов.
Пошаговое решение: автоматическое изменение цен с помощью фильтра woocommerce_product_get_price
1. Используем фильтр для изменения цены при загрузке товара
WooCommerce предоставляет фильтры woocommerce_product_get_price и woocommerce_product_get_regular_price, которые позволяют программно подменять цену товара при запросах. Пример кода ниже показывает, как задать скидку 20% для товаров из категории «sale».
add_filter('woocommerce_product_get_price', 'custom_dynamic_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_dynamic_price', 10, 2);
function custom_dynamic_price($price, $product) {
if (has_term('sale', 'product_cat', $product->get_id())) {
$discount = 0.2; // 20% скидка
$price = $price * (1 - $discount);
}
return $price;
}2. Обработка цены в админке и других местах
Чтобы цена была корректно показана во всех местах, добавьте аналогичный фильтр на woocommerce_get_price_html для отображения цены с учётом скидки.
add_filter('woocommerce_get_price_html', 'custom_dynamic_price_html', 10, 2);
function custom_dynamic_price_html($price_html, $product) {
if (has_term('sale', 'product_cat', $product->get_id())) {
$regular_price = wc_price($product->get_regular_price());
$discounted_price = wc_price($product->get_price());
$price_html = '<del>' . $regular_price . '</del> <ins>' . $discounted_price . '</ins>';
}
return $price_html;
}Как проверить результат после внедрения
- Перейдите на страницу товара из категории «sale» — цена должна отображаться с зачеркнутым оригиналом и новой ценой с 20% скидкой.
- Добавьте товар в корзину — в корзине и на странице оформления заказа должна отображаться обновлённая цена.
- В админке в списке товаров проверьте, что цена не изменилась в базе, а только отображается со скидкой.
Частые ошибки при автоматическом изменении цены и как их исправить
- Цена не меняется на странице товара — возможно, не используются все необходимые фильтры (
woocommerce_product_get_priceиwoocommerce_get_price_html). - Цена меняется в админке — фильтры влияют только на отображение, не изменяйте напрямую
post_metaс ценами без веских причин. - Скидка применяется к уже изменённой цене, получается двойное уменьшение — используйте
$product->get_regular_price()для расчёта скидки, а не$product->get_price(). - Кэширование отображает старую цену — очистите кэш плагинов (например, WP Rocket, W3 Total Cache) и браузера.
Практические советы по производительности и безопасности
- Не делайте сложные запросы к базе внутри фильтров цены — используйте кэширующие механизмы и минимизируйте нагрузку.
- Для условий скидок используйте термины таксономий, мета-поля товара или пользовательские флаги, чтобы избежать сложных вычислений.
- Проверяйте, что фильтры не влияют на API-запросы, если это нежелательно (например, добавьте проверку
is_admin()илиwp_doing_ajax()).
Сравнение вариантов реализации автоматического изменения цены
| Способ | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| Плагины скидок и динамического ценообразования | Простота настройки, готовые правила | Могут быть платными, нагрузка | Если нужна гибкая настройка без кода |
| Фильтры WooCommerce в коде (как выше) | Полный контроль, бесплатно, гибко | Требует навыков программирования, можно ошибиться | Для уникальных бизнес-логик и оптимизации |
| Изменение цен в базе данных (через SQL или import) | Простота, если скидка постоянная | Изменяет исходные данные, риск ошибок | Для разовых массовых изменений |