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

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

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

Диагностика: почему не меняются цены через этот хук

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

  • Вы изменяете цену именно в объекте $cart_item['data'], а не в копии.
  • Изменения делаете при каждой загрузке, а не только один раз — иначе корзина может не обновиться.
  • Нет конфликтов с другими плагинами, которые могут переопределять цены после вашего хука.
  • Вы не кэшируете страницы с корзиной или кэш очищается при изменении корзины.

Пошаговое решение: пример кода для динамического снижения цены на 10%

Добавьте следующий код в functions.php вашей темы или в кастомный плагин:

add_action('woocommerce_before_calculate_totals', 'custom_dynamic_price_adjustment', 20, 1);
function custom_dynamic_price_adjustment( $cart ) {
    if ( is_admin() && ! defined('DOING_AJAX') ) {
        return;
    }

    // Чтобы избежать многократного применения
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) {
        return;
    }

    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $product = $cart_item['data'];
        $original_price = $product->get_regular_price();
        $new_price = $original_price * 0.9; // Снижение на 10%
        $product->set_price( $new_price );
    }
}

Объяснение:

  • Проверяем, что код не срабатывает в админке вне AJAX.
  • Избегаем повторного применения изменения цен.
  • Идем по всем товарам в корзине и уменьшаем цену на 10% от регулярной цены.

Как изменить цену только для определённой категории товаров

foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
    $product = $cart_item['data'];
    if ( has_term( 'sale-category', 'product_cat', $product->get_id() ) ) {
        $original_price = $product->get_regular_price();
        $new_price = $original_price * 0.85; // 15% скидка на категорию
        $product->set_price( $new_price );
    }
}

Проверка результата: как убедиться, что цены изменились

  • Добавьте в корзину товары, подходящие под условия.
  • Перейдите на страницу корзины — цены должны измениться на указанный процент.
  • Используйте инструменты разработчика браузера, чтобы проверить итоговую цену товара в DOM.
  • Включите режим отладки WooCommerce define( 'WP_DEBUG', true ); и посмотрите, нет ли ошибок.

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

  • Изменение цены не на объекте продукта: нужно менять цену через $cart_item['data']->set_price(), иначе изменения не применятся.
  • Повторное срабатывание хука: если не ограничить вызов, цена может уменьшаться много раз, что приведет к неверным итогам.
  • Изменение цены в админке без AJAX: это может испортить данные при редактировании заказа.
  • Кэширование страницы корзины: если включено кэширование, изменения могут не отражаться. Рекомендуется исключить страницу корзины из кэша.

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

  • Избегайте тяжелых запросов и сложных вычислений в этом хуке — он вызывается при каждой загрузке корзины.
  • Кэшируйте результаты, если делаете запросы к базе или внешним API.
  • Используйте проверки is_admin() и DOING_AJAX, чтобы не менять цены в админке без необходимости.
  • При необходимости используйте пользовательские мета-поля для хранения условий скидок, чтобы не захламлять код.

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

МетодПлюсыМинусыКогда применять
Хук woocommerce_before_calculate_totalsГибкий, позволяет менять цену динамически, работает с корзинойТребует аккуратности, возможны баги при неправильном использованииДинамические скидки, акции, специальные цены
Использование плагинов скидокПростота настройки, готовые решенияМожет быть тяжёлым, ограниченная кастомизацияСтандартные скидки без кастома
Изменение цены в базе или через meta поляПостоянное изменение цены товараМенее гибко, влияет на все заказыЕсли цена должна меняться для всех покупателей
Как сделать автоматический экспорт постов WordPress в Excel
30.03.2026
Автоматическая замена изображений вариаций в WooCommerce
12.05.2026
WooCommerce: как использовать хук woocommerce_before_calculate_totals для автоматического изменения цен
07.07.2026
Как избежать конфликтов между плагинами в WordPress
22.01.2026
WooCommerce: автоматическое изменение стоимости товара при применении купона
30.06.2026