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

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

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

Основная проблема — понять, какой именно хук использовать, и как правильно изменить цену без конфликтов с кэшированием и другими плагинами.

Выбор правильных хуков для динамического изменения цены

Для изменения цены товара в WooCommerce чаще всего используются фильтры:

  • woocommerce_product_get_price — возвращает цену для продукта;
  • woocommerce_product_get_regular_price — цена без скидки;
  • woocommerce_product_get_sale_price — цена со скидкой;
  • woocommerce_get_price_html — позволяет изменить HTML вывода цены;
  • woocommerce_cart_item_price — цена товара в корзине.

Для динамического изменения цены в корзине и на странице оформления заказа применяют фильтры, связанные с объектами корзины, например woocommerce_before_calculate_totals.

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

Задача: скидка 10% для пользователей с ролью "subscriber" на все товары.

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

    $user = wp_get_current_user();
    if ( in_array('subscriber', (array) $user->roles) ) {
        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 );
        }
    }
}

Этот код проверяет роль пользователя при расчете корзины и меняет цену каждого товара на 90% от регулярной.

Изменение цены на странице товара

Чтобы цена отображалась измененной и на странице товара, можно использовать фильтр woocommerce_product_get_price:

add_filter('woocommerce_product_get_price', 'custom_dynamic_price_display', 10, 2);
function custom_dynamic_price_display( $price, $product ) {
    $user = wp_get_current_user();
    if ( in_array('subscriber', (array) $user->roles) ) {
        return $price * 0.9; // 10% скидка
    }
    return $price;
}

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

  • Залогиньтесь под пользователем с ролью "subscriber" и проверьте цену товара на странице товара и в корзине — она должна быть на 10% ниже.
  • Залогиньтесь под другим пользователем или гостем — цена должна оставаться без изменений.
  • Очистите кэш сайта и браузера, чтобы убедиться, что изменения видны.
  • Проверьте, что на странице оформления заказа и в письмах цена соответствует измененной.

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

  • Цена не меняется на странице товара: возможно, используется кэширование или фильтр применяется некорректно. Проверьте, что код подключен в functions.php или плагине и что нет конфликтов с другими плагинами кэширования.
  • Цена меняется, но в корзине и на странице оформления заказа не обновляется: убедитесь, что используется woocommerce_before_calculate_totals и что функция не вызывается дважды (смотрите проверку did_action).
  • Ошибка "Cannot modify header information": проверьте, что в файлах нет лишних пробелов или пустых строк до <?php или после ?>.
  • Изменение цены влияет на отчеты и заказы некорректно: помните, что динамическое изменение цены — только для отображения и расчета в корзине. Для изменения данных заказа нужно использовать хуки при сохранении заказа.

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

  • Не используйте динамическое изменение цены для важных финансовых данных без логирования — это может запутать владельца магазина.
  • Всегда проверяйте пользовательскую роль через wp_get_current_user(), а не через глобальные переменные.
  • Избегайте тяжелых операций внутри хука woocommerce_before_calculate_totals, чтобы не замедлять процесс оформления заказа.
  • Тестируйте изменения на тестовой среде и с отключенным кэшем, чтобы избежать ложных срабатываний.

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

МетодПреимуществаНедостатки
Фильтр woocommerce_product_get_priceИзменяет цену на странице товара и везде, где берется ценаНе влияет на цену в корзине по умолчанию, требуется дополнительный код
Хук woocommerce_before_calculate_totalsИзменяет цену в корзине и на этапе оформления заказаНе меняет цену на странице товара без дополнительных фильтров
Изменение цены через метаданные товараСохраняется в базе, работает во всех местахТребует модификации товара, не подходит для временных скидок
Как удалить метаданные из файлов при загрузке в медиа библиотеку WordPress
05.12.2025
Оптимизация базы данных WordPress для ускорения сайта
27.11.2025
Как правильно удалить оставшиеся заказы WooCommerce без ошибок
09.06.2026
Как удалить неиспользуемые атрибуты продуктов WooCommerce без ошибок
10.07.2026
Как решить проблему не удаления товаров из WooCommerce после их удаления
22.04.2026