WooCommerce: изменение цены товара в корзине через хук woocommerce_before_calculate_totals

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

Часто возникает необходимость изменить цену товара в корзине динамически — например, применить скидку, изменить цену в зависимости от выбранных опций или пользовательских условий. Многие пытаются изменить цену товара, модифицируя объект товара в корзине, но это не всегда работает из-за особенностей WooCommerce и кеширования цен.

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

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

1. Подключаем функцию к хуку

Хук woocommerce_before_calculate_totals вызывается в момент пересчёта корзины. Здесь можно получить все товары и изменить их цены.

2. Изменяем цену товара в корзине

Пример функции, которая изменяет цену всех товаров на фиксированную:

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

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

    foreach ( $cart->get_cart() as &$cart_item ) {
        // Новая цена, например фиксированная 500 рублей
        $new_price = 500;
        $cart_item['data']->set_price( $new_price );
    }
}

3. Учёт условий для изменения цены

Можно добавить проверку по ID товара, категории, пользовательским мета или другим условиям.

foreach ( $cart->get_cart() as &$cart_item ) {
    $product_id = $cart_item['product_id'];
    if ( $product_id === 123 ) { // Только для товара с ID 123
        $cart_item['data']->set_price( 300 );
    }
}

Проверка результата после внедрения

После добавления кода:

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

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

  • Изменение цены вне хука woocommerce_before_calculate_totals: цена не применяется. Решение — использовать именно этот хук.
  • Множественное применение функции: цена меняется несколько раз, что ломает логику. Используйте проверку did_action.
  • Изменение цены в админке: приводит к ошибкам. Добавьте проверку is_admin() && ! defined('DOING_AJAX'), чтобы исключить админку.
  • Неправильный объект: меняйте цену через $cart_item['data']->set_price(), а не напрямую в массиве.

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

  • Вызывайте функцию с приоритетом 10 и одним аргументом — это стандарт и оптимально для WooCommerce.
  • Избегайте тяжелых запросов внутри функции изменения цены, чтобы не замедлять загрузку корзины.
  • Кешируйте результаты, если вычисления сложные, но помните, что цена может быть разной для каждого пользователя.
  • Следите за обновлениями WooCommerce — API для корзины может меняться.

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

МетодПлюсыМинусыКогда использовать
Хук woocommerce_before_calculate_totals Корректный момент изменения, поддерживается WooCommerce, гибко Требует правильной реализации, может влиять на производительность при сложных вычислениях Изменение цены динамически в корзине
Прямое изменение цены товара Просто, но часто не работает Не учитывает логику корзины, цены могут не обновиться Редкие случаи, когда нужна простая замена
Плагины скидок и акций Удобно и быстро Зависимость от стороннего кода, ограниченная кастомизация Если нужна стандартная логика скидок
WooCommerce: как исправить проблемы с удалённым обновлением статуса заказа
11.06.2026
Как установить и настроить push-уведомления в WordPress
09.02.2026
Как решить проблему: не работает AJAX в WooCommerce при добавлении товара в корзину
18.04.2026
Как автоматизировать создание кастомных типов постов в WordPress
30.11.2025
Как отображать пользовательские метаданные в WordPress REST API
25.01.2026