WooCommerce: как использовать хук woocommerce_before_calculate_totals для динамических изменений цен в корзине

Что такое хук woocommerce_before_calculate_totals и зачем он нужен

Хук woocommerce_before_calculate_totals срабатывает перед расчетом итоговой стоимости корзины в WooCommerce. Это идеальное место для динамического изменения цен товаров в корзине — например, для применения пользовательских скидок, изменения стоимости в зависимости от количества или кастомных условий.

В отличие от прямого изменения цены товара в базе, использование этого хука позволяет менять стоимость только для текущей сессии покупателя без нарушения данных в базе WooCommerce.

Диагностика проблемы с динамическим изменением цены

Часто разработчики сталкиваются с тем, что изменения цены в корзине не применяются или сбрасываются после обновления страницы. Основные причины:

  • Неправильный способ изменения цены — изменение свойства $cart_item['data']->price нужно делать правильно.
  • Хук вызывается не в нужное время, или изменения применяются вне цикла корзины.
  • Кэширование на уровне плагинов или сервера, из-за которого изменения не видны.

Пошаговое решение: как правильно использовать woocommerce_before_calculate_totals

Рассмотрим пример кода, который уменьшает цену товара на 10% при количестве товара в корзине больше 3 штук:

add_action('woocommerce_before_calculate_totals', 'custom_dynamic_price_change', 10, 1);
function custom_dynamic_price_change( $cart ) {
    if ( is_admin() && ! defined('DOING_AJAX') ) return;
    
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $product = $cart_item['data'];
        $quantity = $cart_item['quantity'];
        if ( $quantity > 3 ) {
            $original_price = $product->get_regular_price();
            $discounted_price = $original_price * 0.9; // скидка 10%
            $product->set_price( $discounted_price );
        } else {
            // возвращаем оригинальную цену, если условие не выполняется
            $product->set_price( $product->get_regular_price() );
        }
    }
}

Ключевые моменты:

  • Проверяем, что мы не в админке (кроме AJAX запросов).
  • Перебираем все товары в корзине.
  • Устанавливаем новую цену через метод set_price() объекта товара.
  • Обязательно возвращаем цену к оригинальной, чтобы избежать фиксации скидки после удаления из корзины.

Как проверить, что динамическое изменение цены сработало

1. Добавьте в корзину товар в количестве больше 3 штук — цена должна уменьшиться на 10%.
2. Измените количество на 3 или меньше — цена должна вернуться к исходной.
3. Проверьте отображение цены на странице корзины и оформления заказа.
4. Откройте консоль браузера и отключите кэширование, чтобы убедиться, что цены обновляются динамически.

Частые ошибки при использовании woocommerce_before_calculate_totals и как их исправить

  • Изменения не применяются: Не используйте $cart_item['data']->price напрямую, используйте set_price().
  • Цена остается измененной после удаления товара: Всегда возвращайте цену к оригинальной, если условие не выполняется.
  • Изменения влияют на админку и вызывают ошибки: Добавьте проверку if ( is_admin() && ! defined('DOING_AJAX') ) return;.
  • Кэширование мешает увидеть изменения: Отключите кэш плагинов на время теста или используйте режим разработчика.

Практические советы по производительности и безопасности

  • Минимизируйте сложные вычисления внутри цикла корзины, чтобы не замедлять загрузку страницы.
  • Не сохраняйте измененную цену в базе данных — изменения должны быть только в сессии пользователя.
  • Используйте проверку условий для применения изменений, чтобы избежать ненужных вызовов.
  • Если нужна более сложная логика, выделите ее в отдельные функции для удобства тестирования и поддержки.

Сравнение способов динамического изменения цены в корзине WooCommerce

МетодПлюсыМинусыКогда использовать
Хук woocommerce_before_calculate_totals с set_price()Работает без изменений в базе, динамически, простоНе подходит для сложных акций с сохранением в заказеДинамические скидки в корзине и чекауте
Использование плагинов скидок (например, WooCommerce Dynamic Pricing)Готовые функции, много условий, интерфейсМожет быть тяжелым, платным, избыточнымСложные маркетинговые акции
Изменение цены в базе товараПостоянное изменение ценыНарушает историю заказов, не подходит для временных скидокДолгосрочные изменения
Как автоматизировать обновление публикаций в WordPress с помощью WP-Cron
27.02.2026
Как добавить автоматическое удаление старых комментариев в WordPress
04.03.2026
WooCommerce: как автоматически удалять заказы со статусом Отменен и Возврат
11.06.2026
WooCommerce: решение проблемы не обновляющегося SKU вариаций товаров
07.05.2026
WooCommerce: как автоматически удалять заказы со статусом Отменен и Возврат
18.06.2026