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

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

Задача здесь не в том, чтобы просто «спрятать оплату», а в том, чтобы связать доступность платежных методов с конкретной доставкой. В WooCommerce это можно сделать без тяжёлых плагинов, если у вас понятная логика: например, наложенный платёж доступен только при самовывозе, а банковский перевод — только для курьерской доставки.

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

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

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

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

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

Сначала проверьте, что именно у вас считается «доступной доставкой». В WooCommerce это не всегда один метод: иногда выбранная доставка хранится как комбинация идентификатора метода и instance ID, особенно если у вас несколько зон доставки.

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

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

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

Рабочий способ через фильтр WooCommerce

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

Ниже пример, который скрывает cod и bacs, если выбран не тот способ доставки. Идентификаторы нужно заменить на свои: у вас они могут отличаться в зависимости от настроек и плагинов.

<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpbono_filter_payment_gateways_by_shipping' );

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

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

    $chosen_methods = WC()->session ? WC()->session->get( 'chosen_shipping_methods' ) : array();
    $chosen_shipping = isset( $chosen_methods[0] ) ? $chosen_methods[0] : '';

    if ( ! $chosen_shipping ) {
        return $gateways;
    }

    // Пример: local_pickup:3 — самовывоз с instance ID 3.
    // Замените на свои значения из настроек доставки.
    $pickup_methods = array( 'local_pickup:3' );

    if ( in_array( $chosen_shipping, $pickup_methods, true ) ) {
        unset( $gateways['bacs'] ); // банковский перевод
    } else {
        unset( $gateways['cod'] );  // наложенный платёж
    }

    return $gateways;
}

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

Если нужно учитывать не только доставку, но и состав корзины

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

<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpbono_disable_gateways_for_cart_rules' );

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

    $has_virtual = false;

    foreach ( WC()->cart->get_cart() as $item ) {
        if ( ! empty( $item['data'] ) && $item['data']->is_virtual() ) {
            $has_virtual = true;
            break;
        }
    }

    if ( $has_virtual ) {
        unset( $gateways['cod'] );
    }

    return $gateways;
}

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

Плагин, код или гибридный вариант

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

ПодходКогда подходитМинус
Код через фильтрНужны 1–3 понятных правилаНужно аккуратно поддерживать идентификаторы методов
Плагин условий checkoutПравил много, их меняет менеджерЛишняя нагрузка и риск конфликтов
ГибридЧасть логики в коде, часть — в настройкахВажно не дублировать правила

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

Пошаговое внедрение без поломки checkout

  1. Скопируйте код в дочернюю тему или в собственный мини-плагин.
  2. Замените идентификаторы способов оплаты на реальные: cod, bacs, stripe и т.д.
  3. Проверьте instance ID у способов доставки, если логика завязана на конкретную зону.
  4. Очистите кэш страницы оформления заказа, если он используется.
  5. Протестируйте сценарии в разных зонах доставки и с разными товарами.

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

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

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

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

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

Неправильный идентификатор метода доставки

Самая частая ошибка — сравнивают не тот ID. В WooCommerce у доставки может быть не просто local_pickup, а local_pickup:3. Если instance ID не совпадает, условие никогда не сработает.

Проверка только по первой доставке

В корзине с несколькими пакетами доставки может быть несколько значений в chosen_shipping_methods. Если у вас сложная логика, одного индекса [0] может быть недостаточно. Для простых магазинов этого хватает, но в мультипакетных сценариях нужно смотреть структуру данных внимательнее.

Скрытие оплаты в админке

Если не ограничить выполнение кода, можно случайно повлиять на админские экраны или AJAX-запросы. Поэтому в примерах выше есть проверка is_admin() и контроль наличия WC().

Конфликт с плагином доставки или оплаты

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

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

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

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

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

WooCommerce: как исключить определённые товары из способов оплаты
26.04.2026
Как добавить вывод из внешнего API в WordPress с помощью AJAX
20.03.2026
Использование хука wpbono_pre_update_post для кастомизации обновления записей в WordPress
15.01.2026
Как сделать обязательное поле комментария в WooCommerce при оформлении заказа
12.08.2026
Как оптимизировать загрузку библиотеки jQuery в WordPress
31.12.2025