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

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

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

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

Как изменить цену товара в корзине через хук woocommerce_before_calculate_totals

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

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

    // Проверка, чтобы не менять цену несколько раз
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) {
        return;
    }

    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // Пример: изменить цену для товара с ID 123
        if ( $cart_item['product_id'] == 123 ) {
            // Задаём новую цену
            $new_price = 500; // новая цена в валюте магазина
            $cart_item['data']->set_price( $new_price );
        }

        // Можно добавить другие условия
        // Например, если количество товара > 3, даём скидку 10%
        if ( $cart_item['quantity'] > 3 ) {
            $original_price = $cart_item['data']->get_regular_price();
            $discounted_price = $original_price * 0.9;
            $cart_item['data']->set_price( $discounted_price );
        }
    }
}

Объяснение кода

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

Пошаговое решение для изменения цены по роли пользователя

Допустим, нужно сделать скидку 15% для пользователей с ролью "оптовик".

add_action('woocommerce_before_calculate_totals', 'discount_for_wholesale_users', 20, 1);
function discount_for_wholesale_users( $cart ) {
    if ( is_admin() && ! defined('DOING_AJAX') ) {
        return;
    }
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) {
        return;
    }

    // Проверяем роль пользователя
    if ( current_user_can('wholesale') ) {
        foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
            $original_price = $cart_item['data']->get_regular_price();
            $discount_price = $original_price * 0.85; // скидка 15%
            $cart_item['data']->set_price( $discount_price );
        }
    }
}

Как проверить, что цена изменилась правильно

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

Частые ошибки при изменении цены в корзине и как их избежать

  • Двойное применение скидок: если не ограничить вызов функции, цена будет меняться несколько раз. Используйте проверку did_action().
  • Изменение цены в админке: влияет на отображение заказа и может привести к конфликтам, проверяйте is_admin().
  • Изменение цены товара, а не вариации: при работе с вариациями используйте $cart_item['variation_id'] или проверяйте объект WC_Product.
  • Не обновляется итоговая сумма: всегда меняйте цену через метод set_price() объекта товара, а не напрямую в массиве.

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

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

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

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

Добавь в закладки и поделись с друзьями:

⭐⭐⭐⭐⭐
WooCommerce: как исправить проблему с возвратом денег при отключённой AJAX-обработке
07.05.2026
Как создать свой шорткод в WordPress: подробное руководство с примерами
10.11.2025
Как создать динамический виджет в WordPress с примерами кода
19.12.2025
Как избежать проблем с базой данных при масштабных обновлениях WordPress
08.01.2026
Как отключить автообновления тем и плагинов WordPress через функции
25.02.2026
×
Оптимизируй свой сайт!

Скидка -15% на премиум плагин Clearfy Pro

Купить плагин сейчас ⋙