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

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

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

Чаще всего ошибка выглядит так: в корзине выбран способ доставки local_pickup, но WooCommerce продолжает показывать все доступные способы оплаты. Иногда наоборот — после выбора доставки список оплаты пустеет полностью, и оформить заказ нельзя. Ещё один частый случай — на сайте установлен плагин доставки, который создаёт собственные ID методов, и старое правило перестаёт работать после обновления.

Что проверить в первую очередь

  • какой именно method_id у способа доставки в вашей установке;
  • какие методы оплаты должны оставаться доступными при самовывозе;
  • не влияет ли на выбор оплаты плагин доставки или мультивендорный модуль;
  • не используется ли кэш на уровне страницы корзины или checkout;
  • не переопределяет ли тему шаблоны WooCommerce.

Если вы не уверены в ID доставки, его проще всего посмотреть через временный лог или отладочный вывод в фильтре, чем гадать по названию на русском в админке.

Какие есть варианты решения

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

ПодходКогда подходитМинус
ПлагинНужны правила без кода и несколько сценариевЗависимость от стороннего решения
functions.phpОдно-два точных условияРиск потерять код при смене темы
Мини-плагинНужно стабильное решение без привязки к темеЧуть дольше на внедрение

Если у вас уже есть набор утилит для чистки и оптимизации сайта, например Clearfy Pro, часть мелких задач по WooCommerce и checkout можно держать в одном месте. Но саму бизнес-логику оплаты лучше не прятать в «комбайн», если она критична для продаж.

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

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

<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpbit_hide_payment_methods_for_local_pickup' );
function wpbit_hide_payment_methods_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 = $chosen_methods[0];

    // local_pickup — стандартный ID самовывоза в WooCommerce.
    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 — оплата при получении. Если вам нужно оставить, например, банковский перевод, добавьте его ID в массив $allowed_gateways.

Как узнать ID способа оплаты

В WooCommerce ID обычно совпадает с системным названием метода: cod, bacs, cheque, stripe, paypal. У сторонних платёжных шлюзов ID нужно смотреть в настройках плагина или в коде, если документация не помогает. Не ориентируйтесь только на подпись в интерфейсе — она может не совпадать с фактическим ID.

Если нужно отключать оплату не только для local_pickup

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

<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpbit_payment_gateways_by_shipping_zone' );
function wpbit_payment_gateways_by_shipping_zone( $gateways ) {
    if ( is_admin() || ! function_exists( 'WC' ) || ! WC()->session ) {
        return $gateways;
    }

    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    if ( empty( $chosen_methods[0] ) ) {
        return $gateways;
    }

    $shipping_method = $chosen_methods[0];

    // При самовывозе убираем онлайн-эквайринг.
    if ( strpos( $shipping_method, 'local_pickup' ) !== false ) {
        unset( $gateways['stripe'] );
        unset( $gateways['paypal'] );
    }

    // При доставке курьером убираем оплату наличными.
    if ( strpos( $shipping_method, 'flat_rate' ) !== false ) {
        unset( $gateways['cod'] );
    }

    return $gateways;
}

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

Пошаговое внедрение без сюрпризов

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

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

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

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

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

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

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

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

Если вы сравниваете строку с local_pickup, а плагин доставки использует другой идентификатор, условие никогда не сработает. Решение простое: выведите значение chosen_shipping_methods в лог и проверьте фактический ID.

Код добавлен в неподходящее место

Если вставить фрагмент в шаблон страницы вместо functions.php или мини-плагина, он может не выполниться на AJAX-запросе checkout. Для WooCommerce это критично: список оплат часто обновляется именно через AJAX.

Скрыли все способы оплаты

Такое случается, когда массив $allowed_gateways пустой или в нём указан неправильный ID. В результате клиент не может завершить заказ. Всегда оставляйте хотя бы один рабочий метод для каждого сценария.

Кэш мешает обновлению checkout

Если кэшируется страница оформления заказа или фрагменты WooCommerce, клиент видит старый список оплат. Проверьте исключения для /cart/ и /checkout/, а также настройки CDN и серверного кэша.

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

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

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

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

Как удалить все пустые теги в WordPress
04.11.2025
Как создать собственный шорткод в WordPress
10.11.2025
Как настроить автоматическую отправку email уведомлений в WordPress
01.01.2026
Как избежать проблем с отключением WP-Cron в WordPress
20.04.2026
Как отключить индексацию архивов авторов и дат в WordPress без потери нужных страниц
21.08.2026