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

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

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

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

Есть и обратная ситуация: для доставки курьером онлайн-оплата нужна, а для самовывоза — нет. Тогда логика должна зависеть не от всего магазина, а именно от выбранного способа доставки в корзине.

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

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

  • local_pickup — стандартный самовывоз;
  • flat_rate — фиксированная доставка, если вы используете её как самовывоз вручную;
  • кастомный метод от плагина доставки, у которого будет свой ID.

Если вы не уверены, какой ID используется, откройте корзину/оформление заказа и временно выведите выбранные shipping methods в лог или посмотрите массив в сессии. На практике проще сначала проверить стандартный local_pickup, а уже потом адаптировать под ваш плагин.

Что именно нужно скрывать

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

ПодходКогда подходитМинус
Настройка в админкеЕсли логика одинаковая для всего магазинаНе умеет зависеть от доставки
Код через фильтр WooCommerceЕсли нужно скрывать оплату только при самовывозеНужно аккуратно тестировать
Плагин для условий оплатыЕсли нет доступа к кодуДополнительная зависимость и возможные конфликты

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

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

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

function wptem_hide_payment_for_local_pickup( $available_gateways ) {
    if ( is_admin() ) {
        return $available_gateways;
    }

    if ( ! function_exists( 'WC' ) || ! WC()->session ) {
        return $available_gateways;
    }

    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );

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

    $chosen_shipping = $chosen_methods[0];

    if ( strpos( $chosen_shipping, 'local_pickup' ) !== false ) {
        // Оставляем только оплату при получении, если она есть.
        $allowed_gateways = array( 'cod' );

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

    return $available_gateways;
}

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

Если нужно просто отключить онлайн-оплату при самовывозе

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

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

function wptem_disable_online_payments_for_pickup( $available_gateways ) {
    if ( is_admin() || ! function_exists( 'WC' ) || ! WC()->session ) {
        return $available_gateways;
    }

    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );

    if ( empty( $chosen_methods[0] ) ) {
        return $available_gateways;
    }

    if ( false === strpos( $chosen_methods[0], 'local_pickup' ) ) {
        return $available_gateways;
    }

    $blocked_gateways = array( 'stripe', 'paypal', 'bacs' );

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

    return $available_gateways;
}

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

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

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

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

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

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

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

Самая частая причина — в коде проверяют local_pickup, а на сайте используется метод от стороннего плагина. В этом случае условие никогда не срабатывает. Решение простое: найдите реальный ID доставки и подставьте его в проверку.

Скрывают оплату в админке вместо фильтра

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

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

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

Не учитывают кэш и оптимизацию checkout

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

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

Логика оплаты — это не то место, где стоит экономить на проверках. Перед внедрением на рабочем магазине:

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

Если на сайте много технических дублей, лишних скриптов и мусорных настроек, полезно сначала привести базовую конфигурацию в порядок. В таких задачах обычно помогает аудит плагинов и оптимизация служебных настроек, например через Clearfy Pro: https://wpshop.ru/plugins/clearfy. Но саму логику оплаты всё равно лучше оставить в коде или в специализированном плагине условий оплаты.

Если нужен более гибкий сценарий

Иногда правило сложнее: например, для самовывоза из конкретного склада оставить карту, а для самовывоза из магазина — только наличные. Тогда одного условия по local_pickup уже мало. В таком случае логика строится по нескольким признакам: выбранный shipping method, метаданные метода доставки, город, сумма заказа или состав корзины.

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

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

Как динамически изменять заголовки страниц в WordPress
18.12.2025
Как автоматически отменять заказы WooCommerce после неудачной оплаты
19.04.2026
WooCommerce: автоматическое возврат средств после отмены заказа
10.06.2026
Как избежать конфликтов между плагинами WordPress: практические решения
27.01.2026
Как автоматизировать удаление старого контента в WordPress
03.04.2026