Проблема: купоны WooCommerce применяются ко всем товарам, включая нежелательные
Стандартный функционал WooCommerce не позволяет исключить из действия купонов товары на основе произвольных метаданных (custom fields). Это становится проблемой, когда, например, нужно запретить применение скидок к товарам с определённым статусом, серийным номером или другими мета-полями.
Диагностика проблемы
Чтобы убедиться, что купон применяется ко всем товарам, в том числе и с метаданными, которые должны быть исключены, сделайте следующее:
- Создайте купон в WooCommerce с процентной скидкой (например, 10%).
- Добавьте в корзину товар с нужным метаданным, который должен быть исключён.
- Оформите заказ и проверьте, что скидка применяется к этому товару.
- Если скидка применяется — значит, стандартная логика не учитывает метаданные.
Решение: исключение товаров по метаданным из купонов через фильтр
Для решения задачи нужно модифицировать логику применения купонов с помощью хука woocommerce_coupon_is_valid_for_product. В этом фильтре можно проверять товары на наличие метаданных и запрещать применение купона для таких товаров.
Добавьте следующий код в файл functions.php вашей темы или в плагин для пользовательских функций:
add_filter('woocommerce_coupon_is_valid_for_product', 'exclude_products_by_meta_from_coupon', 10, 4);
function exclude_products_by_meta_from_coupon($valid, $product, $coupon, $values) {
// Ключ метаданных, по которому фильтруем
$meta_key = '_exclude_from_coupon';
// Проверяем есть ли мета и равно ли оно 'yes'
$exclude = get_post_meta($product->get_id(), $meta_key, true);
if ($exclude === 'yes') {
// Запретить применение купона для этого товара
return false;
}
return $valid;
}В этом примере товары с мета-полем _exclude_from_coupon и значением yes не будут участвовать в скидках купонов.
Как добавить метаданные для товаров
Чтобы добавить метаданные:
- Перейдите в админку WooCommerce → Товары → выберите нужный товар.
- В разделе «Дополнительные поля» (Custom Fields) добавьте новое поле с ключом
_exclude_from_couponи значениемyes. - Обновите товар.
Если раздел «Дополнительные поля» не виден, активируйте его в настройках экрана (в верхнем правом углу админки).
Проверка результата
- Очистите кэш сайта и браузера.
- Добавьте в корзину товар с меткой
_exclude_from_coupon = yesи купон, который вы создали. - Убедитесь, что для этого товара скидка не применяется.
- Для товаров без этого мета-поля скидка должна работать как обычно.
Частые ошибки и их решения
- Купон применяется ко всем товарам: проверьте, что мета-поле действительно сохранено у товара и ключ написан правильно.
- Купон не применяется совсем: возможно, фильтр возвращает
falseневерно. Добавьтеerror_logилиvar_dumpвнутри функции для отладки. - Кэш мешает увидеть результат: отключите кэш плагина и браузера при тестах.
- Функция не срабатывает: убедитесь, что код добавлен в
functions.phpактивной темы или подключён плагин с этим кодом.
Практические советы по производительности и безопасности
- Используйте
get_post_metaс третьим параметромtrueдля получения одиночного значения и снижения нагрузки. - Кешируйте результаты проверки метаданных, если корзина содержит много товаров.
- Проверяйте наличие метаполей только для товаров, участвующих в купоне, чтобы избежать лишних вызовов.
- Не меняйте логику купонов глобально — всегда уточняйте, что изменения не повлияют на другие сценарии.
Сравнение вариантов реализации
| Вариант | Описание | Плюсы | Минусы |
|---|---|---|---|
| Использовать плагин для исключения товаров | Специализированные плагины позволяют исключить товары по условиям | Простота использования, готовый интерфейс | Зависимость от стороннего кода, может быть лишний функционал |
Кастомный код с хуком woocommerce_coupon_is_valid_for_product |
Полный контроль, гибкость с метаданными | Легко адаптировать под любые мета-поля, без лишних плагинов | Требует базовых навыков PHP, возможны ошибки при реализации |