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

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

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

Основные признаки задачи:

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

Пошаговое решение: как программно изменить стоимость товаров в корзине

1. Хук для изменения цены товаров в корзине

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

2. Пример кода для изменения цены по количеству

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

    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $quantity = $cart_item['quantity'];
        $original_price = $cart_item['data']->get_regular_price();

        // Пример: скидка 10% при покупке 3 и более
        if ( $quantity >= 3 ) {
            $new_price = $original_price * 0.9;
            $cart_item['data']->set_price( $new_price );
        } else {
            // Восстановление оригинальной цены
            $cart_item['data']->set_price( $original_price );
        }
    }
}

3. Изменение цены при наличии определенного товара в корзине

Иногда нужно менять цены других товаров, если в корзине есть товар с конкретенным ID:

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

    $target_product_id = 123; // ID товара, наличие которого влияет на скидки
    $has_target = false;

    // Проверяем наличие товара
    foreach ( $cart->get_cart() as $item ) {
        if ( $item['product_id'] == $target_product_id ) {
            $has_target = true;
            break;
        }
    }

    // Если есть товар, меняем цену на 80% для всех остальных
    if ( $has_target ) {
        foreach ( $cart->get_cart() as $cart_item ) {
            if ( $cart_item['product_id'] != $target_product_id ) {
                $original_price = $cart_item['data']->get_regular_price();
                $cart_item['data']->set_price( $original_price * 0.8 );
            }
        }
    } else {
        // Восстановление оригинальных цен
        foreach ( $cart->get_cart() as $cart_item ) {
            $cart_item['data']->set_price( $cart_item['data']->get_regular_price() );
        }
    }
}

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

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

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

  • Цена меняется бесконечно, происходит зацикливание. Решение: важно менять цену только один раз. Добавьте проверку, например, храните флаг в объекте корзины или сравнивайте текущую цену с оригиналом.
  • Цены не меняются, хотя код добавлен. Проверьте приоритет хука и отсутствие конфликтов с другими плагинами, отключите кэширование на время теста.
  • В итогах заказа отображается неверная цена. Возможна проблема с кэшированием или с подсчетом налогов, проверьте настройки WooCommerce и отключите кэширование страниц корзины и оформления заказа.
  • Изменение цены сохраняется в базе и ломает основной товар. Никогда не используйте update_post_meta для цены, меняйте цену только через объект $cart_item['data']->set_price().

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

  • Не используйте тяжелые запросы к базе внутри функции изменения цены — это может замедлить страницу корзины.
  • При необходимости сложных условий кешируйте результаты вычислений в сессии или transient.
  • Используйте is_admin() и проверку DOING_AJAX, чтобы код срабатывал только на фронтенде корзины.
  • Тестируйте на staging-сайте с разными версиями WooCommerce и тем, чтобы избежать конфликтов.
  • Для более сложных правил рассмотрите плагины типа WooCommerce Dynamic Pricing или Advanced Coupons, если поддержка собственного кода затруднительна.

Сравнение вариантов реализации

МетодОписаниеПлюсыМинусы
Код на woocommerce_before_calculate_totalsИзменение цены программно через хукГибкость, без сторонних плагинов, полное управлениеТребуются навыки программирования, возможны ошибки
Плагин Dynamic PricingГотовые правила скидок и изменений ценыПростота настройки, поддержка, шаблоны скидокСтоимость, ограниченная гибкость, нагрузка
Купоны WooCommerceСтандартные скидки и акцииПростота, встроеноМаленькая гибкость, не подходит для сложных правил

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

Как автоматически удалять старые медиафайлы в WordPress
09.02.2026
Автоматическое отключение AJAX-запросов в WordPress для оптимизации и ускорения сайта
20.02.2026
Автоматическое отключение Pingback и Trackback в WordPress: практическое руководство
11.04.2026
Как создать автоматический экспорт пользовательских данных в WordPress
06.04.2026
Как создать автоматический импорт продуктов в WooCommerce
15.04.2026