Сценарий типичный: товар должен остаться видимым в каталоге, но купить его нельзя. Это бывает у товаров «под заказ», архивных позиций, образцов, витринных карточек или товаров, которые временно сняты с продажи. Удалять карточку неудобно: теряются ссылки, SEO-страница, история и внутренние переходы. Гораздо практичнее отключить покупку точечно, только для нужных товаров.
Когда это нужно и что именно отключать
В WooCommerce есть несколько разных состояний, которые часто путают. Если просто поставить товару статус «нет в наличии», он может продолжать отображаться, но поведение зависит от темы и настроек каталога. Если скрыть товар из каталога, карточка исчезнет полностью. Если сделать товар внешним или виртуальным, это тоже не решает задачу.
Нам нужен другой эффект: карточка открывается, цена может быть видна, но кнопка Добавить в корзину не показывается, а прямое добавление в корзину через URL или форму не срабатывает.
Диагностика проблемы перед правкой
Сначала проверьте, где именно у вас появляется кнопка покупки. В WooCommerce она может быть выведена:
- в шаблоне темы;
- через стандартные хуки WooCommerce;
- в блоках каталога и на странице товара;
- в кэше страницы, если используется плагин кэширования.
Если после изменения кода кнопка не исчезает, обычно причина одна из трёх:
- код добавлен не в тот файл или не активен;
- тема переопределяет шаблон WooCommerce;
- страница отдается из кэша и вы видите старую версию.
Для проверки удобно временно открыть карточку товара в режиме инкогнито и очистить кэш сайта, если он есть.
Пошаговое решение через хук WooCommerce
Самый надёжный вариант — отключать покупку через фильтры WooCommerce для конкретных товаров. Так вы не ломаете шаблоны темы и можете управлять логикой по ID товара, категории или метаполю.
Вариант 1: отключить кнопку для конкретных ID товаров
Добавьте код в functions.php дочерней темы или в собственный мини-плагин:
add_filter( 'woocommerce_is_purchasable', 'wpdir_disable_purchase_for_selected_products', 10, 2 );
function wpdir_disable_purchase_for_selected_products( $purchasable, $product ) {
$disabled_ids = array( 123, 456, 789 );
if ( in_array( $product->get_id(), $disabled_ids, true ) ) {
return false;
}
return $purchasable;
}
add_filter( 'woocommerce_variation_is_purchasable', 'wpdir_disable_purchase_for_selected_variations', 10, 2 );
function wpdir_disable_purchase_for_selected_variations( $purchasable, $variation ) {
$disabled_ids = array( 123, 456, 789 );
if ( in_array( $variation->get_id(), $disabled_ids, true ) ) {
return false;
}
return $purchasable;
}Первый фильтр работает для простых и внешних товаров, второй — для вариаций. Если у вас variable product, без второго фильтра часть вариаций может остаться доступной к покупке.
Вариант 2: отключать покупку по категории
Если у вас есть целая группа товаров, например «Архив» или «Образцы», удобнее завязаться на категорию:
add_filter( 'woocommerce_is_purchasable', 'wpdir_disable_purchase_for_category', 10, 2 );
function wpdir_disable_purchase_for_category( $purchasable, $product ) {
if ( has_term( 'archive', 'product_cat', $product->get_id() ) ) {
return false;
}
return $purchasable;
}Здесь archive — это slug категории товаров. Такой подход проще сопровождать, если список товаров меняется часто.
Вариант 3: скрыть кнопку и блок покупки на странице товара
Иногда фильтра недостаточно, потому что тема всё равно рисует часть интерфейса. Тогда можно убрать стандартные действия с карточки товара:
add_action( 'wp', 'wpdir_remove_add_to_cart_button_for_selected_products' );
function wpdir_remove_add_to_cart_button_for_selected_products() {
if ( ! is_product() ) {
return;
}
global $product;
if ( ! $product ) {
return;
}
$disabled_ids = array( 123, 456, 789 );
if ( in_array( $product->get_id(), $disabled_ids, true ) ) {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}
}Это полезно, если тема добавляет кнопку через стандартный хук. Но если шаблон темы вставляет собственную кнопку вручную, придётся править шаблон или использовать CSS как временную меру.
Как не сломать корзину и прямые ссылки
Отключить кнопку — это только половина задачи. Пользователь может попасть на URL добавления в корзину напрямую, например через старую ссылку, закладку или кнопку в письме. Если товар больше не должен продаваться, лучше дополнительно проверить поведение на уровне корзины.
Для этого можно запретить добавление в корзину через фильтр:
add_filter( 'woocommerce_add_to_cart_validation', 'wpdir_block_add_to_cart_for_selected_products', 10, 3 );
function wpdir_block_add_to_cart_for_selected_products( $passed, $product_id, $quantity ) {
$disabled_ids = array( 123, 456, 789 );
if ( in_array( (int) $product_id, $disabled_ids, true ) ) {
wc_add_notice( 'Этот товар временно недоступен для покупки.', 'error' );
return false;
}
return $passed;
}Так вы закрываете и кнопку, и прямое добавление в корзину. Сообщение можно заменить на своё, но не делайте его слишком общим: пользователю лучше сразу понимать, что товар доступен только для просмотра.
Сравнение подходов: код, плагин, шаблон
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Хуки WooCommerce | Нужно отключить покупку точечно | Гибко, не трогает шаблоны | Нужен код и базовая проверка темы |
| Правка шаблона темы | Тема выводит кнопку нестандартно | Можно убрать любой элемент | Сложнее обновлять, выше риск поломки |
| Плагин для скрытия кнопок | Нет доступа к коду | Быстрое внедрение | Может конфликтовать с темой и кэшем |
Если у вас уже стоит набор оптимизационных настроек вроде Clearfy Pro, часть задач по очистке интерфейса и дублей можно закрыть им, но отключение покупки для отдельных товаров всё равно лучше держать в коде: так логика прозрачнее и не зависит от лишнего слоя настроек.
Проверка результата после внедрения
После добавления кода проверьте не только внешний вид карточки, но и реальные сценарии покупки.
- Откройте товар из списка отключённых и убедитесь, что кнопка
Добавить в корзинуисчезла. - Попробуйте открыть товар в новой вкладке и проверить, не выводится ли форма покупки через блок темы.
- Попробуйте добавить товар в корзину по прямой ссылке или из старой кнопки.
- Проверьте вариации, если товар вариативный.
- Очистите кэш страницы и CDN, если он используется.
Если товар всё ещё покупается, значит где-то остался альтернативный путь: кастомная кнопка в теме, сторонний плагин каталога или старый кэш.
Частые ошибки и как их исправить
Код добавили в родительскую тему
После обновления темы изменения пропадут. Используйте дочернюю тему или собственный плагин.
Проверяют только простые товары
Для вариативных товаров нужно отдельно учитывать woocommerce_variation_is_purchasable. Иначе часть вариаций может остаться доступной.
Отключили кнопку, но не запретили добавление в корзину
Пользователь всё ещё может попасть в корзину через прямую ссылку или старый URL. Для полного запрета нужен и фильтр woocommerce_add_to_cart_validation.
Не очистили кэш
Если сайт кэшируется, вы можете видеть старую версию страницы даже после правки кода. Сначала очищайте кэш плагина, сервера и CDN, потом проверяйте.
Используют CSS вместо логики
Скрыть кнопку стилями легко, но это не блокирует покупку. CSS годится только как временный визуальный слой, не как защита от покупки.
Практические советы по безопасности и поддержке
Если вы часто отключаете и включаете продажу у разных товаров, не храните список ID в разрозненных местах. Лучше вынести его в отдельную функцию или в метаполе товара, чтобы не править код каждый раз. Для больших каталогов удобнее завязаться на категорию или пользовательский флаг в метаданных.
Если у вас есть админская команда, зафиксируйте правило: перед публикацией товара проверять, должен ли он быть purchasable. Это снижает риск случайно открыть продажу на архивной карточке.
И ещё один практичный момент: если товар должен быть только витринным, не полагайтесь на визуальное скрытие кнопки. Блокировка покупки должна работать на сервере, а не только в интерфейсе.