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

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

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

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

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

1. Используем хук 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 ) {
        $product = $cart_item['data'];
        $quantity = $cart_item['quantity'];

        // Пример условия: если куплено 5 и более товаров, цена уменьшается на 10%
        if ( $quantity >= 5 ) {
            $original_price = $product->get_regular_price();
            $new_price = $original_price * 0.9; // скидка 10%
            $product->set_price( $new_price );
        } else {
            // Важно вернуть цену к оригиналу, если условие не выполняется
            $product->set_price( $product->get_regular_price() );
        }
    }
}

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

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

    if ( ! is_user_logged_in() ) return;

    $user = wp_get_current_user();
    $roles = (array) $user->roles;

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

        if ( in_array( 'wholesale_customer', $roles ) ) {
            // Оптовая цена 20% ниже
            $new_price = $product->get_regular_price() * 0.8;
            $product->set_price( $new_price );
        } else {
            $product->set_price( $product->get_regular_price() );
        }
    }
}

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

  • Добавьте в корзину нужное количество товара и проверьте, изменяется ли цена в соответствии с условием.
  • Если меняете цену по роли — войдите под соответствующим пользователем и повторите добавление товара в корзину.
  • Проверьте итоговую сумму заказа на странице оформления заказа и в админке WooCommerce.
  • Для отладки можно добавить error_log или var_dump, чтобы убедиться, что условие срабатывает.

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

  • Цена не меняется: убедитесь, что хук подключён правильно и приоритет 20 установлен (раньше может не сработать). Проверьте, что код не выполняется в админке.
  • Цена сбрасывается в конце: важно всегда возвращать цену к оригинальной, если условие не выполняется, иначе цена может остаться изменённой для следующих товаров.
  • Конфликты с кешированием: кэш страниц или объектов может показывать старые цены — очистите кэш и отключите кеширование для теста.
  • Изменение цены не сохраняется при AJAX обновлении корзины: убедитесь, что хук поддерживает AJAX, и код не блокирует ajax-запросы.
  • Изменения цены влияют на отпечатки корзины (session hash): если используете сторонние плагины кеширования, проверьте совместимость.

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

  • Не используйте глобальные переменные и минимизируйте обращение к базе данных внутри хука.
  • Проверяйте роль пользователя и количество товаров один раз за вызов, а не для каждого товара.
  • Используйте is_admin() && ! defined( 'DOING_AJAX' ) для предотвращения избыточного выполнения в админке.
  • Для сложных условий лучше использовать transient или кеширование, чтобы не нагружать сервер при каждом обновлении корзины.

Таблица сравнения вариантов реализации изменения цены в WooCommerce

СпособПлюсыМинусыПример использования
Код через woocommerce_before_calculate_totalsГибкий, без плагинов, контролируемыйТребует навыков программирования, возможны ошибкиИзменение цены по количеству или роли
Плагины скидок и динамического ценообразованияУдобно, много функций, интерфейсМожет нагружать сайт, конфликтовать, платныеWooCommerce Dynamic Pricing, Discount Rules
Создание отдельного товара с нужной ценойПросто, без кодаМного товаров, неудобно управлятьДля статических скидок
Как удалить или изменить заголовок страницы в WordPress
30.11.2025
Как использовать WPCommunity для создания форума в WordPress
01.02.2026
Как использовать хук WooCommerce before_add_to_cart для дополнительной проверки товара
09.07.2026
Исключение определённых товаров из поиска WooCommerce: практическое руководство
17.06.2026
Как автоматически удалять старые посты в WordPress
15.04.2026