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

Обзор задачи: зачем менять стоимость товаров программно

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

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

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

  • Правильно ли выбран хук для изменения цены (например, woocommerce_before_calculate_totals для изменения цены в корзине)?
  • Изменяете ли вы цену объекта товара, а не просто переменную?
  • Не конфликтует ли ваш код с другими плагинами, которые могут перезаписывать цену?
  • Вы не изменяете цену товара в базе, а только для сессии пользователя?

Пошаговое решение: изменение цены в корзине с помощью хука

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

1. Подключаемся к хуку woocommerce_before_calculate_totals

Этот хук срабатывает при пересчёте стоимости товаров в корзине. В нём можно изменить цену каждого товара.

2. Проверяем роль пользователя и корректируем цену

add_action('woocommerce_before_calculate_totals', 'custom_wholesale_discount', 10, 1);
function custom_wholesale_discount($cart) {
    if (is_admin() && !defined('DOING_AJAX')) {
        return;
    }
    // Проверяем роль
    $user = wp_get_current_user();
    if (!in_array('wholesale_customer', (array) $user->roles)) {
        return;
    }
    // Проходим по товарам в корзине
    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $original_price = $product->get_regular_price();
        $discounted_price = $original_price * 0.9; // скидка 10%
        $product->set_price($discounted_price);
    }
}

3. Добавляем проверку, чтобы не применялось в админке и AJAX-запросах

Это нужно, чтобы не ломать обработку в панели управления и при обновлении корзины.

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

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

  • Залогиньтесь под пользователем с ролью wholesale_customer.
  • Добавьте товар в корзину.
  • В корзине цена должна автоматически уменьшиться на 10%.
  • Под другим пользователем цена останется без изменений.

Для дополнительной проверки можно временно вставить error_log() внутри функции и смотреть логи сервера, например:

error_log('Original price: ' . $original_price . ', Discounted price: ' . $discounted_price);

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

  • Изменение цены не отображается: Возможно, вы меняете цену не у объекта $product, а у массива. Используйте $product->set_price().
  • Цена меняется глобально для всех пользователей: Проверьте условие по роли пользователя. Возможно, роль не передается корректно.
  • Код ломает админку: Добавьте проверку is_admin() && !defined('DOING_AJAX') и пропускайте выполнение в админке.
  • Кэширование мешает обновлению цены: Очистите кэш плагинов или серверный кэш.

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

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

Дополнительно: сравнение вариантов реализации

ВариантПримерПлюсыМинусы
Изменение цены через woocommerce_before_calculate_totalsКод вышеГибко, без изменения базы, работает для корзиныНе меняет цену в каталоге, только в корзине
Использование фильтра woocommerce_get_price
add_filter('woocommerce_get_price', 'custom_price_filter', 10, 2);
function custom_price_filter($price, $product) {
    // условия и возврат новой цены
}
Меняет цену везде, включая каталогМожет конфликтовать с другими плагинами и кешем
Изменение цены напрямую в базеSQL-запросы к таблице wp_postmetaПостоянное изменение ценыРиск ошибок, нужно откатить изменения вручную
Как удалить неиспользуемые метаданные в WordPress для оптимизации базы данных
29.12.2025
Как добавить динамические табуляторы в WordPress без плагинов
10.04.2026
Как создать автоматический отчет о проблемах WordPress
28.01.2026
Как удалить заблокированные товары из WooCommerce
26.04.2026
Как создать настройки для плагина WordPress: подробное руководство
29.11.2025