Диагностика задачи: зачем нужны накопительные скидки и их автоматизация
В интернет-магазинах на 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 );
}
}Проверка результата после внедрения
- Авторизуйтесь как пользователь с разной суммой предыдущих заказов (например, меньше 10000, между 10000 и 30000, больше 30000 рублей).
- Добавьте товары в корзину и перейдите в корзину или на страницу оформления заказа.
- Проверьте, что цены товаров изменились согласно заданным процентам скидки (0%, 5% или 10%).
- Для тестирования можно временно вывести сумму накопленных заказов и процент скидки, добавив
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 интеграции |