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

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

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

Диагностика задачи: когда нужно менять цены в корзине через этот хук

Типичные сценарии использования:

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

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

Пошаговое решение: пример изменения цены для определенной роли пользователя

Рассмотрим пример, когда для пользователей с ролью subscriber нужно сделать скидку 10% на все товары в корзине.

add_action('woocommerce_before_calculate_totals', 'custom_discount_for_subscribers', 10, 1); 
function custom_discount_for_subscribers($cart) {
    if (is_admin() && !defined('DOING_AJAX')) return;
    if (did_action('woocommerce_before_calculate_totals') >= 2) return;

    if (current_user_can('subscriber')) {
        foreach ($cart->get_cart() as $cart_item) {
            $original_price = $cart_item['data']->get_regular_price();
            $discounted_price = $original_price * 0.9; // скидка 10%
            $cart_item['data']->set_price($discounted_price);
        }
    }
}

Объяснение:

  • Проверяем, что действие не выполняется в админке и не дважды подряд.
  • Проверяем роль пользователя через current_user_can().
  • Проходимся по всем товарам в корзине и устанавливаем новую цену через set_price().

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

  1. Залогиньтесь под пользователем с ролью subscriber.
  2. Добавьте в корзину товары.
  3. Перейдите в корзину и убедитесь, что цены уменьшились ровно на 10%.
  4. Залогиньтесь под другим пользователем без роли subscriber и проверьте, что цены не изменились.

Для дополнительной проверки можно временно включить вывод цены в консоль, добавив error_log('Цена товара: '.$cart_item['data']->get_price()); внутри цикла.

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

  • Изменение цены вне хука: попытка изменить цену в других хуках, где итоговая сумма уже посчитана, не даст эффекта.
  • Двойной вызов: неиспользование did_action приводит к бесконечным циклам и ошибкам.
  • Изменение цены в админке: без проверки is_admin можно сломать работу админ-панели.
  • Неправильное получение цены: использование get_price() вместо get_regular_price() может привести к неверным расчетам.

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

  • Всегда проверяйте роль или условия, чтобы не выполнять ненужные операции на каждом обновлении корзины.
  • Избегайте тяжелых запросов и сложной логики внутри хука, так как это может замедлить процесс подсчета корзины.
  • Внимательно тестируйте работу на разных типах товаров (простой, вариативный, с акциями).
  • Используйте did_action для предотвращения рекурсий.

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

МетодГде применяетсяПлюсыМинусы
Хук woocommerce_before_calculate_totalsИзменение цены перед расчетом корзиныНадежно меняет итоговую цену, работает с любыми товарамиТребует правильной реализации, чтобы избежать рекурсий
Фильтр woocommerce_get_priceВывод цены товараПозволяет менять цену на фронтендеНе меняет итоговую сумму в корзине
Плагины скидокГотовые решения для скидокПросты в использовании, много опцийМогут быть тяжелыми, не всегда гибкие
Как создать автоматический отчет в WordPress с помощью WP-Cron и REST API
28.03.2026
Добавление пользовательского поля профиля на фронтенде WordPress
17.03.2026
Оптимизация базы данных WordPress для повышения производительности сайта
16.11.2025
Как создать настройки плагина WordPress на основе Customizer
11.04.2026
Как использовать хук WooCommerce woocommerce_before_calculate_totals для изменения цен в корзине
13.05.2026