В WooCommerce вариативный товар обычно нельзя купить, пока покупатель не выберет нужную вариацию. Это нормальное поведение, но на некоторых проектах оно мешает: например, когда вариации нужны только для отображения характеристик, а продавать нужно один базовый SKU; или когда тема/плагин выводит кнопку «В корзину» раньше времени и пользователь получает ошибку при клике.
Ниже разберём, как именно отключить покупку вариативного товара без выбора вариации, не ломая каталог и не вмешиваясь в ядро WooCommerce. Покажу, как диагностировать причину, какие есть рабочие варианты и как проверить, что всё действительно работает.
Когда это нужно и как выглядит проблема
Типичный сценарий: на странице товара есть вариативный продукт, но покупатель видит кнопку покупки до выбора атрибутов. После клика WooCommerce либо показывает сообщение о необходимости выбрать параметры, либо тема ведёт себя нестабильно — кнопка активна, но форма отправляется с ошибкой. В другом сценарии наоборот: нужно полностью скрыть возможность покупки, пока не выбран размер, цвет, объём или комплектность.
Если задача именно в том, чтобы запретить добавление в корзину без вариации, важно не путать её с отключением самого товара. Товар должен оставаться видимым в каталоге, но действие покупки должно зависеть от выбора вариации.
Диагностика: что именно мешает покупке
Перед правкой кода проверьте, где возникает проблема. В WooCommerce на поведение влияют три слоя: шаблон темы, JavaScript на странице товара и фильтры PHP, которые формируют доступность кнопки «В корзину».
Что проверить в первую очередь
- Товар действительно имеет тип
variable, а не простой товар с атрибутами в описании. - У каждой вариации заполнены цена и статус публикации.
- Атрибуты отмечены как используемые для вариаций.
- Тема не переопределяет шаблон
single-product/add-to-cart/variable.php. - Нет плагина, который меняет поведение кнопки покупки или AJAX-формы.
Если кнопка «В корзину» активна до выбора вариации, это часто не ошибка WooCommerce, а результат кастомного шаблона или скрипта темы. В таком случае править нужно не только PHP-фильтр, но и фронтенд-логику.
Рабочие способы решения
Есть три практических подхода: скрыть кнопку до выбора вариации, запретить добавление в корзину на сервере и заменить стандартную кнопку на свой сценарий. Для большинства магазинов достаточно первого и второго вариантов вместе.
| Подход | Что делает | Плюсы | Минусы |
|---|---|---|---|
| Через шаблон и JS | Прячет кнопку до выбора вариации | Понятно пользователю, не ломает каталог | Нужно следить за темой и обновлениями |
| Через PHP-фильтры | Запрещает добавление без вариации | Надёжно на уровне сервера | Не решает визуальную часть само по себе |
| Через плагин | Меняет поведение без кода | Быстро внедрить | Меньше контроля, возможны конфликты |
Вариант 1: запретить добавление в корзину без выбранной вариации
Если нужно именно защитить серверную логику, используйте фильтр woocommerce_add_to_cart_validation. Он срабатывает до добавления товара в корзину и позволяет остановить действие, если вариация не выбрана.
add_filter( 'woocommerce_add_to_cart_validation', function( $passed, $product_id, $quantity, $variation_id = 0, $variations = array() ) {
$product = wc_get_product( $product_id );
if ( $product && $product->is_type( 'variable' ) ) {
if ( empty( $variation_id ) ) {
wc_add_notice( __( 'Сначала выберите параметры товара.', 'textdomain' ), 'error' );
return false;
}
}
return $passed;
}, 10, 5 );Этот код лучше добавлять в дочернюю тему или в небольшой mu-plugin. Он не зависит от шаблона и продолжит работать даже после обновления темы.
Вариант 2: скрыть кнопку «В корзину» до выбора вариации
Если проблема ещё и в интерфейсе, кнопку можно скрыть на странице вариативного товара и показывать только после выбора атрибутов. В WooCommerce стандартная форма вариаций уже умеет сообщать о выбранной комбинации, поэтому достаточно аккуратно привязаться к её событиям.
add_action( 'wp_enqueue_scripts', function() {
if ( ! function_exists( 'is_product' ) || ! is_product() ) {
return;
}
wp_add_inline_script( 'wc-add-to-cart-variation', "
jQuery(function($){
var form = $('.variations_form');
var button = form.find('.single_add_to_cart_button');
button.prop('disabled', true).addClass('is-hidden-until-variation');
form.on('found_variation', function(){
button.prop('disabled', false).removeClass('is-hidden-until-variation');
});
form.on('reset_data hide_variation', function(){
button.prop('disabled', true).addClass('is-hidden-until-variation');
});
});
" );
} );Если тема не подключает стандартный скрипт wc-add-to-cart-variation, сначала проверьте, не сломан ли шаблон товара. Без этого скрипта события found_variation и reset_data не сработают.
Вариант 3: заменить кнопку на подсказку
Иногда лучше не прятать кнопку, а заменить её на понятную подсказку: «Выберите размер и цвет». Это снижает количество пустых кликов и уменьшает число обращений в поддержку.
add_action( 'woocommerce_single_product_summary', function() {
global $product;
if ( ! $product || ! $product->is_type( 'variable' ) ) {
return;
}
echo '<p class="product-variation-hint">Выберите параметры товара, чтобы добавить его в корзину.</p>';
}, 29 );Число 29 здесь важно: стандартная кнопка WooCommerce выводится примерно на этом приоритете. Если тема меняет порядок блоков, приоритет может потребоваться скорректировать.
Пошаговое внедрение без поломки темы
- Сделайте резервную копию файлов и базы.
- Проверьте, что проблема воспроизводится на стандартной теме WooCommerce.
- Добавьте серверную проверку через
woocommerce_add_to_cart_validation. - Если нужно, добавьте JS-логику для отключения кнопки до выбора вариации.
- Очистите кэш страницы и объектный кэш, если он используется.
- Проверьте товар в обычном окне и в режиме инкогнито.
Если у вас включён плагин кэширования, не забудьте сбросить кэш именно страницы товара. Иначе можно решить, что код не работает, хотя на самом деле браузер показывает старую версию шаблона.
Как проверить, что решение сработало
Проверка должна быть не визуальной, а функциональной. Откройте страницу вариативного товара и попробуйте добавить его в корзину без выбора атрибутов. После внедрения серверной проверки WooCommerce должен показать ошибку и не добавить товар.
- Кнопка покупки неактивна до выбора вариации или заменена подсказкой.
- Без выбранных атрибутов товар не добавляется в корзину.
- После выбора корректной вариации товар добавляется нормально.
- Сообщение об ошибке отображается один раз и не дублируется.
- На мобильной версии форма вариаций работает так же, как на десктопе.
Дополнительно откройте консоль браузера. Если там есть ошибки JavaScript, сначала исправьте их: часто именно они мешают стандартным событиям WooCommerce.
Частые ошибки и как их исправить
Проверяют не тот тип товара
Иногда товар выглядит как вариативный, но на самом деле это простой товар с атрибутами в описании. В таком случае фильтр для вариаций не сработает, потому что WooCommerce не считает такой товар variable product.
Ломают шаблон variable.php
Если тема переопределяет шаблон формы вариаций, стандартные классы и data-атрибуты могут отсутствовать. Тогда JS не видит событие выбора вариации. Решение — сравнить шаблон темы с актуальным шаблоном WooCommerce и убрать лишние изменения.
Отключают кнопку только визуально
Скрыть кнопку через CSS недостаточно. Пользователь или сторонний скрипт всё равно может отправить форму. Поэтому визуальный слой нужно дублировать серверной проверкой.
Не учитывают кэш
Если страница товара кэшируется целиком, после правки может отображаться старая кнопка. Очистите кэш плагина, серверный кэш и CDN, если он есть.
Безопасность и производительность
Такую правку лучше делать без установки тяжёлого плагина, если задача точечная. Один небольшой сниппет в mu-plugin обычно надёжнее, чем ещё один плагин, который добавляет свои скрипты и стили на каждую страницу.
Если вы используете плагин оптимизации вроде Clearfy Pro, проверьте, не отключает ли он нужные скрипты WooCommerce на странице товара. Для вариативных товаров критичен скрипт wc-add-to-cart-variation; без него форма выбора вариаций работает нестабильно.
Ещё один практический момент: не встраивайте логику в functions.php активной темы, если тема часто обновляется или меняется. Для таких задач лучше отдельный мини-плагин или mu-plugin — так проще сопровождать код и не потерять его при обновлении.
Что делать, если нужен другой сценарий
Иногда задача не в запрете покупки, а в том, чтобы автоматически подставлять единственную доступную вариацию или скрывать недоступные комбинации. Это уже другой сценарий: там нужно работать с наличием, ценой и логикой показа атрибутов. Если у вас именно такой кейс, решение будет отличаться от описанного выше.
Для большинства магазинов достаточно двух вещей: серверной проверки и понятного интерфейса. Тогда покупатель не сможет добавить товар без выбора вариации, а вы не получите лишних ошибок в корзине и на checkout.