Наложенный платёж удобен покупателю и рискован магазину: товар едет к клиенту, а деньги — под вопросом, пока он не заберёт посылку. Для дешёвых и ходовых позиций риск терпимый, но для дорогих, хрупких или сделанных под заказ вещей многие магазины предпочитают предоплату. WooCommerce позволяет убрать «Наложенный платёж» из списка способов оплаты, если в корзине оказался хотя бы один такой товар.
Как это работает
Список способов оплаты на чекауте проходит через фильтр woocommerce_available_payment_gateways. Он получает массив доступных шлюзов, где ключ — идентификатор способа оплаты. У встроенного «Наложенного платежа» это cod. Удаляем ключ из массива — способ исчезает с чекаута. Код добавляется в functions.php дочерней темы.
Вариант 1: по списку товаров
add_filter( 'woocommerce_available_payment_gateways', 'shop_disable_cod_for_products' );
function shop_disable_cod_for_products( $gateways ) {
// В админке и там, где корзины ещё нет, ничего не трогаем
if ( is_admin() || ! WC()->cart || ! isset( $gateways['cod'] ) ) {
return $gateways;
}
// ID товаров, для которых наложенный платёж недоступен
$no_cod_products = array( 37, 40, 53 );
foreach ( WC()->cart->get_cart() as $item ) {
if ( in_array( $item['product_id'], $no_cod_products, true ) ) {
unset( $gateways['cod'] );
break; // достаточно одного совпадения
}
}
return $gateways;
}
Три момента, которые здесь важны. Проверка в начале защищает от ошибок: фильтр срабатывает не только на чекауте, но и в админке при ручном создании заказа, где объекта корзины может не быть. Проверка isset( $gateways['cod'] ) экономит цикл, если наложенный платёж и так выключен. А break останавливает перебор после первого совпадения — искать дальше незачем.
ID товара видно в админке в списке товаров при наведении на название, либо в адресной строке на странице редактирования.
Вариативные товары
У товара с вариациями два идентификатора: product_id — общий родительский, и variation_id — конкретной вариации. Код выше сравнивает родительский, то есть отключает наложенный платёж для всех вариаций товара сразу. Если нужно ограничить только одну вариацию, скажем, самую дорогую, сравнивайте $item['variation_id'] и указывайте в списке ID вариаций.
Вариант 2: по категории — удобнее в поддержке
Список ID в коде — это то, что придётся править при каждом новом товаре. Практичнее завести категорию, например «Без наложенного платежа», и относить к ней товары прямо из админки. Код при этом не меняется никогда:
add_filter( 'woocommerce_available_payment_gateways', 'shop_disable_cod_for_category' );
function shop_disable_cod_for_category( $gateways ) {
if ( is_admin() || ! WC()->cart || ! isset( $gateways['cod'] ) ) {
return $gateways;
}
foreach ( WC()->cart->get_cart() as $item ) {
// has_term принимает slug или ID категории; проверяем по родительскому товару
if ( has_term( 'bez-nalozhennogo-platezha', 'product_cat', $item['product_id'] ) ) {
unset( $gateways['cod'] );
break;
}
}
return $gateways;
}
Категория может быть скрытой от каталога — покупателю её видеть не обязательно. Тот же приём работает и с метками (product_tag) или классом доставки, если товары уже размечены таким образом: у класса доставки «Хрупкое» логично сразу отключать и наложенный платёж.
Другие условия
Фильтр не ограничен товарами — внутри доступна вся корзина, поэтому по той же схеме отключают наложенный платёж по сумме заказа (например, свыше 20 000 ₽), по выбранному способу доставки (курьером — можно, почтой — нет) или по региону покупателя. Логика та же: проверили условие, удалили ключ, вернули массив.
Идентификаторы других способов оплаты отличаются от cod и зависят от плагина. Посмотреть их можно в WooCommerce → Настройки → Платежи, либо один раз вывести в лог array_keys( $gateways ) внутри фильтра.
Классический и блочный чекаут
Хорошая новость для тех, кто перешёл на блочный чекаут: список способов оплаты и там формируется через тот же фильтр — блок запрашивает доступные способы с сервера, и woocommerce_available_payment_gateways отрабатывает на этом запросе. То есть в отличие от многих сниппетов для классического чекаута этот работает в обоих вариантах. Единственное, что стоит проверить после установки, — что после изменения состава корзины список способов на чекауте действительно обновляется.
Коротко
Отключение наложенного платежа для отдельных товаров — это один фильтр и один цикл по корзине. Для пары позиций хватит списка ID, для живого каталога заведите категорию или метку и управляйте всем из админки. Не забудьте защиту от контекстов без корзины и помните про разницу между родительским товаром и вариацией.
Частые вопросы
У встроенного наложенного платежа это cod. У других шлюзов — свои: смотрите в WooCommerce → Настройки → Платежи или один раз выведите array_keys( $gateways ) внутри фильтра.
Да. Блок запрашивает доступные способы оплаты с сервера, и фильтр woocommerce_available_payment_gateways отрабатывает на этом запросе — в отличие от многих шаблонных хуков классического чекаута.
Сравнивайте $item['variation_id'] вместо $item['product_id'] и указывайте в списке ID вариаций. Родительский product_id отключает наложку для всех вариаций сразу.
Да — заведите категорию или метку «Без наложенного платежа» и проверяйте её через has_term(). Тогда товары добавляются и убираются из админки, а код не меняется.
Источники
- 1.Cash on Delivery — документация WooCommercehttps://woocommerce.com/document/cash-on-delivery/
- 2.WooCommerce Hooks Reference — woocommerce_available_payment_gatewayshttps://woocommerce.github.io/code-reference/hooks/hooks.html
- 3.has_term — WordPress Developer Referencehttps://developer.wordpress.org/reference/functions/has_term/

