Как отключить оплату при самовывозе в WooCommerce и оставить только оплату при доставке

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

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

Когда это нужно и как выглядит проблема

Сценарий обычно такой:

  • в корзине выбран способ доставки local_pickup;
  • WooCommerce всё равно показывает онлайн-платежи на checkout;
  • нужно оставить, например, только cod или вообще скрыть все платёжные методы для самовывоза;
  • при доставке курьером или почтой платёжные методы должны работать как раньше.

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

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

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

Проверьте код способа доставки

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

Проверьте настройки платёжных шлюзов

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

Проверьте, не делает ли это тема или плагин

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

Варианты решения: плагин, код или настройка

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

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

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

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

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

add_filter( 'woocommerce_available_payment_gateways', 'wpscan_hide_gateways_for_local_pickup' );

function wpscan_hide_gateways_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' );

    if ( empty( $chosen_methods ) || ! is_array( $chosen_methods ) ) {
        return $gateways;
    }

    foreach ( $chosen_methods as $chosen_method ) {
        if ( strpos( $chosen_method, 'local_pickup' ) === 0 ) {
            // Оставляем только оплату при получении, если она есть.
            foreach ( $gateways as $gateway_id => $gateway ) {
                if ( 'cod' !== $gateway_id ) {
                    unset( $gateways[ $gateway_id ] );
                }
            }
            break;
        }
    }

    return $gateways;
}

Что делает этот код:

  • читает выбранный способ доставки из сессии WooCommerce;
  • проверяет, есть ли среди выбранных методов local_pickup;
  • если да — оставляет только cod;
  • если нет — не меняет список платёжных методов.

Если вам нужно не оставлять cod, а скрывать вообще все методы оплаты при самовывозе, замените внутренний цикл на return array();. Но такой вариант подходит не всем: если заказ должен оформляться без оплаты, убедитесь, что это соответствует бизнес-процессу.

Если у вас другой ID способа доставки

У сторонних плагинов доставки ID может быть другим. Тогда условие нужно подстроить под фактический код метода. Например, если метод называется не local_pickup, а содержит свой префикс, проверяйте его через strpos() или точное сравнение.

if ( strpos( $chosen_method, 'my_pickup_method' ) === 0 ) {
    // ваша логика
}

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

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

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

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

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

Код добавили в родительскую тему

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

Проверяют только страницу, а не заказ

Иногда на экране checkout всё выглядит правильно, но заказ создаётся с другим способом оплаты из-за стороннего фильтра. Проверяйте итоговый заказ в админке.

Не учитывают кэш

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

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

Стандартный local_pickup и ID из стороннего плагина — это не одно и то же. Сначала посмотрите фактическое значение в выбранных методах доставки.

Скрывают все платежи без запасного сценария

Если вы полностью убираете оплату, но заказ всё равно требует payment method, checkout может начать вести себя нестабильно. Для таких сценариев заранее проверьте, как магазин обрабатывает заказы без онлайн-оплаты.

Практика безопасности и поддержки

Любую логику checkout лучше держать в отдельном мини-плагине или mu-plugin, а не в случайном фрагменте из редактора темы. Так проще откатить изменение и не потерять его после обновления.

  • храните код в Git, если проект уже ведётся как разработка;
  • тестируйте на staging-копии с реальными способами доставки и оплаты;
  • не отключайте платёжные шлюзы глобально, если они нужны для других сценариев;
  • после правки проверьте мобильный checkout — там чаще всплывают проблемы с обновлением методов доставки через AJAX.

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

Если нужно расширить правило

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

if ( strpos( $chosen_method, 'local_pickup' ) === 0 ) {
    $cart_total = WC()->cart ? WC()->cart->get_total( 'edit' ) : 0;

    if ( $cart_total > 0 ) {
        foreach ( $gateways as $gateway_id => $gateway ) {
            if ( 'cod' !== $gateway_id ) {
                unset( $gateways[ $gateway_id ] );
            }
        }
    }
}

Такой подход удобен, если у вас есть отдельные правила для дорогих заказов или предоплаты. Но перед внедрением обязательно проверьте, что get_total( 'edit' ) возвращает ожидаемое значение в вашей версии WooCommerce, потому что формат суммы может отличаться от того, что вы видите на экране.

Как отключить плагины на определённых страницах WordPress
06.02.2026
Как отладить проблемы с кэшированием в WordPress
25.11.2025
Как защитить WordPress от несанкционированной загрузки файлов
09.02.2026
Как отключить оплату при самовывозе в WooCommerce и оставить только оплату при доставке
11.08.2026
Как использовать REST API WordPress для создания плагинов
08.11.2025