Диагностика проблемы: почему не изменяется стоимость товара в WooCommerce
Если вы пытаетесь программно изменить цену товара в WooCommerce через хук или фильтр, но цена на сайте остается прежней, скорее всего причина в неправильном месте или времени применения изменений. Часто разработчики используют фильтры, которые не влияют на итоговую цену, либо меняют данные объекта продукта после того, как цена уже закеширована или вычислена для корзины.
Для диагностики проверьте, какой именно хук вы используете, и в каком месте кода происходит изменение цены. Также убедитесь, что нет конфликтов с другими плагинами или темой, перекрывающими ваши изменения.
Основные причины неработающей функции изменения цены:
- Использование фильтра
woocommerce_get_price, который не применяется для корзины и оформления заказа. - Изменение цены не в момент расчёта, а на более позднем этапе, когда цена уже установлена.
- Кэширование цен WooCommerce или плагинами кеширования.
- Отсутствие работы вашего кода при AJAX-запросах корзины и страницы оформления заказа.
Пошаговое решение: как правильно изменить стоимость товара программно
Для динамического изменения цены товара в WooCommerce используйте фильтр woocommerce_product_get_price и woocommerce_product_get_regular_price. Они вызываются при получении цены товара, в том числе при расчёте корзины.
Пример корректного сниппета для изменения цены товара с ID 123 в зависимости от условия:
add_filter('woocommerce_product_get_price', 'custom_change_product_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_change_product_price', 10, 2);
function custom_change_product_price($price, $product) {
// Проверяем ID товара
if ($product->get_id() === 123) {
// Пример: уменьшаем цену на 10%
$price = $price * 0.9;
}
return $price;
}Если нужно изменить цену только для корзины и оформления заказа, можно использовать фильтр woocommerce_before_calculate_totals и изменять цену через метод set_price() для каждого товара в корзине:
add_action('woocommerce_before_calculate_totals', 'custom_change_cart_item_price', 20, 1);
function custom_change_cart_item_price($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$product = $cart_item['data'];
if ($product->get_id() === 123) {
// Уменьшаем цену на 10%
$new_price = $product->get_price() * 0.9;
$product->set_price($new_price);
}
}
}Проверка результата после внедрения
Чтобы убедиться, что цена товара изменилась:
- Откройте страницу товара и посмотрите цену — она должна отображаться с учётом изменений.
- Добавьте товар в корзину и проверьте цену в корзине и на странице оформления заказа.
- Если используете кэш, очистите его (включая кэш браузера и плагинов).
- Для проверки можно временно отключить другие плагины, влияющие на цены, чтобы исключить конфликты.
Частые ошибки и как их исправить
- Изменение цены в неправильном хуке: Используйте
woocommerce_product_get_priceилиwoocommerce_before_calculate_totalsвместоwoocommerce_get_price. - Изменения не применяются к вариациям: Уточните ID вариации или применяйте фильтр к вариациям через
$product->get_parent_id(). - Конфликты с кешированием: Отключите плагин кеширования или исключите страницы корзины и оформления заказа из кеша.
- Цена изменяется, но в корзине отображается старая: Проверьте, что изменение происходит в
woocommerce_before_calculate_totals, до подсчёта итогов. - Код не выполняется при AJAX-запросах: Убедитесь, что ваш код подключён везде и не ограничен условием
! is_admin()без проверкиDOING_AJAX.
Практические советы по производительности и безопасности
- Избегайте тяжелых вычислений внутри хуков изменения цены — это может увеличить время загрузки страниц.
- Кэшируйте результаты, если цена зависит от сложных условий, используя transient API.
- Не меняйте цены напрямую в базе данных — используйте официальные хуки и методы WooCommerce.
- Проверяйте права доступа, если ваша логика зависит от роли пользователя или других условий.
Сравнение способов изменения цены в WooCommerce
| Метод | Когда применять | Плюсы | Минусы |
|---|---|---|---|
Фильтр woocommerce_product_get_price | Изменение цены на всех этапах (отображение, корзина) | Гибко, влияет на всю цепочку цен | Не всегда работает с вариациями без дополнительного кода |
Хук woocommerce_before_calculate_totals | Изменение цены только в корзине и оформлении заказа | Удобно для скидок, промо | Не меняет цену на странице товара |