Сценарий типичный: у вас есть самовывоз, курьерская доставка и, например, постамат, но не все способы оплаты должны быть доступны для каждого варианта доставки. Самая частая задача — убрать наложенный платёж для самовывоза, отключить банковский перевод для экспресс-доставки или наоборот оставить только онлайн-оплату там, где это требуется по процессу обработки заказов.
В WooCommerce это решается без тяжёлых плагинов: через фильтр woocommerce_available_payment_gateways. Но перед тем как лезть в код, полезно понять, где именно ломается логика и как проверить, что вы отключаете нужный метод, а не случайно режете оплату на всём сайте.
Когда проблема проявляется и что именно нужно проверить
Обычно ошибка выглядит так: клиент выбирает доставку, а список способов оплаты не меняется. Либо наоборот — нужный способ оплаты пропадает везде, хотя должен исчезать только при конкретной доставке. Ещё один вариант — после обновления корзины WooCommerce показывает старый набор методов, потому что условие завязано не на тот объект или не на тот ID доставки.
Что проверить в первую очередь
- точный ID способа доставки в WooCommerce, а не его название в интерфейсе;
- какой метод доставки реально выбран в сессии на странице оформления заказа;
- не конфликтует ли логика с плагинами кэширования, мини-корзиной или кастомным checkout;
- не отключён ли нужный платёжный шлюз в настройках самого WooCommerce;
- не используется ли несколько зон доставки с одинаковыми названиями методов.
Самая частая ошибка здесь — ориентироваться на текст вроде «Курьер» или «Самовывоз». Для кода нужен стабильный идентификатор, например flat_rate:3 или local_pickup:1. Номер после двоеточия зависит от конкретной настройки метода в зоне доставки.
Как отключить платёжный метод по выбранной доставке
Ниже рабочий пример для файла functions.php дочерней темы или для собственного мини-плагина. Логика простая: если выбран самовывоз, убираем, например, наложенный платёж. Если выбрана курьерская доставка, можно скрыть банковский перевод.
add_filter('woocommerce_available_payment_gateways', 'wpshab_disable_gateways_by_shipping_method');
function wpshab_disable_gateways_by_shipping_method($gateways) {
if (is_admin() && !defined('DOING_AJAX')) {
return $gateways;
}
if (!function_exists('WC') || !WC()->session) {
return $gateways;
}
$chosen_methods = WC()->session->get('chosen_shipping_methods');
$chosen_shipping = is_array($chosen_methods) && !empty($chosen_methods) ? $chosen_methods[0] : '';
if ($chosen_shipping === 'local_pickup:1') {
unset($gateways['cod']);
}
if ($chosen_shipping === 'flat_rate:3') {
unset($gateways['bacs']);
}
return $gateways;
}Что важно в этом коде:
cod— это стандартный ID наложенного платежа в WooCommerce;bacs— стандартный ID банковского перевода;local_pickup:1иflat_rate:3нужно заменить на свои реальные значения;- проверка
is_admin() && !defined('DOING_AJAX')нужна, чтобы не ломать админку и не вмешиваться в лишние запросы.
Как узнать нужный ID доставки
Откройте настройки зоны доставки в админке WooCommerce и посмотрите, какие методы добавлены. Сам ID в интерфейсе напрямую не всегда виден, поэтому на практике проще временно вывести выбранный метод в лог или посмотреть значение в сессии. Для отладки можно использовать такой безопасный вариант:
add_action('woocommerce_checkout_update_order_review', function($post_data) {
parse_str($post_data, $data);
if (!empty($data['shipping_method'][0])) {
error_log('Chosen shipping method: ' . sanitize_text_field($data['shipping_method'][0]));
}
});После этого откройте страницу оформления заказа, переключите доставку и проверьте debug.log. Если логирование у вас не включено, временно активируйте WP_DEBUG и WP_DEBUG_LOG в wp-config.php.
Если нужен более гибкий сценарий: сравнение подходов
Иногда достаточно одного условия, а иногда логика зависит от нескольких факторов: зоны доставки, суммы заказа, страны, наличия товара на складе. В таком случае полезно сравнить варианты до внедрения.
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Код через фильтр | Нужно точечно скрывать оплату по доставке | Быстро, прозрачно, без лишних зависимостей | Нужно поддерживать код и знать ID методов |
| Плагин для условной логики | Много правил и нет желания писать код | Удобный интерфейс, меньше ручной разработки | Дополнительная нагрузка, риск конфликтов, не всегда есть нужная гранулярность |
| Кастомная логика в теме | Правило уникальное и завязано на бизнес-процесс | Полный контроль | Нужно тестировать после обновлений темы |
Если у вас уже есть набор технических правок в теме, лучше вынести это в отдельный мини-плагин. Тогда правило не исчезнет при смене темы и его проще отключить на время диагностики.
Пошаговое внедрение без сюрпризов
- Скопируйте код в дочернюю тему или в собственный плагин.
- Замените
local_pickup:1иflat_rate:3на свои реальные ID. - Проверьте, что нужные платёжные шлюзы включены в WooCommerce → Настройки → Платежи.
- Очистите кэш сайта и кэш браузера, если используется кэширование checkout-страницы.
- Откройте оформление заказа в приватном окне и переключите способы доставки.
- Проверьте, что список оплат меняется без перезагрузки страницы или после стандартного обновления блока оформления заказа.
Более безопасный вариант для мини-плагина
Если не хотите держать код в functions.php, создайте отдельный файл плагина. Это удобнее для сопровождения и проще отключается при конфликте.
<?php
/**
* Plugin Name: Shipping Payment Rules
*/
add_filter('woocommerce_available_payment_gateways', function($gateways) {
if (is_admin() && !defined('DOING_AJAX')) {
return $gateways;
}
if (!function_exists('WC') || !WC()->session) {
return $gateways;
}
$chosen_methods = WC()->session->get('chosen_shipping_methods');
$chosen_shipping = is_array($chosen_methods) && !empty($chosen_methods) ? $chosen_methods[0] : '';
if ($chosen_shipping === 'local_pickup:1') {
unset($gateways['cod']);
}
return $gateways;
});Как проверить, что решение сработало
Проверка должна быть не визуальной «вроде исчезло», а по сценариям. Иначе легко пропустить ситуацию, когда правило работает только для одной зоны доставки или только на уже заполненной корзине.
- выберите доставку, для которой платёж должен скрываться, и убедитесь, что метод исчез из списка;
- смените доставку на разрешающую — способ оплаты должен вернуться;
- проверьте гостевой checkout и checkout авторизованного пользователя;
- протестируйте заказ с разными адресами доставки, если у вас несколько зон;
- посмотрите, не появляется ли ошибка в логах PHP или WooCommerce.
Если у вас включён кэш на страницах магазина, убедитесь, что checkout и корзина исключены из кэширования. Иначе вы можете видеть старый набор оплат, хотя код уже работает правильно.
Частые ошибки и как их исправить
Используют название доставки вместо ID
Название можно поменять в админке, а ID — нет. Если условие написано по тексту, оно быстро ломается после редактирования метода доставки.
Проверяют не тот шлюз оплаты
В WooCommerce ID платёжных методов стандартные, но у сторонних шлюзов они могут отличаться. Перед удалением шлюза из массива посмотрите его ключ в настройках или в коде плагина.
Не учитывают AJAX-обновление checkout
На странице оформления заказа WooCommerce часто обновляет блоки через AJAX. Если логика завязана на устаревшее значение сессии или на неправильный хук, список оплат не меняется сразу.
Ломают админку или письма
Если не ограничить код фронтендом, можно случайно вмешаться в админские запросы и фоновые операции. Проверка is_admin() с исключением AJAX обычно закрывает эту проблему.
Оставляют код в родительской теме
После обновления темы правка исчезнет. Для таких задач лучше использовать дочернюю тему или отдельный плагин.
Что учесть для безопасности и производительности
Сам фильтр лёгкий, но проблемы обычно появляются не в нём, а вокруг него. Не добавляйте лишние запросы к базе на каждом рендере checkout, если можно обойтись данными сессии. Не храните правила в жёстко зашитом HTML или в настройках, которые потом трудно валидировать.
Если правил много, держите их в одном месте и документируйте: какой ID доставки скрывает какой платёж, при каких условиях и кто это поддерживает. Это экономит время, когда через полгода нужно добавить ещё один способ доставки или отключить оплату для конкретной страны.
Если вам нужно не только скрывать оплату, но и чистить лишние технические сущности сайта, иногда удобно дополнять рабочий набор инструментов плагином вроде Clearfy Pro: он помогает убрать часть дублей и мусора в админке, но саму бизнес-логику оплаты всё равно лучше держать в коде, а не в «магии» плагинов. Ссылка на продукт: Clearfy Pro.