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

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

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

Когда проблема проявляется и что именно проверять

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

  • страны или региона покупателя;
  • валюты магазина;
  • суммы заказа;
  • статуса включения самого платежного шлюза;
  • кеша на стороне темы, плагина оптимизации или CDN.

Если платежи пропадают не только при смене доставки, сначала проверьте настройки каждого шлюза в WooCommerce → Настройки → Платежи. Если же логика нужна именно по способу доставки, переходите к фильтру woocommerce_available_payment_gateways.

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

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

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

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

add_filter( 'woocommerce_available_payment_gateways', 'wpcource_filter_payment_gateways_by_shipping' );
function wpcource_filter_payment_gateways_by_shipping( $gateways ) {
    if ( is_admin() && ! wp_doing_ajax() ) {
        return $gateways;
    }

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

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

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

    // Пример: самовывоз
    if ( strpos( $chosen_shipping, 'local_pickup' ) !== false ) {
        unset( $gateways['cod'] );
        unset( $gateways['stripe'] );
        unset( $gateways['paypal'] );
    }

    return $gateways;
}

Что здесь важно:

  • cod, stripe, paypal — это примеры ID платежных шлюзов, а не универсальные значения;
  • local_pickup — часть ID способа доставки, которая часто встречается у стандартного самовывоза;
  • если у вас несколько зон доставки, лучше проверять точный ID, а не только подстроку.

Как подставить свои ID доставки и оплаты

Если вы не уверены в ID, временно выведите их в лог или посмотрите через отладку в браузере. Для доставки стандартные значения обычно выглядят как flat_rate:1, free_shipping:2, local_pickup:3. У платежей ID зависят от шлюза: у банковской карты это может быть stripe, у наложенного платежа — cod.

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

add_filter( 'woocommerce_available_payment_gateways', 'wpcource_allow_only_cash_for_pickup' );
function wpcource_allow_only_cash_for_pickup( $gateways ) {
    if ( is_admin() && ! wp_doing_ajax() ) {
        return $gateways;
    }

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

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

    if ( $chosen_shipping === 'local_pickup:3' ) {
        foreach ( $gateways as $gateway_id => $gateway ) {
            if ( $gateway_id !== 'cod' ) {
                unset( $gateways[ $gateway_id ] );
            }
        }
    }

    return $gateways;
}

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

Плагин или код: что выбрать

ПодходКогда подходитМинус
Код через фильтрОдна-две понятные бизнес-логики по доставке и оплатеНужно аккуратно поддерживать ID методов
Плагин с правилами checkoutМного условий: роли, страны, суммы, способы доставкиБольше настроек, выше риск конфликтов
Комбинированный вариантЧасть правил в коде, часть — в админкеСложнее сопровождать и тестировать

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

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

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

  1. Откройте оформление заказа в режиме инкогнито.
  2. Выберите нужный способ доставки.
  3. Убедитесь, что список оплаты обновился без перезагрузки страницы.
  4. Проверьте, что при смене доставки список платежей меняется обратно.
  5. Создайте тестовый заказ и убедитесь, что в админке он сохраняется с корректным методом оплаты.

Если на checkout используется AJAX-обновление, а список не меняется, проверьте, не ломает ли тему стандартные скрипты WooCommerce. В консоли браузера не должно быть ошибок JavaScript на событии обновления checkout.

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

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

Самая частая причина — в коде указан не тот ID. Визуальное название метода в админке и его технический ID не совпадают. Проверьте ID в настройках плагина оплаты или через временный вывод массива $gateways.

Сравнение только по части строки

Если использовать слишком общее условие, можно случайно задеть несколько способов доставки. Например, строка pickup может совпасть с несколькими методами. Для точного сценария лучше сравнивать полный ID, если он стабилен.

Код вставлен не туда

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

Кеш мешает увидеть изменения

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

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

Для такой задачи не нужен тяжелый плагин, если логика простая. Меньше зависимостей — меньше конфликтов на checkout. Но если вы все же используете плагин условий, проверьте, как он работает с AJAX-обновлением WooCommerce и не добавляет ли лишние запросы на каждой смене доставки.

Код лучше держать в отдельном мини-плагине или mu-plugin, если правило критично для продаж. Тогда оно не исчезнет при смене темы. И не забывайте тестировать после обновлений WooCommerce: фильтр woocommerce_available_payment_gateways стабилен, но поведение checkout может меняться из-за других расширений.

Короткий чек-лист перед запуском

  • Проверены реальные ID способов доставки и платежей.
  • Код не конфликтует с другими плагинами checkout.
  • Очистен кеш сайта и браузера.
  • Тест пройден в инкогнито и на мобильном устройстве.
  • Заказ создается с правильным методом оплаты.

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

Как закрыть дубли страниц в WordPress от пагинации, фильтров и параметров
19.08.2026
Как закрыть от индексации отдельные страницы WordPress без поломки SEO
22.08.2026

Обучение разработке на WordPress, как создавать темы, плагины. Подробнее об обучении.