Проблема: Как задать скидку в WooCommerce в зависимости от размера товара
В стандартном WooCommerce нет возможности автоматически менять скидку на товар в зависимости от его размера, например, длины или объема. Это часто требуется в магазинах одежды, стройматериалов или товаров с вариациями, где цена должна меняться в зависимости от физического параметра.
Диагностика проблемы
Если у вас есть вариации товаров с разными размерами, и вы хотите применять разные скидки автоматом (без ручного редактирования каждого варианта), стандартных настроек недостаточно. Часто владельцы магазинов пытаются использовать обычные скидки или купоны, но это не гибко.
Чтобы проверить, что скидка не применяется автоматически, нужно:
- Перейти в карточку вариации товара и проверить цену и цену со скидкой.
- Добавить товар в корзину с разными размерами и посмотреть итоговую стоимость.
- Проверить, есть ли кастомные функции или плагины, влияющие на цену.
Пошаговое решение: автоматическая скидка через хук WooCommerce
Для реализации автоматического изменения скидки в зависимости от размера вариации используем хук woocommerce_before_calculate_totals. В этом хуке можно изменить цену товара в корзине динамически.
Пример функции, которая добавляет скидку 10% для вариаций с размером больше 50 (например, длина в метрах хранится в атрибуте 'pa_size'):
add_action('woocommerce_before_calculate_totals', 'custom_discount_based_on_size', 10, 1);function custom_discount_based_on_size( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) { $product = $cart_item['data']; $variation_id = $cart_item['variation_id']; if ( ! $variation_id ) continue; // Получаем атрибут размера вариации $size = $product->get_attribute('pa_size'); if ( ! $size ) continue; // Преобразуем размер в число $size_value = floatval( $size ); if ( $size_value > 50 ) { $regular_price = floatval( $product->get_regular_price() ); $discounted_price = $regular_price * 0.9; // 10% скидка $product->set_price( $discounted_price ); } }}Этот код устанавливает цену в корзине с 10% скидкой, если размер товара больше 50. Вы можете адаптировать условие и размер атрибута под ваш случай.
Добавление поддержки разных диапазонов скидок
Для более гибкого управления скидками можно добавить проверку диапазонов:
if ($size_value > 100) { $discount = 0.8; // 20% скидка} elseif ($size_value > 50) { $discount = 0.9; // 10% скидка} else { $discount = 1; // без скидки}$discounted_price = $regular_price * $discount;Проверка результата после внедрения
- Добавьте в корзину товар-варинат с размером меньше 50 — цена должна быть без скидки.
- Добавьте в корзину товар с размером больше 50 — цена должна уменьшиться на 10%.
- Обновите страницу корзины и убедитесь, что отображается правильная цена и сумма.
- Проверьте оформление заказа и итоговые данные в админке WooCommerce.
Частые ошибки и как их исправить
- Скидка не применяется: Проверьте, что название атрибута размера указано правильно, как в WooCommerce (обычно с префиксом
pa_). - Цена сбрасывается после обновления страницы: Убедитесь, что функция подключена через хук
woocommerce_before_calculate_totalsс приоритетом 10, а также что в админке не отключена возможность изменения цены в корзине. - Конфликты с другими плагинами изменения цен: Отключите временно другие плагины, изменяющие цены, чтобы проверить совместимость.
- Атрибут размера возвращается пустым: Проверьте, что у вариаций действительно есть этот атрибут и он заполнен в формате числа.
Практические советы по производительности и безопасности
- Код лучше размещать в дочерней теме или в плагине для кастомизаций, чтобы не потерять изменения при обновлении.
- Избегайте тяжелых операций в хуках изменения цены — они вызываются часто и влияют на скорость оформления заказа.
- Перед изменением цены убедитесь, что пользователь не админ (как показано в условии), чтобы не мешать работе административного интерфейса.
- Для сложных правил скидок рассмотрите использование специализированных плагинов, например, WooCommerce Dynamic Pricing — но если нужна простая логика, лучше кастомный код.
Сравнение вариантов реализации
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Кастомный код через woocommerce_before_calculate_totals | Изменение цены в корзине динамически | Гибко, бесплатно, легко адаптировать | Требует навыков, возможны конфликты с другими плагинами |
| Плагин WooCommerce Dynamic Pricing | Готовое решение для сложных правил скидок | Удобство, поддержка, расширенный функционал | Платный, может быть избыточным для простых задач |
| Использование купонов с ограничениями | Ручное применение скидок по условиям | Просто, без кода | Не автоматично, неудобно при большом количестве вариаций |