Диагностика проблемы: почему стандартные купоны не всегда подходят под бизнес-логику
В WooCommerce купоны по умолчанию позволяют задавать скидки фиксированной суммой или в процентах, но часто возникает задача изменить цену конкретного товара программно при применении купона. Например, при вводе специального купона цена товара должна автоматически снижаться до определённого значения или изменяться с учётом сложной логики, которую стандартный функционал не поддерживает.
Проверить, что стандартный купон не решает задачу, можно так:
- Создайте купон в WooCommerce с фиксированной скидкой.
- Примените купон на страницу корзины.
- Посмотрите, меняется ли цена товара, а не только итоговая сумма.
Если цена товара не меняется (а меняется только итог корзины), то стандартного функционала недостаточно.
Пошаговое решение: программное изменение цены товара при применении купона
1. Использование хука woocommerce_before_calculate_totals
Для того чтобы изменить цену товара в корзине при применении определённого купона, нужно обработать событие до подсчёта итогов корзины. Это позволяет динамически менять цену товаров.
add_action('woocommerce_before_calculate_totals', 'custom_change_price_on_coupon', 10, 1);
function custom_change_price_on_coupon($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
if (did_action('woocommerce_before_calculate_totals') >= 2) return;
// Проверяем, применён ли купон с кодом 'special10'
$coupon_code = 'special10';
$applied_coupons = WC()->cart->get_applied_coupons();
if (!in_array($coupon_code, $applied_coupons)) return;
// Проходим по всем товарам в корзине
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
// Проверяем ID товара, который хотим изменить
if ($cart_item['product_id'] == 123) { // замените 123 на нужный ID
// Устанавливаем новую цену
$new_price = 500; // новая цена в валюте магазина
$cart_item['data']->set_price($new_price);
}
}
}2. Проверка применённого купона
В примере выше проверяется, что купон special10 применён. Можно расширять логику, проверяя несколько купонов или условия.
Проверка результата после внедрения
- Очистите кэш сайта и браузера, если используете кэширование.
- Добавьте в корзину товар с ID, указанным в коде (например, 123).
- Примените купон
special10. - Проверьте, что цена товара изменилась на новую (в примере 500).
- Попробуйте удалить купон — цена должна вернуться к исходной.
Частые ошибки и как их исправить
- Цена не меняется после применения купона: проверьте, что ID товара указан верно, и что купон действительно применяется (вывести
print_r(WC()->cart->get_applied_coupons())для отладки). - Изменения цены не отображаются в админке или на странице оформления заказа: убедитесь, что код добавлен в файл functions.php активной темы или в плагин, и что хук
woocommerce_before_calculate_totalsне вызывается несколько раз (используйтеdid_actionдля контроля). - Конфликты с другими плагинами скидок: отключите сторонние плагины скидок и проверьте работу кода, затем подключайте по одному для выявления конфликтов.
Практические советы по безопасности и производительности
- Оптимизация хука: избегайте повторного вызова функции с помощью проверки
did_action('woocommerce_before_calculate_totals')<2. - Минимизация нагрузки: проверяйте купоны и ID товара до цикла по корзине, чтобы не делать лишних операций.
- Безопасность кода: не используйте пользовательский ввод напрямую, избегайте SQL-запросов без подготовки.
Таблица сравнения способов изменения цен при применении купонов
| Метод | Плюсы | Минусы | Применение |
|---|---|---|---|
| Стандартные купоны WooCommerce | Простота, нет кода | Ограниченная логика скидок | Простые скидки |
Хук woocommerce_before_calculate_totals с изменением цены | Гибкость, динамика | Требует программирования | Сложные скидки, кастомные правила |
| Плагины сторонних разработчиков | Готовые решения | Возможные конфликты, нагрузка | Быстрая настройка без кода |