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

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

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

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

Не стоит отключать оплату «на всякий случай». Этот приём нужен, когда есть чёткое правило, зависящее от состава корзины, категории товара или способа доставки. Например:

  • для товаров из категории preorder доступна только оплата по счёту;
  • для самовывоза нужно скрыть онлайн-эквайринг;
  • для бесплатных товаров или образцов оставить только ручное подтверждение;
  • для крупногабаритных товаров убрать быстрые платежи, если заказ обрабатывается менеджером;
  • для B2B-каталога отключить карты и оставить банковский перевод.

Диагностика проблемы перед изменениями

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

Что проверить в админке

  • Включён ли нужный способ оплаты в WooCommerce → Настройки → Платежи.
  • Не ограничивает ли шлюз страны, валюту или тип товаров.
  • Не влияет ли на поведение плагин доставки, подписок, B2B-ценообразования или мультивалютности.
  • Не меняется ли состав корзины после применения купона или доставки.

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

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

Самый надёжный вариант — добавить небольшой код в дочернюю тему или в собственный мини-плагин. Ниже пример, который отключает онлайн-оплату, если в корзине есть товар из определённой категории. В примере категория называется preorder, но вы можете заменить её на свою.

<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpsolution_disable_gateways_for_preorder_items' );
function wpsolution_disable_gateways_for_preorder_items( $gateways ) {
    if ( is_admin() ) {
        return $gateways;
    }

    if ( ! function_exists( 'WC' ) || ! WC()->cart ) {
        return $gateways;
    }

    $has_preorder_item = false;

    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if ( empty( $cart_item['product_id'] ) ) {
            continue;
        }

        if ( has_term( 'preorder', 'product_cat', $cart_item['product_id'] ) ) {
            $has_preorder_item = true;
            break;
        }
    }

    if ( $has_preorder_item ) {
        unset( $gateways['stripe'] );
        unset( $gateways['paypal'] );
    }

    return $gateways;
}

В этом примере удаляются шлюзы с ID stripe и paypal. У вас ID могут отличаться — их нужно сверить с тем, как шлюз зарегистрирован в магазине. Если вы не уверены, временно выведите массив доступных шлюзов через array_keys( WC()->payment_gateways()->get_available_payment_gateways() ) в лог, а не в браузер.

Если нужно отключать оплату по категории и способу доставки

Часто правило зависит не только от товара, но и от доставки. Например, при самовывозе можно оставить только оплату наличными или переводом. Тогда проверяйте и корзину, и выбранный метод доставки.

<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpsolution_disable_gateways_for_pickup' );
function wpsolution_disable_gateways_for_pickup( $gateways ) {
    if ( is_admin() || ! function_exists( 'WC' ) || ! WC()->session || ! WC()->cart ) {
        return $gateways;
    }

    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    $chosen_shipping = is_array( $chosen_methods ) && ! empty( $chosen_methods[0] ) ? $chosen_methods[0] : '';

    $has_target_category = false;
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        if ( has_term( 'bulky', 'product_cat', $cart_item['product_id'] ) ) {
            $has_target_category = true;
            break;
        }
    }

    if ( $has_target_category && str_contains( $chosen_shipping, 'local_pickup' ) ) {
        unset( $gateways['stripe'] );
        unset( $gateways['yookassa'] );
    }

    return $gateways;
}

Здесь важно не полагаться на название метода доставки «на глаз». WooCommerce хранит технический ID, и он может отличаться от текста, который видит клиент.

Сравнение подходов: код, плагин, настройки

ПодходКогда подходитПлюсыМинусы
Код через фильтрНужна точная логика по товарам, категориям, доставкеКонтроль, предсказуемость, без лишних зависимостейНужно тестировать после обновлений
Плагин условий оплатыНужно быстро настроить без разработкиИнтерфейс, меньше кодаДополнительная нагрузка и риск конфликтов
Настройки шлюзаШлюз сам умеет ограничивать оплатуМинимум вмешательстваОбычно хватает только для простых сценариев

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

Как проверить, что всё работает

После внедрения не ограничивайтесь одним тестом. Проверьте несколько сценариев вручную:

  1. Добавьте в корзину обычный товар и убедитесь, что все нужные методы оплаты видны.
  2. Добавьте товар из целевой категории и проверьте, что лишние шлюзы исчезли.
  3. Смените способ доставки и обновите checkout, чтобы увидеть, не возвращаются ли скрытые методы.
  4. Протестируйте как авторизованный пользователь и как гость.
  5. Проверьте мобильную версию checkout, потому что некоторые темы по-разному перерисовывают блоки оплаты.

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

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

Неверный ID платёжного шлюза

Самая частая ошибка — удаляют не тот ключ из массива $gateways. В результате код выполняется, но нужный способ оплаты остаётся на месте. Сверяйте ID шлюза с его регистрацией в WooCommerce или временно логируйте массив доступных ключей.

Проверка только по product_id, когда нужен variation ID

Если правило завязано на вариации, а вы проверяете только родительский товар, логика может сработать не так, как ожидается. Для вариативных товаров иногда нужно дополнительно смотреть variation_id и свойства вариации.

Код вставлен в неподходящее место

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

Нет проверки на пустую корзину

На некоторых этапах WooCommerce может обращаться к фильтру, когда корзина ещё не инициализирована. Поэтому в коде нужны проверки WC() и WC()->cart.

Конфликт с плагином доставки или мультивалютности

Если шлюз скрывается и появляется обратно после смены доставки, причина часто в стороннем плагине, который пересчитывает checkout через AJAX. В таком случае проверяйте, не переопределяет ли он доступные методы оплаты после вашего фильтра.

Безопасность и производительность

Сам фильтр лёгкий, но плохая реализация может замедлить checkout. Не делайте тяжёлые запросы к базе внутри цикла по корзине и не тяните внешние API на каждом обновлении страницы оплаты. Если правило можно выразить через категорию, тег или метаполе товара, используйте именно эти данные.

Для безопасности не выводите отладку в HTML checkout. Если нужно посмотреть, что происходит, пишите в лог через error_log() или временно используйте WC_Logger. И не забывайте удалять отладочные записи после проверки.

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

Практический чек-лист перед публикацией

  • Проверен точный ID платёжного шлюза.
  • Проверены категории, теги или метаполя, по которым идёт фильтрация.
  • Тест пройден для гостя и авторизованного пользователя.
  • Проверены разные способы доставки.
  • Страница checkout исключена из кеша.
  • Код добавлен в дочернюю тему или мини-плагин, а не в основной файл темы.
  • Нет лишнего вывода в браузер и отладочных сообщений для посетителей.

Если нужно быстро собрать магазин с более чистой админкой и убрать лишние системные элементы, можно посмотреть Clearfy Pro: https://wpshop.ru/plugins/clearfy. Но для самой логики отключения оплаты всё равно нужен код или специализированный плагин условий оплаты.

Как использовать WPRemark для анализа качества контента в WordPress
16.02.2026
Как использовать WP хуки для автоматизации обработки заказов WooCommerce
03.06.2026
Как удалить пустые категории в WordPress с помощью кода
08.04.2026
WooCommerce: как автоматически удалять товары после продажи
22.05.2026
Как удалить порты в WordPress для блокировки внешних запросов
30.03.2026