Использование хука woocommerce_before_calculate_totals для динамического изменения цен в WooCommerce

Для чего нужен хук woocommerce_before_calculate_totals и когда он применяется

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

Диагностика задачи: когда и почему не меняется цена в корзине

Если вы пытаетесь изменить цену товара в корзине через пользовательский код, но итоговая сумма не меняется, возможные причины:

  • Хук используется неправильно или с неверным приоритетом.
  • Изменения цены не применяются к объектам корзины, а только к локальным переменным.
  • Кеширование корзины или сторонние плагины перезаписывают итоговые цены после вашего кода.
  • Вы изменяете цену товара, а не цену позиции в корзине (cart item).

Для диагностики:

  • Подключите вывод error_log или var_dump внутри функции на хук, чтобы убедиться, что функция вызывается.
  • Проверьте, что изменяете цену именно объекта типа WC_Cart_Item внутри корзины.
  • Отключите временно кеширующие плагины и плагины, которые влияют на цены, чтобы исключить конфликт.

Пошаговое решение: как правильно изменить цену товара в корзине через хук

1. Используйте хук woocommerce_before_calculate_totals с достаточно низким приоритетом (например, 10).
2. В функции переберите все товары в корзине через WC()->cart->get_cart().
3. Для каждого товара измените цену через метод set_price() у объекта $cart_item['data'].
4. Добавьте проверку, чтобы не менять цену повторно (например, с помощью пользовательского флага в $cart_item).

add_action('woocommerce_before_calculate_totals', 'custom_change_price_in_cart', 10, 1); 
function custom_change_price_in_cart( $cart ) {
    if ( is_admin() && ! defined('DOING_AJAX') ) return;
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        if ( isset($cart_item['custom_price_applied']) ) continue;
        $original_price = $cart_item['data']->get_price();

        // Пример: уменьшаем цену на 15% для всех товаров
        $new_price = $original_price * 0.85;
        $cart_item['data']->set_price( $new_price );

        // Флаг, чтобы не менять цену повторно
        $cart_item['custom_price_applied'] = true;
    }
}

Как проверить, что решение работает

  • Добавьте товар в корзину и перейдите в корзину или оформление заказа — цена должна измениться согласно формуле.
  • В консоли или логе отладьте вывод цены до и после изменения.
  • Убедитесь, что сумма в итогах корзины пересчиталась и соответствует новым ценам.

Частые ошибки при изменении цены в корзине и способы их исправления

  • Изменение цены вне хука woocommerce_before_calculate_totals: цена не обновится — всегда используйте этот хук.
  • Изменение свойства $cart_item['data'] не через метод set_price(): напрямую менять свойства объекта WC_Product не рекомендуется, используйте официальные методы.
  • Отсутствие проверки флага изменения: приводит к множественным перерасчетам и ошибкам.
  • Вызов функции в админке без проверки: может вызвать ошибки — добавьте проверку is_admin() и DOING_AJAX.

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

  • Не меняйте цену в админке и при AJAX-запросах, которые не связаны с корзиной, чтобы избежать конфликтов.
  • Для сложных условий используйте кэширование расчетов, чтобы не перегружать сервер.
  • Тестируйте код на совместимость с другими плагинами, особенно с кеширующими и оптимизирующими.
  • В продакшене логирование отключайте, чтобы не засорять логи.

Таблица сравнения способов изменения цены в WooCommerce

МетодПрименениеПлюсыМинусы
Хук woocommerce_before_calculate_totalsДинамическое изменение цен в корзинеГибко, работает на лету, не требует плагиновТребует правильного кода, возможны конфликты
Плагины скидок и акцийПростое создание правил скидокУдобный интерфейс, поддержка большинства сценариевМожет влиять на производительность, ограничены логикой
Изменение цены товара через фильтры на уровне продуктаИзменение цены на страницах товаровВлияет на отображение, но не на корзинуНе подходит для динамических скидок в корзине
Как автоматически отключать плагины в WordPress по расписанию
13.01.2026
Почему не работают купоны в WooCommerce и как это исправить
25.04.2026
Как использовать хуки для автоматизации задач в WordPress
17.01.2026
Как быстро использовать атрибуты WooCommerce для фильтрации и вывода товаров
03.05.2026
WooCommerce: как использовать хук woocommerce_before_calculate_totals для автоматического изменения цен
07.07.2026