WooCommerce: автоматическое изменение стоимости товара при изменении количества в корзине

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

По умолчанию WooCommerce рассчитывает стоимость товара в корзине как произведение цены за единицу на количество. Однако в реальных магазинах часто требуется более сложная логика: скидка при покупке нескольких штук, динамическое изменение цены с учетом количества, акционные условия или особые наценки. При этом стандартные методы через промокоды или фиксированные скидки не всегда удобны и гибки.

В этой статье разберем, как программно реализовать изменение стоимости товара в корзине в зависимости от количества, используя хуки WooCommerce, без сторонних плагинов.

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

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

  • Цена товара не изменяется на этапе расчета корзины. Нужно использовать правильный хук, который срабатывает перед подсчетом итогов.
  • Изменения цены не учитываются из-за кеширования корзины или сеанса. Необходимо обновить данные корзины после изменения.
  • Используются неправильные методы для изменения цены. Например, нельзя просто менять $cart_item['data']->price вне нужного хука.

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

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

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

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

    // Проходим по всем товарам корзины
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $quantity = $cart_item['quantity'];
        $product = $cart_item['data'];
        $original_price = $product->get_regular_price();

        // Например, делаем скидку 5% за каждую штуку свыше 3
        if ($quantity > 3) {
            $discount = 0.05 * ($quantity - 3);
            $discount = min($discount, 0.3); // максимум скидка 30%
            $new_price = $original_price * (1 - $discount);

            // Устанавливаем новую цену
            $product->set_price( $new_price );
        } else {
            // Восстанавливаем оригинальную цену, если условий нет
            $product->set_price( $original_price );
        }
    }
}

Шаг 2. Очистка кеша и обновление корзины

Если в вашем магазине активны кеширующие плагины, убедитесь, что AJAX-обновление корзины работает корректно. При необходимости добавьте wc()->cart->calculate_totals(); после изменения цены, но в данном случае WooCommerce сам пересчитывает итоги.

Шаг 3. Тестирование на фронтенде

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

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

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

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

  • Цена не меняется: возможно, вы меняете цену вне хука или не на объекте WC_Product. Используйте woocommerce_before_calculate_totals и метод set_price().
  • Цена сбрасывается при обновлении страницы: убедитесь, что не сохраняете цену напрямую в базе, а изменяете только в сессии корзины.
  • Двойной пересчет цены и некорректные итоги: избегайте вызова calculate_totals() внутри самого хука, чтобы не вызвать рекурсивный вызов.
  • Проблемы с кешированием AJAX: проверьте, что AJAX-запросы корзины не кешируются сервером или плагинами.

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

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

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

МетодОписаниеПлюсыМинусы
Хук woocommerce_before_calculate_totalsИзменение цены в объекте WC_Product в корзинеГибкость, нативный механизм WooCommerceНужно аккуратно работать, чтобы не создавать рекурсию
Плагины скидок и промокодовИспользование готовых решений для скидокПростота установки, готовый интерфейсМеньшая гибкость, зависит от функционала плагина
JS-скрипты на фронтендеИзменение отображаемой цены через JavaScriptБыстрая реализацияЦена изменяется только визуально, не влияет на итоговые расчеты
Оптимизация загрузки шаблонов в WordPress для ускорения сайта
15.12.2025
WooCommerce: решение проблемы нерабочей функции динамического изменения цены товара при промокодах
31.05.2026
Как использовать метаданные в WordPress для улучшения поисковой оптимизации
21.12.2025
Как использовать хуки в WordPress: практическое руководство
10.11.2025
WooCommerce: автоматическое изменение стоимости товара при добавлении в корзину по условиям
20.05.2026