Как отключить покупку для отдельных товаров в WooCommerce без удаления карточки

Иногда товар должен оставаться в каталоге, но продавать его в лоб нельзя: нет остатка, цена согласуется вручную, товар доступен только для оптовиков или временно снят с продажи. В WooCommerce это лучше решать не удалением карточки и не костылями в шаблоне, а точечным отключением покупки для конкретных товаров.

Ниже разберём рабочие варианты: скрыть кнопку Купить, заменить её на текст или ссылку, оставить карточку в каталоге и при этом заблокировать добавление в корзину. Подходы подойдут для простых товаров и для вариативных, если нужно отключать продажу не у всего каталога, а у отдельных позиций.

Когда это действительно нужно

Типичный сценарий выглядит так: карточка товара должна индексироваться, попадать в подборки и фильтры, но оформление заказа по ней недоступно. Если просто поставить нулевую цену или убрать товар из каталога, вы потеряете часть сценариев: пользователь не увидит товар, менеджер не сможет быстро вернуть продажу, а в поиске останутся дыры.

Практически это применяют для:

  • товаров «под заказ»;
  • позиций без остатка, которые нельзя купить до поставки;
  • закрытых цен для авторизованных пользователей;
  • каталога без онлайн-оплаты, где заявка уходит менеджеру;
  • отдельных вариаций, которые временно недоступны.

Диагностика проблемы: что именно нужно отключить

Перед правкой кода важно понять, что вы хотите убрать. В WooCommerce есть несколько разных точек поведения, и они не всегда связаны между собой.

Скрыть кнопку и оставить просмотр карточки

Это самый мягкий вариант. Пользователь видит товар, но не может добавить его в корзину. Подходит, если продажа временно недоступна, но карточка нужна для SEO и навигации.

Полностью запретить добавление в корзину

Здесь кнопка может исчезнуть, а прямой запрос в корзину тоже будет заблокирован. Это уже защита от обхода интерфейса через URL, AJAX или старые ссылки.

Заменить покупку на заявку или статус

Если товар продаётся только после согласования, вместо кнопки лучше показать понятный текст: Цена по запросу, Доступно для заказа у менеджера, Товар временно недоступен.

Сравнение подходов

ПодходЧто делаетПлюсМинус
Скрыть кнопку в шаблонеУбирает визуальный CTAБыстроНе блокирует прямое добавление в корзину
Фильтры WooCommerceОтключает покупку на уровне логикиНадёжноНужен код
Плагин для каталогаДаёт настройки без разработкиУдобно для менеджераМожет быть лишним по функционалу

Если задача точечная и у вас есть доступ к теме или мини-плагину, лучше идти через хуки WooCommerce. Это предсказуемее, чем править шаблоны, и не сломается при обновлении темы.

Пошаговое решение через код

Ниже пример, который отключает покупку для выбранных товаров по ID. Он убирает кнопку Купить, блокирует добавление в корзину и показывает свой текст на странице товара.

<?php
add_filter( 'woocommerce_is_purchasable', 'wpplugins_disable_purchase_for_products', 10, 2 );
function wpplugins_disable_purchase_for_products( $purchasable, $product ) {
    $disabled_ids = array( 123, 456 );

    if ( in_array( $product->get_id(), $disabled_ids, true ) ) {
        return false;
    }

    return $purchasable;
}

add_filter( 'woocommerce_variation_is_purchasable', 'wpplugins_disable_purchase_for_variations', 10, 2 );
function wpplugins_disable_purchase_for_variations( $purchasable, $product ) {
    $disabled_ids = array( 123, 456 );

    if ( in_array( $product->get_parent_id(), $disabled_ids, true ) ) {
        return false;
    }

    return $purchasable;
}

add_filter( 'woocommerce_loop_add_to_cart_link', 'wpplugins_replace_add_to_cart_button', 10, 2 );
function wpplugins_replace_add_to_cart_button( $html, $product ) {
    $disabled_ids = array( 123, 456 );

    if ( in_array( $product->get_id(), $disabled_ids, true ) ) {
        return '<span class="stock out-of-stock">Цена по запросу</span>';
    }

    return $html;
}

add_filter( 'woocommerce_product_single_add_to_cart_text', 'wpplugins_change_single_add_to_cart_text' );
function wpplugins_change_single_add_to_cart_text( $text ) {
    global $product;

    if ( $product && in_array( $product->get_id(), array( 123, 456 ), true ) ) {
        return 'Уточнить наличие';
    }

    return $text;
}

add_filter( 'woocommerce_is_purchasable', 'wpplugins_block_direct_add_to_cart', 10, 2 );
function wpplugins_block_direct_add_to_cart( $purchasable, $product ) {
    $disabled_ids = array( 123, 456 );

    if ( in_array( $product->get_id(), $disabled_ids, true ) ) {
        return false;
    }

    return $purchasable;
}

