В WooCommerce часто нужно не просто показать список платежных методов, а отфильтровать его по правилам бизнеса: убрать оплату при самовывозе, скрыть наложенный платеж для дорогих заказов, оставить банковский перевод только для B2B-клиентов или отключить конкретный шлюз для части стран. Если этого не сделать, покупатель видит лишние варианты, а менеджер потом вручную исправляет заказы.
Ниже — рабочий способ без выдуманных API и без лишних плагинов: через стандартный фильтр WooCommerce и понятные условия. Подход подходит для большинства тем и не ломает оформление заказа, если не вмешиваться в шаблоны.
Когда проблема проявляется и что именно ломается
Сценарий обычно выглядит так: платежный шлюз установлен, активен, но его нужно показывать не всем. Например, cod должен работать только для локальной доставки, а bacs — только для юрлиц. Если оставить все как есть, WooCommerce продолжит отдавать клиенту весь набор доступных методов оплаты, который собрался на этапе расчета корзины.
Проверять проблему нужно не в админке, а на фронтенде, в реальном сценарии оформления заказа. Один и тот же магазин может показывать разные методы оплаты в зависимости от:
- способа доставки;
- страны и региона;
- суммы корзины;
- роли пользователя;
- наличия конкретных товаров в заказе;
- валюты, если магазин мультивалютный.
Диагностика перед правкой кода
Сначала убедитесь, что нужный шлюз вообще доступен WooCommerce. Если он не отображается даже без условий, проблема не в фильтрации, а в настройках самого плагина оплаты, валюте, географии или совместимости с доставкой.
- Откройте WooCommerce → Настройки → Платежи и проверьте, включен ли метод.
- Проверьте, не ограничен ли шлюз по стране в его собственных настройках.
- Посмотрите, не влияет ли на checkout сторонний плагин доставки или мультивалютности.
- Временно переключите тему на стандартную и отключите кеширование checkout-страниц, если методы оплаты ведут себя нестабильно.
Как отключить метод оплаты по условиям через фильтр WooCommerce
Самый надежный путь — использовать фильтр woocommerce_available_payment_gateways. Он позволяет отфильтровать массив доступных шлюзов перед выводом на checkout. Это штатный механизм WooCommerce, а не костыль через JS.
Добавлять код лучше в мини-плагин или в functions.php дочерней темы. Если правите тему, помните: при обновлении родительской темы изменения могут потеряться.
Пример: скрыть наложенный платеж при сумме заказа выше заданного порога
add_filter( 'woocommerce_available_payment_gateways', function( $gateways ) {
if ( is_admin() && ! wp_doing_ajax() ) {
return $gateways;
}
if ( ! WC()->cart ) {
return $gateways;
}
$threshold = 10000;
$cart_total = (float) WC()->cart->get_total( 'edit' );
if ( $cart_total > $threshold && isset( $gateways['cod'] ) ) {
unset( $gateways['cod'] );
}
return $gateways;
} );Здесь cod — стандартный ID метода наложенного платежа в WooCommerce. Если у вас другой шлюз, ID нужно взять из его кода или посмотреть в массиве доступных методов через отладку.
Пример: оставить банковский перевод только для определенной роли
add_filter( 'woocommerce_available_payment_gateways', function( $gateways ) {
if ( is_admin() && ! wp_doing_ajax() ) {
return $gateways;
}
if ( ! is_user_logged_in() ) {
return $gateways;
}
$user = wp_get_current_user();
if ( in_array( 'wholesale_customer', (array) $user->roles, true ) ) {
return $gateways;
}
if ( isset( $gateways['bacs'] ) ) {
unset( $gateways['bacs'] );
}
return $gateways;
} );Этот вариант полезен, если вы работаете с B2B-магазином и не хотите показывать банковский перевод всем подряд. Роль wholesale_customer здесь пример; у вас она может называться иначе.
Что выбрать: плагин, код или настройку шлюза
Если задача простая и шлюз сам умеет ограничения по стране или валюте, сначала используйте его настройки. Если нужно правило на уровне корзины или роли, без кода обычно не обойтись.
| Подход | Когда подходит | Минус |
|---|---|---|
| Настройки самого шлюза | Ограничение по стране, валюте, способу доставки | Не хватает гибкости |
Фильтр woocommerce_available_payment_gateways | Сложные условия: сумма, роль, товары, доставка | Нужно поддерживать код |
| Сторонний плагин для условий оплаты | Когда нет доступа к разработке | Дополнительная нагрузка и зависимость от плагина |
Если на сайте уже стоит плагин для чистки WooCommerce и удаления лишних дублей, например Clearfy Pro, проверьте, не скрывает ли он что-то на checkout косвенно через оптимизацию скриптов. Такое бывает реже, но при диагностике лучше исключить конфликт настроек.
Пошаговое внедрение без поломки checkout
Чтобы не сломать оформление заказа, действуйте по порядку.
- Сделайте резервную копию файлов или работайте в staging-копии сайта.
- Определите ID платежного метода, который нужно скрывать.
- Выберите условие: сумма, роль, страна, доставка, товары в корзине.
- Добавьте фильтр в мини-плагин или дочернюю тему.
- Проверьте checkout в обычном и инкогнито-режиме.
- Протестируйте сценарии с разными способами доставки и разной суммой корзины.
Если нужно скрывать метод оплаты по способу доставки
Это частый кейс для наложенного платежа. WooCommerce хранит выбранный способ доставки в сессии, и его можно использовать в условии.
add_filter( 'woocommerce_available_payment_gateways', function( $gateways ) {
if ( is_admin() && ! wp_doing_ajax() ) {
return $gateways;
}
if ( ! WC()->session ) {
return $gateways;
}
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_method = is_array( $chosen_methods ) ? reset( $chosen_methods ) : '';
if ( $chosen_method !== 'flat_rate:3' && isset( $gateways['cod'] ) ) {
unset( $gateways['cod'] );
}
return $gateways;
} );Здесь flat_rate:3 — пример идентификатора метода доставки. Его нужно взять из вашей конфигурации. Если ID указан неверно, правило просто не сработает.
Как проверить, что решение работает
Проверка должна быть не формальной, а по сценариям. Иначе легко пропустить ситуацию, когда метод оплаты исчез только в одном браузере или только для авторизованного пользователя.
- Откройте checkout как гость и как авторизованный пользователь.
- Соберите корзину ниже и выше пороговой суммы.
- Поменяйте способ доставки и убедитесь, что список платежей обновляется.
- Проверьте заказ из страны, для которой шлюз должен быть скрыт.
- Посмотрите, не остается ли старый метод оплаты в сохраненной сессии после возврата на checkout.
Если хотите быстро увидеть, какие шлюзы WooCommerce считает доступными, можно временно записать их в лог. Это удобно на staging-сайте.
add_filter( 'woocommerce_available_payment_gateways', function( $gateways ) {
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( 'Available gateways: ' . implode( ', ', array_keys( $gateways ) ) );
}
return $gateways;
} );После проверки не забудьте убрать отладочный лог, чтобы не засорять debug.log.
Частые ошибки и как их исправить
Метод оплаты не скрывается вообще
Обычно причина в неверном ID шлюза. В WooCommerce ID у платежей не всегда совпадает с названием, которое видит пользователь. Проверьте ключ массива $gateways через лог или временный var_dump на staging.
Метод пропадает у всех пользователей без исключения
Часто это происходит, если условие написано слишком жестко или срабатывает в админке. Обязательно оставляйте проверку is_admin() && ! wp_doing_ajax(), иначе можно сломать сохранение заказа в панели.
Checkout ведет себя нестабильно после установки кеш-плагина
Страницу оформления заказа нельзя кешировать как обычную. Проверьте исключения для /checkout/, /cart/ и /my-account/. Если кеш отдает старую сессию, список платежей будет выглядеть случайным.
Условие по доставке не срабатывает
Причина обычно в том, что выбранный метод доставки еще не записан в сессию в момент выполнения фильтра. Тогда нужно тестировать сценарий после обновления checkout AJAX-запросом, а не только при первой загрузке страницы.
Безопасность и производительность
Фильтр woocommerce_available_payment_gateways выполняется на checkout часто, поэтому код должен быть коротким и без тяжелых запросов к базе. Не делайте внутри фильтра сложные WP_Query, если можно обойтись данными сессии, роли пользователя или параметрами корзины.
Если правило зависит от метаданных товара, лучше заранее собрать нужные данные и минимизировать количество обращений к постам. Для больших магазинов это важнее, чем кажется: checkout и так нагружен AJAX-обновлениями.
Для изменений в продакшене безопаснее использовать дочернюю тему или мини-плагин. Так вы не потеряете правку при обновлении темы и сможете быстро отключить логику, если партнерский шлюз изменит ID или поведение.
Если задача выходит за рамки одного условия и нужно управлять десятками правил, имеет смысл вынести логику в отдельный плагин условий оплаты или в кастомный mu-plugin. Это проще сопровождать, чем разбрасывать код по шаблонам темы.