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

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

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

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

Шаги решения: автоматическое изменение цены товара через хуки WooCommerce

1. Выбор хука для изменения цены

Для динамической корректировки цены в WooCommerce оптимально использовать фильтр woocommerce_product_get_price и woocommerce_product_get_regular_price. Они позволяют перехватить вызов цены товара и заменить ее на свое значение без изменения самой записи в базе данных.

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

Ниже простой пример, который снижает цену товара на 5% при достижении в мета-поле пользователя суммы покупок свыше 10000 рублей. В реальном проекте расчет суммы покупок можно заменить на более сложную логику.

add_filter('woocommerce_product_get_price', 'apply_cumulative_discount_to_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'apply_cumulative_discount_to_price', 10, 2);

function apply_cumulative_discount_to_price($price, $product) {
    // Получаем ID текущего пользователя
    $user_id = get_current_user_id();
    if (!$user_id) {
        return $price; // если гость, цена без изменений
    }

    // Получаем сумму покупок из пользовательского мета (пример)
    $total_spent = (float) get_user_meta($user_id, '_total_spent', true);
    if ($total_spent >= 10000) {
        // Применяем скидку 5%
        $price = $price * 0.95;
    }
    return round($price, 2);
}

3. Автоматическое обновление мета-поля с суммой покупок

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

add_action('woocommerce_order_status_completed', 'update_user_total_spent');
function update_user_total_spent($order_id) {
    $order = wc_get_order($order_id);
    $user_id = $order->get_user_id();
    if (!$user_id) {
        return;
    }
    $total_spent = (float) get_user_meta($user_id, '_total_spent', true);
    $order_total = (float) $order->get_total();
    $new_total = $total_spent + $order_total;
    update_user_meta($user_id, '_total_spent', $new_total);
}

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

  • Залогиньтесь под пользователем с общей суммой покупок больше 10000 (или вручную установите мета _total_spent через phpMyAdmin или WP-CLI).
  • Перейдите на страницу товара и убедитесь, что цена уменьшена на 5%.
  • Оформите новый заказ и после подтверждения статуса «Завершён» проверьте увеличение мета-поля _total_spent и корректное обновление цены при следующем посещении.

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

  • Цена не меняется: убедитесь, что используете правильные хуки woocommerce_product_get_price и woocommerce_product_get_regular_price, а не другие фильтры.
  • Скидка не применяется для гостей: это нормальное поведение, т.к. нет user ID. Для гостей можно добавить отдельную логику, если необходимо.
  • Цена сбрасывается на старую при кешировании: отключите кеширование страниц для пользователей с накопительными скидками (например, через настройки плагина кеша или с помощью DONOTCACHEPAGE).
  • Некорректная сумма покупок: проверьте логику обновления _total_spent, чтобы учитывать только завершённые заказы и избегать дублирования.

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

  • Поддерживайте логику обновления мета-поля только на статусе completed, чтобы не суммировать отменённые и возвратные заказы.
  • Используйте round() для округления цен, чтобы избежать дробных значений с длинной десятичной частью.
  • Кешируйте результат подсчета суммы покупок, если вычисления усложняются, например, через транзиенты.
  • Проверяйте совместимость с плагинами кеширования, отключая кеш для динамических страниц с ценами.
  • Не храните чувствительную информацию в пользовательских мета без шифрования — в данном случае это безопасно, так как это только сумма.

Сравнение подходов: плагин vs. кастомный код

КритерийПлагин накопительных скидокКастомный код (описанный выше)
ГибкостьОграничена функционалом плагинаПолный контроль, можно адаптировать под любые правила
ПроизводительностьМожет замедлять сайт из-за лишних запросовМинимальное влияние при оптимизации
ОбновляемостьОбновляется автоматически, но может конфликтоватьТребует поддержки разработчиком
СтоимостьЧасто платныеБесплатно, если реализовать самостоятельно
Сложность внедренияПростая установкаТребуется знания PHP и WooCommerce API
WooCommerce: как исправить проблему с не обновляющейся ценой вариаций товаров
20.06.2026
WooCommerce: автоматическое отслеживание и удаление товаров без наличия на складе
17.06.2026
Как удалить пустые термины и таксономии в WordPress: практическое руководство
03.04.2026
Как создать динамические блоки с ключевыми словами в WordPress
26.01.2026
Как сделать динамические варианты в выборах форм в WordPress
17.04.2026