Как отключить оплату наложенным платежом в WooCommerce для отдельных товаров и регионов

Наложенный платеж в 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 может остаться доступным для вариации, которую вы считали запрещенной.

Пошаговая настройка без сюрпризов

  1. Создайте мини-плагин или добавьте код в functions.php дочерней темы. Для боевого сайта мини-плагин надежнее.
  2. Определите точное условие: категория, список товаров, сумма корзины, страна доставки.
  3. Добавьте фильтр woocommerce_available_payment_gateways и уберите cod через unset().
  4. Проверьте поведение на обычном товаре, на вариативном товаре и на заказе с несколькими позициями.
  5. Очистите кэш страницы, если 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: тема, плагин доставки или кастомный фильтр.

Как найти и убрать дубли архивных страниц в WordPress
12.09.2026
Оптимизация базы данных WordPress: лучшие практики и решения
24.11.2025
Удаление пустых HTML-тегов в WordPress: эффективное решение без ущерба SEO
31.01.2026
Как удалить или изменить атрибуты изображений в WordPress без плагинов
31.03.2026
Как использовать WP-Cron для автоматизации задач на сайте WordPress
05.03.2026