wpstart.ru wordpress wpstart.ru

Ограничение способов оплаты по стране в WooCommerce

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

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

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

Ограничение по стране полезно не только для платёжных систем. Оно помогает, если:

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

Диагностика: почему метод оплаты виден всем

Сначала проверьте, где именно WooCommerce принимает решение о доступности шлюза. Частая ошибка — пытаться скрыть метод через CSS или JS. Это работает только визуально: в заказе метод всё равно может остаться доступным, а при пересчёте checkout он снова появится.

Посмотрите на три вещи:

  1. какие платёжные шлюзы активны в WooCommerce → Настройки → Платежи;
  2. какая страна указана в адресе доставки или оплаты;
  3. используется ли плагин, который уже фильтрует методы оплаты по условиям.

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

Рабочее решение через фильтр доступных шлюзов

Для такой задачи подходит фильтр woocommerce_available_payment_gateways. Он позволяет убрать конкретные методы оплаты в зависимости от страны в адресе доставки или оплаты.

Ниже пример для functions.php дочерней темы или собственного мини-плагина. В примере:

  • для России оставляем все методы;
  • для других стран скрываем bacs и cod;
  • если страна не определена, ничего не ломаем и не удаляем методы принудительно.
add_filter( 'woocommerce_available_payment_gateways', 'wpstart_limit_payment_gateways_by_country' );
function wpstart_limit_payment_gateways_by_country( $gateways ) {
    if ( is_admin() ) {
        return $gateways;
    }

    if ( ! function_exists( 'WC' ) || ! WC()->customer ) {
        return $gateways;
    }

    $country = WC()->customer->get_billing_country();

    // Если страна оплаты не заполнена, не вмешиваемся.
    if ( empty( $country ) ) {
        $country = WC()->customer->get_shipping_country();
    }

    // Для России оставляем все доступные методы.
    if ( 'RU' === $country ) {
        return $gateways;
    }

    // Для остальных стран скрываем банковский перевод и наложенный платёж.
    $blocked_gateways = array( 'bacs', 'cod' );

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

    return $gateways;
}

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

add_filter( 'woocommerce_available_payment_gateways', 'wpstart_payment_gateways_by_country_map' );
function wpstart_payment_gateways_by_country_map( $gateways ) {
    if ( is_admin() || ! function_exists( 'WC' ) || ! WC()->customer ) {
        return $gateways;
    }

    $country = WC()->customer->get_billing_country();
    if ( empty( $country ) ) {
        $country = WC()->customer->get_shipping_country();
    }

    $rules = array(
        'RU' => array(),
        'KZ' => array( 'cod' ),
        'BY' => array( 'cod', 'bacs' ),
        'US' => array( 'cod', 'cheque' ),
    );

    if ( empty( $rules[ $country ] ) ) {
        return $gateways;
    }

    foreach ( $rules[ $country ] as $gateway_id ) {
        unset( $gateways[ $gateway_id ] );
    }

    return $gateways;
}

Если страна зависит от доставки, а не от адреса оплаты

В некоторых магазинах покупатель сначала вводит адрес доставки, а платёжный метод должен зависеть именно от него. Тогда логика по billing country может быть недостаточной. В таком случае лучше использовать shipping country, но с оговоркой: на раннем этапе checkout оно может быть пустым.

Практически это означает, что:

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

Если магазин работает только с одной страной доставки, можно жёстко опираться на shipping country. Если стран несколько, лучше использовать оба поля с приоритетом billing → shipping, как в примерах выше.

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

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

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

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

Что смотреть в логах и отладке

Если метод не скрывается, временно добавьте логирование в код, чтобы понять, какая страна реально приходит в объекте клиента. Это особенно полезно, когда адрес подставляется из геолокации или автозаполнения.

add_filter( 'woocommerce_available_payment_gateways', 'wpstart_debug_payment_country', 20 );
function wpstart_debug_payment_country( $gateways ) {
    if ( function_exists( 'WC' ) && WC()->customer ) {
        error_log( 'Billing country: ' . WC()->customer->get_billing_country() );
        error_log( 'Shipping country: ' . WC()->customer->get_shipping_country() );
    }

    return $gateways;
}

После проверки этот код нужно убрать. Постоянный error_log в checkout быстро засоряет логи и мешает искать реальные ошибки.

Сравнение подходов: код, плагин, CSS

ПодходКогда подходитПлюсыМинусы
Фильтр WooCommerceНужна точная логика по странеРаботает на сервере, не ломает оформлениеНужно поддерживать код
Плагин с правилами оплатыЕсть сложные условия без разработкиБыстро настраиваетсяМожет конфликтовать с checkout и доставкой
CSS/JS скрытиеТолько временный визуальный обходПросто внедритьНе решает задачу корректно, метод остаётся доступным

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

Ошибка 1. Используют неправильный ID шлюза. В WooCommerce ID метода оплаты не всегда совпадает с его названием в интерфейсе. Проверьте реальный идентификатор в коде плагина или через отладку массива $gateways.

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

Ошибка 3. Пишут код в основной теме. После обновления темы правило пропадёт. Используйте дочернюю тему или небольшой кастомный плагин.

Ошибка 4. Скрывают метод только на фронтенде. Это не ограничение оплаты, а косметика. Метод должен быть удалён из доступных шлюзов на сервере.

Ошибка 5. Не тестируют гостевой checkout. У авторизованного пользователя адрес может подтягиваться из профиля, а у гостя — нет. Это разные сценарии, и оба нужно проверить.

Как сделать правило безопаснее и проще в поддержке

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

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

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

×

AI-плагин

WPGPT
Сам создает статьи для вашего сайта WordPress

SEO и мета-теги

Парсинг конкурентов

Изображения

Комментарии

Подробнее