Сценарий типичный: до определённой суммы вы хотите показывать только онлайн-оплату, а при крупном заказе — банковский перевод или оплату по счёту. В WooCommerce это лучше делать не через правку шаблонов, а через фильтр woocommerce_available_payment_gateways. Тогда логика остаётся в одном месте и не ломает оформление checkout.
Ниже разберём, как диагностировать проблему, выбрать подход и проверить, что ограничения реально работают на витрине и в админке заказов.
Когда это нужно и что именно ломается
Чаще всего задача выглядит так:
- при сумме корзины меньше 3000 ₽ нужно оставить только карту и онлайн-эквайринг;
- при сумме больше 3000 ₽ нужно скрыть наложенный платёж;
- для заказов от определённой суммы нужен только безналичный расчёт;
- для конкретной страны или валюты доступен не весь список способов оплаты.
Проблема обычно не в самих платёжных модулях, а в том, что условия проверяются слишком поздно или не учитывают актуальную сумму корзины. Если логика написана в шаблоне checkout, она часто конфликтует с обновлениями темы и плагинов. Если условие завязано на $_POST или на старые значения сессии, список методов может не обновляться после изменения количества товаров.
Диагностика: что проверить до внесения кода
Перед правкой кода проверьте несколько вещей. Это экономит время, когда кажется, что фильтр «не работает».
1. Какие способы оплаты вообще активны
Зайдите в WooCommerce → Настройки → Платежи и убедитесь, что нужные методы включены. Если метод выключен здесь, фильтр его не вернёт.
2. Как считается сумма корзины
Для ограничения по сумме важно понимать, что брать за основу: subtotal, сумму после купонов, сумму с налогами или без. В WooCommerce в корзине есть несколько значений, и они могут отличаться. Если вы сравниваете не ту величину, условие будет срабатывать «не там».
3. Нет ли кеширования checkout
Страница оформления заказа не должна кешироваться как обычная страница. Если на сайте агрессивный кеш, список способов оплаты может не обновляться после изменения корзины. Это особенно заметно, когда условие зависит от суммы, а не от роли пользователя.
4. Не вмешивается ли другой плагин
Плагины доставки, подписок, B2B-ценообразования и мультивалютности тоже могут менять доступные способы оплаты. Если логика не совпадает с ожиданиями, временно отключите сторонние плагины на тестовом стенде и проверьте базовый сценарий.
Рабочий способ: фильтр доступных способов оплаты
Самый надёжный вариант — добавить код в мини-плагин или в functions.php дочерней темы. Для боевого проекта мини-плагин предпочтительнее: так логика не пропадёт при смене темы.
<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpmentor_limit_payment_gateways_by_cart_total' );
function wpmentor_limit_payment_gateways_by_cart_total( $available_gateways ) {
if ( is_admin() ) {
return $available_gateways;
}
if ( ! function_exists( 'WC' ) || ! WC()->cart ) {
return $available_gateways;
}
$cart_total = (float) WC()->cart->get_cart_contents_total();
// Пример: если сумма корзины меньше 3000, скрываем оплату по счёту.
if ( $cart_total < 3000 ) {
unset( $available_gateways['bacs'] );
}
// Пример: если сумма корзины 3000 и выше, скрываем наложенный платёж.
if ( $cart_total >= 3000 ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
}
Здесь используются стандартные идентификаторы методов оплаты WooCommerce: bacs для банковского перевода, cod для наложенного платежа. У ваших платёжных плагинов ID может быть другим. Его нужно смотреть в настройках плагина или в массиве доступных шлюзов.
Если нужно учитывать сумму с налогами и доставкой
Иногда ограничение должно работать не по сумме товаров, а по итоговой сумме заказа. Тогда логика меняется: вместо суммы содержимого корзины берите сумму с учётом доставки и налогов. Но здесь важно не путать значения, потому что на этапе выбора оплаты доставка ещё может быть не выбрана.
<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpmentor_limit_gateways_by_order_total' );
function wpmentor_limit_gateways_by_order_total( $available_gateways ) {
if ( is_admin() || ! function_exists( 'WC' ) || ! WC()->cart ) {
return $available_gateways;
}
$total = (float) WC()->cart->total;
if ( $total < 5000 ) {
unset( $available_gateways['bacs'] );
}
return $available_gateways;
}
Этот вариант подходит не всегда. На checkout итог может меняться после выбора доставки, поэтому для точных сценариев лучше тестировать несколько комбинаций корзины и адреса.
Пошаговая настройка без лишней магии
- Определите правило: по сумме товаров, по итоговой сумме, по стране, по роли покупателя или по категории товаров.
- Найдите ID платёжных методов, которые нужно скрывать или оставлять.
- Добавьте фильтр
woocommerce_available_payment_gatewaysв мини-плагин или дочернюю тему. - Проверьте, что код не выполняется в админке и не ломает AJAX-обновление checkout.
- Протестируйте несколько корзин: ниже порога, на пороге и выше порога.
Как проверить, что решение сработало
Проверка должна быть не визуальной «на глаз», а по сценариям. Откройте checkout в режиме инкогнито и соберите корзину с разной суммой.
- Сумма ниже порога: нужный метод оплаты скрыт, остальные доступны.
- Сумма равна порогу: правило отрабатывает именно так, как вы задумали, без пограничных ошибок.
- Сумма выше порога: запрещённый метод исчезает после обновления checkout.
- Изменение количества товаров в корзине пересчитывает список методов без ручной перезагрузки страницы.
Если хотите быстро увидеть, что реально приходит в фильтр, временно добавьте логирование:
<?php
add_filter( 'woocommerce_available_payment_gateways', function( $available_gateways ) {
if ( function_exists( 'WC' ) && WC()->cart ) {
error_log( 'Cart total: ' . WC()->cart->get_cart_contents_total() );
error_log( 'Gateways: ' . implode( ',', array_keys( $available_gateways ) ) );
}
return $available_gateways;
} );
После проверки не забудьте убрать логирование, чтобы не засорять error log на продакшене.
Плагин, код или компромисс: что выбрать
| Подход | Когда подходит | Минусы |
|---|---|---|
| Код через фильтр | Нужна точная логика и контроль над условиями | Требует тестирования и поддержки |
| Плагин для управления checkout | Нужно быстро собрать правило без разработки | Может добавить лишний интерфейс и зависимость от обновлений |
| Правка шаблона checkout | Редкий случай с глубокой кастомизацией | Хрупко при обновлениях темы и WooCommerce |
Если задача простая и однотипная, код обычно надёжнее. Если правил много и ими должен управлять менеджер без доступа к коду, тогда уже имеет смысл смотреть в сторону плагина. Для общих настроек сайта и удаления лишнего мусора в WooCommerce иногда помогает Clearfy Pro, но саму логику ограничения способов оплаты он не заменяет.
Частые ошибки и как их исправить
Скрывают не тот метод оплаты
У платёжного шлюза может быть свой ID, не совпадающий с названием в интерфейсе. Проверьте ключ массива в $available_gateways. Если ID неверный, unset() ничего не изменит.
Используют сумму без учёта нужного сценария
Ошибка возникает, когда сравнивают get_cart_contents_total(), а бизнес-правило требует итоговую сумму с доставкой. Сначала зафиксируйте, что именно должно считаться, потом выбирайте источник данных.
Код добавили в родительскую тему
После обновления темы правило исчезнет. Для кастомной логики используйте дочернюю тему или мини-плагин.
Не учитывают AJAX-обновление checkout
Если список методов оплаты не меняется после изменения корзины, проверьте, не кэшируется ли checkout и не ломает ли страницу другой скрипт. Иногда проблема не в PHP-коде, а в фронтенд-оптимизации.
Безопасность и производительность
Фильтр woocommerce_available_payment_gateways выполняется на checkout, поэтому не стоит нагружать его тяжёлыми запросами к базе или внешним API. Если правило зависит от сложных данных, заранее кэшируйте результат в пользовательской сессии или в мета-данных заказа, а не пересчитывайте всё на каждом рендере.
Не выводите отладку в HTML на боевом сайте. Для диагностики используйте error_log() или временно включённый лог на тестовом стенде. И не забывайте, что любые изменения платёжной логики нужно проверять после обновлений WooCommerce и платёжных плагинов: они часто меняют поведение checkout без изменения вашего кода.
Если нужна более сложная логика — например, скрывать методы оплаты по сумме, стране и категории товара одновременно — лучше вынести правила в отдельный класс или мини-плагин. Так проще тестировать и не превращать functions.php в набор разрозненных условий.