Наложенный платеж в WooCommerce часто включают «на всякий случай», а потом сталкиваются с типичной проблемой: способ оплаты виден там, где он не должен быть. Например, для хрупких товаров, дорогих заказов, самовывоза, отдельных регионов или заказов с цифровыми товарами. Если оставить всё как есть, менеджеры начинают вручную править заказы, а покупатели видят лишний способ оплаты и путаются на checkout.
Ниже — рабочая схема, как скрывать Cash on delivery точечно: по товарам, категориям, сумме заказа и зоне доставки. Без выдуманных хуков и без правки ядра WooCommerce.
Когда проблема действительно в способе оплаты
Сначала стоит убедиться, что дело не в теме, кэше или плагине доставки. В WooCommerce способ оплаты может исчезать по трем причинам: он отключен в настройках, его убирает сторонний плагин, или его фильтрует ваш код. Если COD пропадает только на части заказов, значит логика уже где-то есть, и её нужно найти.
Что проверить в админке и на фронтенде
- Включен ли
Cash on deliveryвWooCommerce → Настройки → Платежи. - Не ограничен ли он по способам доставки в настройках самого метода.
- Не влияет ли на checkout плагин кэширования, оптимизации или кастомной доставки.
- Появляется ли способ оплаты в тестовом заказе без купонов, без скидок и без сторонних плагинов.
Если COD исчезает только для части корзин, дальше уже имеет смысл смотреть на условия: товары, категории, регион, сумму заказа, выбранную зону доставки.
Какой подход выбрать: плагин, код или комбинация
Для точечной логики удобнее код. Плагин имеет смысл, если правил много и ими будут управлять менеджеры без доступа к теме. Но для одной-двух условий код обычно проще, прозрачнее и быстрее в поддержке.
| Подход | Когда подходит | Минус |
|---|---|---|
| Код через фильтр WooCommerce | Нужно скрывать COD по понятным условиям | Логику придется поддерживать в теме или мини-плагине |
| Плагин с правилами оплаты | Много исключений, нужен UI для менеджеров | Дополнительная зависимость и риск конфликта |
| Комбинация | Базовые правила в коде, редкие исключения в настройках | Нужно следить, чтобы правила не дублировались |
Решение через фильтр woocommerce_available_payment_gateways
Самый практичный способ — отфильтровать доступные методы оплаты перед выводом на checkout. WooCommerce передает массив шлюзов, и вы можете удалить из него cod, если заказ не проходит ваши условия.
Ниже пример, который скрывает наложенный платеж для отдельных категорий товаров и для заказов дороже заданной суммы.
<?php
add_filter( 'woocommerce_available_payment_gateways', 'wppro_hide_cod_for_specific_conditions' );
function wppro_hide_cod_for_specific_conditions( $gateways ) {
if ( is_admin() ) {
return $gateways;
}
if ( ! isset( $gateways['cod'] ) ) {
return $gateways;
}
$cart = WC()->cart;
if ( ! $cart ) {
return $gateways;
}
$hide_cod = false;
// Скрываем COD, если в корзине есть товары из этих категорий.
$blocked_categories = array( 'fragile', 'electronics' );
foreach ( $cart->get_cart() as $cart_item ) {
$product_id = $cart_item['product_id'];
if ( has_term( $blocked_categories, 'product_cat', $product_id ) ) {
$hide_cod = true;
break;
}
}
// Скрываем COD для заказов дороже 10000.
if ( $cart->get_total( 'edit' ) > 10000 ) {
$hide_cod = true;
}
if ( $hide_cod ) {
unset( $gateways['cod'] );
}
return $gateways;
}Этот вариант хорош тем, что логика читается прямо в коде. Но у него есть важная особенность: он смотрит на корзину в целом. Если вам нужно учитывать не только товары, но и регион доставки, лучше добавить проверку shipping zone.
Как скрыть COD по региону доставки
В WooCommerce регион обычно определяется через адрес доставки и зону доставки. На практике проще проверять страну, штат или индекс в зависимости от того, как у вас настроены зоны. Если магазин работает только по одной стране, часто достаточно проверки shipping_country.
<?php
add_filter( 'woocommerce_available_payment_gateways', 'wppro_hide_cod_for_regions' );
function wppro_hide_cod_for_regions( $gateways ) {
if ( is_admin() || ! isset( $gateways['cod'] ) || ! WC()->customer ) {
return $gateways;
}
$blocked_countries = array( 'UA', 'KZ' );
$shipping_country = WC()->customer->get_shipping_country();
if ( $shipping_country && in_array( $shipping_country, $blocked_countries, true ) ) {
unset( $gateways['cod'] );
}
return $gateways;
}Если у вас доставка часто меняется на checkout через AJAX, проверяйте поведение именно после выбора адреса. WooCommerce обновляет доступные платежи динамически, и фильтр должен отрабатывать на каждом пересчете.
Как связать оплату с конкретными товарами без лишней логики
Иногда нужно не просто скрыть COD для категории, а запретить его для конкретных товаров. Это полезно, если в магазине есть товары с предоплатой, крупногабаритные позиции или товары под заказ. В таком случае лучше проверять ID товаров, а не категорию.
<?php
add_filter( 'woocommerce_available_payment_gateways', 'wppro_hide_cod_for_products' );
function wppro_hide_cod_for_products( $gateways ) {
if ( is_admin() || ! isset( $gateways['cod'] ) || ! WC()->cart ) {
return $gateways;
}
$restricted_products = array( 123, 456, 789 );
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( in_array( (int) $cart_item['product_id'], $restricted_products, true ) ) {
unset( $gateways['cod'] );
break;
}
}
return $gateways;
}Если товар вариативный, иногда нужно проверять не только product_id, но и variation_id. Иначе COD может остаться доступным для вариации, которую вы считали запрещенной.
Пошаговая настройка без сюрпризов
- Создайте мини-плагин или добавьте код в
functions.phpдочерней темы. Для боевого сайта мини-плагин надежнее. - Определите точное условие: категория, список товаров, сумма корзины, страна доставки.
- Добавьте фильтр
woocommerce_available_payment_gatewaysи уберитеcodчерезunset(). - Проверьте поведение на обычном товаре, на вариативном товаре и на заказе с несколькими позициями.
- Очистите кэш страницы, если checkout кэшируется на уровне плагина или CDN.
Как проверить, что решение сработало
Проверка должна быть не только визуальной. На checkout способ оплаты может скрываться из-за фронтенда, но оставаться доступным в API или в повторном AJAX-обновлении.
- Добавьте в корзину товар из запрещенной категории и убедитесь, что COD исчез.
- Смените адрес доставки на разрешенный регион и проверьте, что способ оплаты возвращается, если это предусмотрено логикой.
- Откройте checkout в режиме инкогнито, чтобы исключить влияние сессии и кэша браузера.
- Проверьте оформление заказа до и после обновления корзины, особенно если у вас включен AJAX update checkout.
Если COD не исчезает, временно добавьте error_log() или используйте WC_Logger, чтобы понять, какие условия реально срабатывают.
<?php
$logger = wc_get_logger();
$logger->info( 'COD check: country=' . WC()->customer->get_shipping_country(), array( 'source' => 'cod-rules' ) );Частые ошибки и как их исправить
Проверяют только корзину, но не адрес доставки
Если фильтр завязан только на товары, COD будет виден в неподходящих регионах. Добавьте проверку страны или зоны доставки, иначе логика останется неполной.
Пишут код в родительскую тему
После обновления темы правило исчезнет. Для таких задач лучше использовать дочернюю тему или мини-плагин.
Забывают про вариации
Если ограничение должно работать на конкретную вариацию, проверка только product_id не поможет. Нужна отдельная логика для variation_id.
Кэшируют checkout
Если страница оформления заказа попадает под агрессивный кэш, способы оплаты могут отображаться некорректно. Checkout и корзину нужно исключать из кэширования на уровне плагина и CDN.
Отключают COD слишком поздно
Если фильтр срабатывает не на woocommerce_available_payment_gateways, а после рендера формы, пользователь уже увидит лишний вариант. Убирать шлюз нужно до вывода списка методов оплаты.
Безопасность и поддержка кода
Не вставляйте такие правила в случайные сниппеты без контроля версий. Для магазина безопаснее хранить код в отдельном мини-плагине, чтобы его можно было быстро отключить и отладить. Если правил становится много, имеет смысл вынести их в конфигурационный массив и документировать, почему конкретный товар или регион исключен.
Если вам нужно не только скрывать способы оплаты, но и чистить лишнюю логику на сайте, полезно посмотреть в сторону Clearfy Pro: он помогает убрать часть технического мусора и держать сайт в более предсказуемом состоянии. Но саму бизнес-логику оплаты всё равно лучше оставлять в коде, а не пытаться спрятать в общих настройках оптимизации.
Если у вас уже есть несколько правил для доставки и оплаты, держите их в одном месте и не дублируйте в разных плагинах. Иначе через месяц будет сложно понять, кто именно убрал COD: тема, плагин доставки или кастомный фильтр.