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

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

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

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

1. Определяем критерии накопительной скидки

Для примера возьмём условие, что скидка растёт в зависимости от общей суммы предыдущих заказов пользователя:

  • До 10000 руб — скидка 0%
  • От 10000 до 30000 руб — скидка 5%
  • От 30000 руб и выше — скидка 10%

2. Создаём функцию для подсчёта общей суммы завершённых заказов пользователя

function get_user_total_spent( $user_id ) {
    if ( ! $user_id ) {
        return 0;
    }
    $customer_orders = wc_get_orders( array(
        'customer_id' => $user_id,
        'status' => array('completed', 'processing'),
        'return' => 'ids',
    ) );

    $total = 0;
    foreach ( $customer_orders as $order_id ) {
        $order = wc_get_order( $order_id );
        $total += $order->get_total();
    }
    return $total;
}

3. Добавляем хук для изменения цены товара в корзине с учётом скидки

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

    $user_id = get_current_user_id();
    if ( ! $user_id ) {
        return;
    }

    $total_spent = get_user_total_spent( $user_id );
    $discount_percentage = 0;

    if ( $total_spent >= 30000 ) {
        $discount_percentage = 10;
    } elseif ( $total_spent >= 10000 ) {
        $discount_percentage = 5;
    }

    if ( $discount_percentage <= 0 ) {
        return;
    }

    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        $original_price = $cart_item['data']->get_regular_price();
        $discounted_price = $original_price * ( 1 - $discount_percentage / 100 );
        $cart_item['data']->set_price( $discounted_price );
    }
}

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

  1. Авторизуйтесь как пользователь с разной суммой предыдущих заказов (например, меньше 10000, между 10000 и 30000, больше 30000 рублей).
  2. Добавьте товары в корзину и перейдите в корзину или на страницу оформления заказа.
  3. Проверьте, что цены товаров изменились согласно заданным процентам скидки (0%, 5% или 10%).
  4. Для тестирования можно временно вывести сумму накопленных заказов и процент скидки, добавив error_log или var_dump в функцию.

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

  • Скидка не применяется: Проверьте, что хук woocommerce_before_calculate_totals зарегистрирован правильно и функция не прерывается при админских запросах.
  • Цена товара становится отрицательной или нулевой: Убедитесь, что цена товара корректно возвращается через get_regular_price(), а не get_price(). Если товар уже в скидке, используйте регулярную цену для расчёта.
  • Скидка применяется к гостям: В коде есть проверка get_current_user_id(), для гостей функция не изменит цену.
  • Скидка не учитывает отменённые или возвратные заказы: В параметре запроса указывайте статусы заказов, которые действительно считаются в накоплении (например, completed, processing).

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

  • Кэшируйте результат суммы потраченных средств пользователя, если сайт с большим трафиком, чтобы не делать много запросов к базе при каждом обновлении корзины.
  • Не изменяйте цены товара глобально, только в корзине, чтобы избежать проблем с отображением на страницах каталога и возможных ошибок в отчётах.
  • Используйте nonce и проверяйте права доступа при добавлении пользовательских функций, если планируете расширять логику через формы или AJAX.

Сравнение подходов реализации накопительных скидок

МетодПлюсыМинусыПример
Плагин (например, WooCommerce Dynamic Pricing)Быстрая настройка, гибкие правилаПлатный, нагрузка на производительностьhttps://woocommerce.com/products/dynamic-pricing/
Код на PHP в functions.phpПолный контроль, бесплатно, лёгкая кастомизацияТребует навыков разработки, сложно для сложных правилПример из статьи
Внешний сервис или CRM интеграцияАвтоматизация, аналитика, масштабируемостьСложность интеграции, дополнительные расходыAPI интеграции
Автоматическое удаление старого метаданных в WordPress
10.04.2026
Как добавить автоподсказки в поиск WordPress
31.03.2026
WooCommerce: как исправить проблему с не обновляющейся ценой вариаций товаров
22.05.2026
Как удалить варианты товаров WooCommerce, которых нет в наличии
05.05.2026
Как автоматически удалять неиспользуемые типы записей в WordPress
23.02.2026