Диагностика задачи: зачем менять цены товаров программно в WooCommerce
В ряде сценариев требуется динамически корректировать цену товара в WooCommerce без ручного редактирования в админке. Например, сезонные скидки, изменения цены по количеству в корзине, специальные условия для определённых ролей пользователей или автоматическое повышение цены при низком остатке на складе.
Стандартные настройки WooCommerce и плагины скидок не всегда способны покрыть такие специфические условия, и тогда приходится внедрять кастомный код.
Как программно изменять цены товаров в WooCommerce: пошаговое решение
Использование фильтра woocommerce_get_price
Для изменения цены товара на лету, перед её выводом, можно использовать фильтр woocommerce_get_price. Ниже пример, который увеличивает цену на 10% для товаров категории special-offer:
add_filter('woocommerce_get_price', 'custom_dynamic_price', 10, 2); function custom_dynamic_price($price, $product) { if(has_term('special-offer', 'product_cat', $product->get_id())) { $price = $price * 1.1; } return $price; }Изменение цены с учётом роли пользователя
Если нужно менять цену для определённых ролей (например, для оптовиков), добавим проверку роли:
add_filter('woocommerce_get_price', 'price_for_wholesale_users', 10, 2); function price_for_wholesale_users($price, $product) { if(current_user_can('wholesale_customer')) { $price = $price * 0.85; // скидка 15% } return $price; }Изменение цены в зависимости от количества в корзине
Чтобы менять цену в зависимости от количества товара в корзине, можно использовать фильтр woocommerce_before_calculate_totals для изменения цены объектов корзины:
add_action('woocommerce_before_calculate_totals', 'bulk_price_adjustment'); function bulk_price_adjustment($cart) { if (is_admin() && !defined('DOING_AJAX')) return; foreach ($cart->get_cart() as $cart_item) { if ($cart_item['quantity'] >= 10) { $original_price = $cart_item['data']->get_regular_price(); $discounted_price = $original_price * 0.9; // 10% скидка $cart_item['data']->set_price($discounted_price); } } }Проверка результата после внедрения кода
- Откройте страницу товара из категории
special-offerи убедитесь, что цена увеличилась на 10%. - Залогиньтесь под пользователем с ролью
wholesale_customer(создайте её, если нет) и проверьте, что цена у товаров снижается на 15%. - Добавьте в корзину 10 и более единиц одного товара и проверьте, что цена в корзине изменилась согласно скидке 10%.
- Очистите кеш сайта и браузера, если используете кеширующие плагины или внешний кеш.
Частые ошибки и как их исправить
- Неправильный приоритет фильтра: убедитесь, что приоритет 10 или ниже, чтобы ваш фильтр сработал вовремя.
- Отсутствие проверки условий: всегда проверяйте условия (категория, роль), иначе код будет менять цену для всех товаров, что неправильно.
- Изменение цены напрямую в базе: не меняйте цены в таблицах базы — используйте фильтры, чтобы избежать проблем с обновлениями и кешем.
- Проблемы с кешированием: если цены не меняются, очистите кеш плагинов, CDN и браузера.
- Использование
woocommerce_get_price_htmlвместоwoocommerce_get_price: первый фильтр меняет только отображение цены, не влияет на расчёты корзины и оформления заказа.
Практические советы по производительности и безопасности
- Не вызывайте тяжелые запросы к базе внутри фильтров изменения цены — кешируйте результаты.
- Минимизируйте использование
current_user_canв циклах — лучше заранее определить роль пользователя. - Не записывайте изменённые цены в сессию или мета товары — используйте временные фильтры.
- Проверяйте совместимость с плагинами кеширования и оптимизации, чтобы не было расхождений цен.
Сравнение методов изменения цены в WooCommerce
| Метод | Преимущества | Недостатки |
|---|---|---|
Фильтр woocommerce_get_price | Изменяет цену везде (каталог, карточка, корзина) Гибко настраивается | Не всегда учитывает скидки и акции Нужно тщательно фильтровать условия |
Изменение цены в корзине (woocommerce_before_calculate_totals) | Изменяет цену только в корзине Удобно для скидок по количеству | Цена в каталоге не меняется Может конфликтовать с другими плагинами скидок |
| Плагины скидок | Просты в настройке, часто без кода | Могут быть дорогими Меньше гибкости под кастомные условия |