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

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

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

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

Сначала стоит убедиться, что речь действительно о методе доставки local_pickup. В WooCommerce самовывоз может быть настроен в нескольких зонах доставки, и иногда проблема возникает не из-за оплаты, а из-за того, что выбран не тот shipping method ID или на странице оформления заказа используется кэшированная форма.

Диагностика перед правкой кода

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

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

Решение через код: скрываем онлайн-оплату при самовывозе

Самый надёжный вариант — добавить фильтр в functions.php дочерней темы или в небольшой mu-plugin. Логика простая: если в сессии выбран local_pickup, оставляем только нужные способы оплаты, например наличные при получении или оплату при самовывозе.

add_filter( 'woocommerce_available_payment_gateways', 'wpcource_disable_payments_for_local_pickup' );
function wpcource_disable_payments_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;
    }

    $chosen_shipping = reset( $chosen_methods );

    if ( strpos( $chosen_shipping, 'local_pickup' ) === false ) {
        return $gateways;
    }

    // Оставляем только оплату при получении, если она включена.
    $allowed_gateways = array( 'cod' );

    foreach ( $gateways as $gateway_id => $gateway ) {
        if ( ! in_array( $gateway_id, $allowed_gateways, true ) ) {
            unset( $gateways[ $gateway_id ] );
        }
    }

    return $gateways;
}

В этом примере при самовывозе останется только cod — стандартный метод WooCommerce для оплаты при доставке/получении. Если у вас используется другой способ, например банковский перевод, просто добавьте его ID в массив $allowed_gateways.

Если нужно отключить только конкретные методы оплаты

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

add_filter( 'woocommerce_available_payment_gateways', 'wpcource_hide_online_payments_for_pickup' );
function wpcource_hide_online_payments_for_pickup( $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 ) : '';

    if ( strpos( $chosen_shipping, 'local_pickup' ) === false ) {
        return $gateways;
    }

    $blocked_gateways = array( 'stripe', 'ppcp-gateway', 'paypal' );

    foreach ( $blocked_gateways as $gateway_id ) {
        if ( isset( $gateways[ $gateway_id ] ) ) {
            unset( $gateways[ $gateway_id ] );
        }
    }

    return $gateways;
}

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

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

ПодходКогда подходитПлюсыМинусы
Фильтр woocommerce_available_payment_gatewaysНужно гибко скрывать оплаты по способу доставкиТочный контроль, без лишних зависимостейНужно аккуратно проверить ID методов
Настройки платёжного плагинаПлагин умеет ограничивать оплату по доставкеМеньше кода, проще поддержкаНе у всех решений есть нужная логика
Отдельный плагин для conditional paymentsНужны правила без разработкиБыстрый стартДополнительная нагрузка и риск конфликтов

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

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

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

  • Откройте checkout в режиме инкогнито.
  • Добавьте товар в корзину и выберите самовывоз.
  • Убедитесь, что онлайн-оплата исчезла, а нужный метод остался.
  • Смените доставку на курьерскую и проверьте, что оплаты вернулись.
  • Проверьте мобильную версию: иногда тема рендерит блоки checkout иначе, чем на десктопе.

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

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

Неверный ID способа доставки

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

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

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

Слишком жёсткая фильтрация

Иногда разработчики полностью очищают массив $gateways и возвращают только один метод оплаты без проверки контекста. В результате на других страницах или при нестандартных сценариях checkout покупатель остаётся без доступных способов оплаты. Лучше всегда проверять, что выбран именно самовывоз, и не трогать оплату в админке.

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

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

Практические советы по безопасности и производительности

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

Код лучше хранить отдельно от темы, если правило бизнес-критичное. Для этого подойдёт небольшой mu-plugin: он не отключится случайно и не зависит от смены темы. А если в магазине уже стоит набор оптимизационных инструментов, например Clearfy Pro, проверьте, не вмешивается ли он в checkout-скрипты и не отключает ли нужные AJAX-запросы.

Что должно получиться после внедрения

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

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

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

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