Этот пример лучше вставлять не в functions.php активной темы, а в небольшой mu-plugin или в собственный мини-плагин. Так вы не потеряете логику при смене темы.

Если нужно отключать покупку по метаполю

Когда список товаров часто меняется, удобнее хранить флаг в метаданных товара, например _disable_purchase. Тогда менеджер может включать и выключать продажу без правки кода.

<?php
add_filter( 'woocommerce_is_purchasable', 'wpplugins_disable_purchase_by_meta', 10, 2 );
function wpplugins_disable_purchase_by_meta( $purchasable, $product ) {
    if ( 'yes' === get_post_meta( $product->get_id(), '_disable_purchase', true ) ) {
        return false;
    }

    return $purchasable;
}

В админке это можно связать с пользовательским полем или с ACF, если он уже используется в проекте. Главное — не смешивать логику отображения и логику продажи в одном шаблоне.

Как проверить, что решение сработало

После внедрения проверьте не только внешний вид, но и поведение корзины. Иначе можно убрать кнопку, но оставить возможность добавить товар через старую ссылку или AJAX-запрос.

  • откройте карточку товара в каталоге и убедитесь, что кнопка покупки заменена на нужный текст;
  • попробуйте открыть товар напрямую и проверить, исчезла ли форма добавления в корзину;
  • добавьте товар по старой ссылке ?add-to-cart=ID и убедитесь, что WooCommerce его не принимает;
  • проверьте вариативный товар: каждая вариация должна вести себя так же, как и родительский товар;
  • очистите кеш страницы, если используется плагин кеширования или серверный кеш.

Если товар всё ещё добавляется в корзину, значит вы скрыли только кнопку, но не заблокировали логику покупки. В этом случае нужен именно фильтр woocommerce_is_purchasable, а не только правка шаблона.

Частые ошибки и как их исправить

Меняют только шаблон, а не логику

Это самая распространённая ошибка. Кнопка исчезает, но товар всё равно можно добавить в корзину через прямой URL, сохранённую ссылку или сторонний скрипт. Исправление простое: блокируйте покупку на уровне WooCommerce-фильтров.

Не учитывают вариации

Если отключить только родительский товар, вариации могут остаться покупаемыми. Для вариативных товаров проверяйте не только get_id(), но и get_parent_id(), как в примере выше.

Ломают вывод в каталоге для всех товаров

Иногда разработчик забывает ограничить условие списком ID или метаполем, и вместо одного товара отключается весь магазин. Перед публикацией проверьте массив ID и тестовый товар.

Ставят нулевую цену вместо отключения покупки

Это плохая замена. Нулевая цена не означает запрет продажи: товар может попасть в корзину и оформить заказ как бесплатный. Если товар не должен продаваться, нужно именно отключать purchasable-логику.

Если нужен вариант без кода

Когда проектом управляет контент-менеджер и список недоступных товаров меняется часто, можно использовать плагин каталога или режим каталога для WooCommerce. Но перед установкой проверьте, что плагин умеет именно отключать покупку, а не только скрывать кнопки. Иначе проблема вернётся на уровне корзины.

Если у вас уже стоит набор инструментов для чистки и оптимизации сайта, например Clearfy Pro, проверьте, не конфликтует ли он с шаблоном каталога и кастомными фильтрами WooCommerce. Любая дополнительная логика в магазине должна тестироваться на staging-копии, особенно если тема переопределяет шаблоны WooCommerce.

Практические советы по безопасности и производительности

  • не храните список отключённых товаров в жёстко зашитом коде, если он часто меняется;
  • используйте метаполе или отдельную настройку, чтобы не редактировать код при каждой правке каталога;
  • проверяйте поведение на мобильной версии, потому что тема может по-разному рендерить кнопку покупки;
  • после изменения логики очистите кеш страниц, object cache и CDN, если он есть;
  • не правьте файлы плагина WooCommerce напрямую — обновление затрёт изменения.

Если задача сводится к нескольким товарам, лучше сделать маленький mu-plugin с одним-двумя фильтрами. Это проще сопровождать, чем держать код в теме, и безопаснее для обновлений.

Как создать автоматический кеш для REST API WordPress
22.02.2026
WooCommerce: решение проблемы отображения атрибутов вариаций в корзине
18.05.2026
WooCommerce: решение проблемы неудачного удаления товара из корзины
10.06.2026
Автоматическое удаление старого контента в WordPress
06.02.2026
Как настроить автоматическую очистку кеша в WordPress: эффективные методы и примеры
08.03.2026