Сценарий знакомый: на странице оформления заказа клиент выбирает доставку, а вместе с ней в блоке оплаты остаются методы, которые в этой ситуации использовать нельзя. В итоге появляются лишние вопросы, ошибки на checkout и заказы, которые потом приходится вручную исправлять.
Задача здесь не в том, чтобы просто «спрятать оплату», а в том, чтобы связать доступность платежных методов с конкретной доставкой. В WooCommerce это можно сделать без тяжёлых плагинов, если у вас понятная логика: например, наложенный платёж доступен только при самовывозе, а банковский перевод — только для курьерской доставки.
Когда это действительно нужно
Чаще всего проблема возникает в магазинах с несколькими сценариями доставки:
- самовывоз и курьерская доставка;
- доставка в пункт выдачи и доставка транспортной компанией;
- отдельные способы для крупногабаритных или хрупких товаров;
- регионы, где часть оплат технически недоступна.
Если не ограничивать оплату, покупатель видит лишние варианты и может выбрать тот, который не проходит по правилам вашего склада, курьера или платёжного провайдера.
Диагностика проблемы перед правкой кода
Сначала проверьте, что именно у вас считается «доступной доставкой». В WooCommerce это не всегда один метод: иногда выбранная доставка хранится как комбинация идентификатора метода и instance ID, особенно если у вас несколько зон доставки.
Откройте оформление заказа и посмотрите, какие методы доставки реально доступны в нужной зоне. Затем проверьте, какие способы оплаты показываются сейчас. Если логика зависит от региона, суммы корзины или типа товара, сначала убедитесь, что сама доставка в WooCommerce настроена корректно. Иначе вы будете лечить не причину, а симптом.
Что проверить в админке
- Зоны доставки и порядок их обработки.
- Instance ID у методов доставки, если в зоне несколько одинаковых методов.
- Какие способы оплаты включены глобально.
- Нет ли стороннего плагина, который уже меняет список оплат на checkout.
Рабочий способ через фильтр WooCommerce
Для такой задачи обычно достаточно фильтра woocommerce_available_payment_gateways. Он позволяет отфильтровать список доступных платёжных шлюзов уже после того, как WooCommerce определил текущую корзину и доставку.
Ниже пример, который скрывает cod и bacs, если выбран не тот способ доставки. Идентификаторы нужно заменить на свои: у вас они могут отличаться в зависимости от настроек и плагинов.
<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpbono_filter_payment_gateways_by_shipping' );
function wpbono_filter_payment_gateways_by_shipping( $gateways ) {
if ( is_admin() ) {
return $gateways;
}
if ( ! function_exists( 'WC' ) || ! WC()->cart ) {
return $gateways;
}
$chosen_methods = WC()->session ? WC()->session->get( 'chosen_shipping_methods' ) : array();
$chosen_shipping = isset( $chosen_methods[0] ) ? $chosen_methods[0] : '';
if ( ! $chosen_shipping ) {
return $gateways;
}
// Пример: local_pickup:3 — самовывоз с instance ID 3.
// Замените на свои значения из настроек доставки.
$pickup_methods = array( 'local_pickup:3' );
if ( in_array( $chosen_shipping, $pickup_methods, true ) ) {
unset( $gateways['bacs'] ); // банковский перевод
} else {
unset( $gateways['cod'] ); // наложенный платёж
}
return $gateways;
}
Этот вариант удобен тем, что не трогает шаблоны checkout и работает на уровне логики WooCommerce. Если у вас несколько условий, их можно расширить: по зоне доставки, по сумме корзины, по категории товара или по тегу.
Если нужно учитывать не только доставку, но и состав корзины
Иногда одного способа доставки мало. Например, наложенный платёж разрешён только для товаров без предзаказа, а оплата при получении запрещена для цифровых товаров или товаров под заказ. Тогда лучше проверять и доставку, и содержимое корзины.
<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpbono_disable_gateways_for_cart_rules' );
function wpbono_disable_gateways_for_cart_rules( $gateways ) {
if ( is_admin() || ! function_exists( 'WC' ) || ! WC()->cart ) {
return $gateways;
}
$has_virtual = false;
foreach ( WC()->cart->get_cart() as $item ) {
if ( ! empty( $item['data'] ) && $item['data']->is_virtual() ) {
$has_virtual = true;
break;
}
}
if ( $has_virtual ) {
unset( $gateways['cod'] );
}
return $gateways;
}
Такой подход полезен, если доставка сама по себе не отражает все ограничения. Но не смешивайте в одном фильтре слишком много правил без структуры: через месяц это будет трудно сопровождать.
Плагин, код или гибридный вариант
Если у вас магазин без разработчика в штате, иногда проще использовать плагин с условиями для checkout. Но для точечной логики код обычно надёжнее и прозрачнее: вы контролируете, что именно скрывается и при каких условиях.
| Подход | Когда подходит | Минус |
|---|---|---|
| Код через фильтр | Нужны 1–3 понятных правила | Нужно аккуратно поддерживать идентификаторы методов |
| Плагин условий checkout | Правил много, их меняет менеджер | Лишняя нагрузка и риск конфликтов |
| Гибрид | Часть логики в коде, часть — в настройках | Важно не дублировать правила |
Если у вас уже стоит набор инструментов для оптимизации и очистки сайта, например Clearfy Pro, это не решает задачу оплаты напрямую, но помогает держать проект без лишнего мусора и конфликтных скриптов. Для checkout это важно: чем меньше сторонней логики вмешивается в оформление заказа, тем проще отлаживать поведение.
Пошаговое внедрение без поломки checkout
- Скопируйте код в дочернюю тему или в собственный мини-плагин.
- Замените идентификаторы способов оплаты на реальные:
cod,bacs,stripeи т.д. - Проверьте instance ID у способов доставки, если логика завязана на конкретную зону.
- Очистите кэш страницы оформления заказа, если он используется.
- Протестируйте сценарии в разных зонах доставки и с разными товарами.
Как проверить, что решение сработало
Проверка должна быть не одной, а по нескольким сценариям. Иначе можно случайно скрыть оплату только в одном случае, а в другом оставить старое поведение.
- Выберите доставку, для которой метод оплаты должен скрываться, и убедитесь, что он исчез из списка.
- Смените доставку на разрешённую и проверьте, что способ оплаты снова появился.
- Проверьте оформление заказа в режиме гостя и под авторизованным пользователем.
- Сделайте тестовый заказ с разными товарами: обычными, виртуальными, предзаказными, если они есть.
- Посмотрите, не ломается ли пересчёт доставки при смене адреса.
Если метод оплаты скрывается только после обновления страницы, а не сразу при смене доставки, это уже вопрос к JavaScript-обновлению checkout или к конфликту темы/плагина. В таком случае сначала проверьте консоль браузера и отключите сторонние скрипты, которые вмешиваются в checkout.
Частые ошибки и как их исправить
Неправильный идентификатор метода доставки
Самая частая ошибка — сравнивают не тот ID. В WooCommerce у доставки может быть не просто local_pickup, а local_pickup:3. Если instance ID не совпадает, условие никогда не сработает.
Проверка только по первой доставке
В корзине с несколькими пакетами доставки может быть несколько значений в chosen_shipping_methods. Если у вас сложная логика, одного индекса [0] может быть недостаточно. Для простых магазинов этого хватает, но в мультипакетных сценариях нужно смотреть структуру данных внимательнее.
Скрытие оплаты в админке
Если не ограничить выполнение кода, можно случайно повлиять на админские экраны или AJAX-запросы. Поэтому в примерах выше есть проверка is_admin() и контроль наличия WC().
Конфликт с плагином доставки или оплаты
Некоторые плагины сами фильтруют доступные шлюзы. Если ваш код не работает, временно отключите сторонние плагины и проверьте базовый сценарий. Так вы поймёте, кто именно меняет список оплат последним.
Безопасность и производительность
Для такой задачи не нужен тяжёлый плагин, если правило однотипное и понятное. Код в дочерней теме или мини-плагине проще контролировать, а значит меньше риск, что после обновления темы логика сломается.
Не вставляйте этот код в шаблон checkout напрямую. Лучше держать его отдельно, чтобы можно было быстро отключить и протестировать без редактирования вёрстки. Если правил становится много, выносите их в отдельные функции с понятными именами и комментариями.
И ещё один практический момент: не полагайтесь только на визуальную проверку. После внедрения откройте заказ в админке и убедитесь, что клиент не может оформить оплату через запрещённый шлюз в неподходящей зоне доставки. Именно это и есть конечная проверка, а не просто исчезновение кнопки на странице.