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

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

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

Чаще всего задача возникает в магазинах с несколькими сценариями доставки:

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

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

Диагностика проблемы: что проверить до правки кода

Прежде чем лезть в шаблоны и функции, проверьте, как WooCommerce хранит выбранную доставку. На странице оформления заказа метод доставки передаётся как ID вида flat_rate:3, local_pickup:1 или free_shipping:2. Именно по этому значению и нужно фильтровать оплату.

Полезно сначала понять, где проблема проявляется:

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

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

Как решить задачу через фильтр WooCommerce

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

Пример: скрыть оплату при самовывозе

Ниже код, который убирает оплату при получении, если выбран самовывоз. Его можно добавить в functions.php дочерней темы или в небольшой кастомный плагин.

add_filter( 'woocommerce_available_payment_gateways', 'wpbit_hide_cod_for_local_pickup' );

function wpbit_hide_cod_for_local_pickup( $gateways ) {
    if ( is_admin() ) {
        return $gateways;
    }

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

    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    $chosen_shipping = is_array( $chosen_methods ) ? reset( $chosen_methods ) : '';

    if ( strpos( $chosen_shipping, 'local_pickup' ) !== false ) {
        unset( $gateways['cod'] );
    }

    return $gateways;
}

Здесь cod — стандартный ID метода «Оплата при доставке». Если у вас другой способ оплаты, нужно подставить его ID. Посмотреть ID можно в настройках платежных шлюзов или через временный вывод массива доступных шлюзов.

Пример: скрыть несколько способов оплаты для конкретной доставки

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

add_filter( 'woocommerce_available_payment_gateways', 'wpbit_limit_gateways_by_shipping_method' );

function wpbit_limit_gateways_by_shipping_method( $gateways ) {
    if ( is_admin() || ! function_exists( 'WC' ) || ! WC()->session ) {
        return $gateways;
    }

    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    $chosen_shipping = is_array( $chosen_methods ) ? reset( $chosen_methods ) : '';

    $rules = array(
        'local_pickup' => array( 'cod', 'bacs' ),
        'flat_rate'     => array( 'cod' ),
    );

    foreach ( $rules as $shipping_key => $payment_ids ) {
        if ( strpos( $chosen_shipping, $shipping_key ) !== false ) {
            foreach ( $payment_ids as $payment_id ) {
                unset( $gateways[ $payment_id ] );
            }
        }
    }

    return $gateways;
}

Этот вариант удобен, если у вас есть несколько зон доставки и для каждой — свой набор платежей. Но не перегружайте его сложной логикой, если условие одно и простое.

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

ПодходКогда подходитПлюсыМинусы
Настройки WooCommerceНужно отключить метод оплаты глобальноБез кода, быстроНе умеет связывать оплату с доставкой
Плагин для checkout-правилНужно управлять правилами без разработкиУдобно для менеджераЛишняя зависимость, не всегда прозрачно работает с кешем
Код через фильтрНужна точная логика по доставкеКонтроль, предсказуемость, минимум лишнегоНужно аккуратно тестировать

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

Пошаговое внедрение без лишнего риска

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

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

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

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

Что стоит проверить отдельно:

  • обновление чекаута без перезагрузки страницы;
  • поведение на мобильном устройстве;
  • гостевой заказ и заказ после входа в аккаунт;
  • корректность на всех зонах доставки;
  • отсутствие ошибок в консоли браузера и в debug.log.

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

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

Сравнивают не тот ID доставки

Иногда разработчик проверяет только local_pickup, а реальный ID метода выглядит как local_pickup:2. В таком случае условие не срабатывает. Используйте strpos() или точное сравнение с полным ID, если он стабилен.

Проверяют только на сервере, но забывают про AJAX

WooCommerce на чекауте обновляет блоки через AJAX. Если метод оплаты скрывается только после полной перезагрузки, а не при смене доставки, значит логика не учитывает динамическое обновление страницы.

Ломают работу в админке

Без проверки is_admin() фильтр может мешать редактированию заказов или тестам в бэкенде. В большинстве случаев это не нужно, поэтому лучше сразу ограничить код фронтендом.

Скрывают не тот шлюз

В коде нужно использовать ID шлюза, а не его название в интерфейсе. Например, cod, bacs, cheque. Если ID указан неверно, метод не исчезнет, хотя фильтр отработает.

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

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

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

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

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

Как автоматизировать удаление старых неиспользуемых медиафайлов в WordPress
07.03.2026
Как автоматизировать удаление старого контента в WordPress с помощью Cron и плагинов
02.03.2026
WooCommerce: автоматическое удаление неактивных клиентов по истории заказов
05.08.2026
Как автоматизировать удаление старых пустых записей в WordPress
10.02.2026
Как установить и очистить очередь AJAX в WordPress для улучшения производительности
27.03.2026