Диагностика задачи: зачем нужна автоматическая корректировка цены при накопительных скидках
В интернет-магазинах на WooCommerce часто возникает потребность внедрить накопительные скидки — когда цена товара снижается в зависимости от общей суммы или количества покупок клиента. Стандартный WooCommerce не поддерживает подобное поведение из коробки. Чтобы избежать путаницы и упростить управление скидками, стоит автоматизировать изменение стоимости товаров при оформлении заказа или на странице товара.
Основные способы реализации накопительных скидок в WooCommerce
1. Использование плагинов
Существуют готовые решения, например WooCommerce Advanced Discounts или Clearfy Pro с возможностью настраивать накопительные скидки без кода. Однако, они часто добавляют нагрузку и не всегда гибко интегрируются с уникальными сценариями.
2. Кастомный код с использованием хуков WooCommerce
Более гибкий вариант — написать собственный код, который будет изменять цену товара в зависимости от истории покупок пользователя или текущей корзины.
Пошаговое решение с примером кода
Шаг 1. Определение накопленной суммы покупок пользователя
Чтобы вычислить накопительную скидку, нужно получить общую сумму прошлых заказов клиента. Для этого используем функцию:
function get_user_total_spent( $user_id ) {
if ( ! $user_id ) return 0;
$total = wc_get_customer_total_spent( $user_id );
return $total ? $total : 0;
}Шаг 2. Создание функции для расчёта скидки
Допустим, мы хотим дать 5% скидку при накопленных покупках от 10000 рублей, 10% — от 20000 и 15% — от 50000.
function get_cumulative_discount_percentage( $total_spent ) {
if ( $total_spent >= 50000 ) {
return 15;
} elseif ( $total_spent >= 20000 ) {
return 10;
} elseif ( $total_spent >= 10000 ) {
return 5;
}
return 0;
}Шаг 3. Изменение цены товара в корзине
Используем хук woocommerce_before_calculate_totals, чтобы применить скидку к каждому товару в корзине:
add_action( 'woocommerce_before_calculate_totals', 'apply_cumulative_discount_to_cart' );
function apply_cumulative_discount_to_cart( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if ( ! is_user_logged_in() ) return;
$user_id = get_current_user_id();
$total_spent = get_user_total_spent( $user_id );
$discount_percent = get_cumulative_discount_percentage( $total_spent );
if ( $discount_percent > 0 ) {
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$original_price = $cart_item['data']->get_regular_price();
$discounted_price = $original_price * ( 1 - $discount_percent / 100 );
$cart_item['data']->set_price( $discounted_price );
}
}
}Шаг 4. Отображение накопительной скидки на странице товара
Чтобы пользователь видел скидку заранее, добавим динамическое изменение цены на странице товара:
add_filter( 'woocommerce_get_price_html', 'show_cumulative_discount_on_product_page', 10, 2 );
function show_cumulative_discount_on_product_page( $price_html, $product ) {
if ( ! is_user_logged_in() ) return $price_html;
$user_id = get_current_user_id();
$total_spent = get_user_total_spent( $user_id );
$discount_percent = get_cumulative_discount_percentage( $total_spent );
if ( $discount_percent > 0 ) {
$regular_price = $product->get_regular_price();
$discounted_price = wc_price( $regular_price * ( 1 - $discount_percent / 100 ) );
$price_html = '<del>' . wc_price( $regular_price ) . '</del> <ins>' . $discounted_price . '</ins>';
}
return $price_html;
}Проверка результата после внедрения
- Войдите под пользователем с накопленной суммой заказов более 10000 руб.
- Откройте страницу товара — должна отображаться цена с накопительной скидкой.
- Добавьте товар в корзину — цена должна автоматически измениться с учётом скидки.
- Оформите заказ и проверьте, что итоговая сумма корректна с учетом скидки.
Частые ошибки и как их исправить
- Скидка не применяется в корзине: Проверьте, что в функции
apply_cumulative_discount_to_cartнет ошибок и что хук подключён правильно. Убедитесь, что цена меняется именно черезset_price, а не напрямую с мета-данными. - Скидка не отображается на странице товара: Убедитесь, что фильтр
woocommerce_get_price_htmlне конфликтует с другими плагинами или темой. Проверьте, что пользователь авторизован. - Скидка считается неверно: Проверьте логику функции
get_cumulative_discount_percentageи правильность подсчёта total_spent. - Проблемы с производительностью: Если в магазине много заказов, кешируйте сумму покупок пользователя, чтобы не делать множество запросов к базе.
Практические советы по безопасности и производительности
- Не меняйте цену товара напрямую в базе — используйте стандартные методы WooCommerce (например,
set_price), чтобы избежать конфликтов. - Кешируйте результаты вычисления суммы покупок пользователя через Transients API с разумным временем жизни (например, 1 час), чтобы снизить нагрузку на базу.
- Проверяйте, что пользователь авторизован перед применением скидок — для гостей логика должна работать по-другому или отсутствовать.
- Для более сложных накопительных схем рассмотрите использование WPShop Clearfy Pro для оптимизации и расширенных настроек скидок.
Сравнение вариантов реализации накопительных скидок
| Метод | Плюсы | Минусы | Пример |
|---|---|---|---|
| Плагин | Быстрый старт, готовый функционал, поддержка | Нагрузка, ограниченная кастомизация, возможные конфликты | WooCommerce Advanced Discounts |
| Кастомный код | Максимальная гибкость, лёгкость поддержки, минимальный вес | Требует навыков, больше времени на разработку | Хуки и фильтры WooCommerce, пример выше |