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

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

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

Проверить, что происходит именно эта проблема, можно так:

  • Примените промокод в корзине;
  • Обратите внимание на цену товара в списке — она не меняется;
  • Общая сумма корзины корректно пересчитывается со скидкой;
  • Цена в виджетах товара и на страницах товаров остаётся без скидки.

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

1. Используем хук woocommerce_before_calculate_totals

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

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

    // Проверяем, что корзина существует
    if ( ! $cart || empty( $cart->get_cart() ) ) {
        return;
    }

    // Проверяем наличие конкретного промокода
    $target_coupon = 'specialdiscount'; // замените на ваш промокод
    $applied_coupons = $cart->get_applied_coupons();
    if ( ! in_array( $target_coupon, $applied_coupons ) ) {
        return;
    }

    // Цикл по товарам в корзине
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // Пример: для товара с ID 123 меняем цену
        if ( $cart_item['product_id'] == 123 ) {
            $original_price = $cart_item['data']->get_price();
            $new_price = $original_price * 0.8; // скидка 20%
            $cart_item['data']->set_price( $new_price );
        }
    }
}

2. Добавляем проверку на AJAX и админку

Чтобы избежать нежелательных изменений цены в админке и при других запросах, мы добавили проверку is_admin() && ! defined( 'DOING_AJAX' ). Это стандартная практика для таких хуков.

3. Подключаем код в файл functions.php вашей темы или в кастомный плагин

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

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

  1. Очистите кеш браузера и кеш сайта, если он используется.
  2. Добавьте в корзину товар с ID, указанным в коде (в примере 123).
  3. Примените промокод specialdiscount.
  4. Проверьте, что цена товара в корзине изменилась на 20% ниже исходной.
  5. Переходите на страницу оформления заказа и убедитесь, что итоговая сумма корректна.

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

  • Промокод не применяется к цене товара: Проверьте, правильно ли указано имя промокода в переменной $target_coupon и совпадает ли регистр.
  • Цена меняется для всех товаров: Убедитесь, что условие $cart_item['product_id'] == 123 ограничивает применение скидки только к нужному товару.
  • Цена не обновляется при AJAX обновлении корзины: Проверьте, что хук woocommerce_before_calculate_totals подключен с приоритетом 20 или выше, и нет конфликтов с другими плагинами.
  • Цена меняется в админке: Добавьте проверку is_admin() && ! defined('DOING_AJAX') для исключения админ-запросов.

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

  • Не меняйте цену товара глобально — только в корзине, чтобы не влиять на данные в базе и не создавать рассинхронизацию.
  • Используйте кеширование с осторожностью: динамическая цена зависит от промокода, поэтому кеш страниц с корзиной должен быть отключен или использоваться с вариациями для разных пользователей.
  • Проверяйте совместимость с другими плагинами, которые могут влиять на цену, например, плагины скидок или кэширования.
  • Для сложных условий лучше использовать кастомные поля или метаданные продуктов, чтобы не хардкодить ID в коде.

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

МетодПреимуществаНедостаткиПример
Хук woocommerce_before_calculate_totalsГибкий, без плагинов, точечное изменение цены в корзинеТребует навыков PHP, влияет только на корзинуПример из статьи
Плагины скидок (например, WooCommerce Dynamic Pricing)Удобный интерфейс, управление скидками без кодаМожет влиять на производительность, лицензииClearfy Pro позволяет оптимизировать сайт, но не меняет цены напрямую
JS-решения на клиентеБыстрая визуальная корректировка ценыЦена не меняется на сервере, риск рассинхронизацииНе рекомендуется для финальных расчетов
Оптимизация загрузки изображений в WordPress для ускорения сайта
06.02.2026
WooCommerce: как автоматически удалять заказы со статусом Отменен и Возврат
18.06.2026
Как установить ограничения на регистрацию в WordPress по домену и email
17.03.2026
WooCommerce: решение проблемы неактивных вариантов товаров
08.06.2026
Как использовать хуки в WordPress: практическое руководство
10.11.2025