Сценарий простой и довольно частый: товар еще можно купить, но вы не хотите принимать, например, оплату при получении или банковский перевод, если на складе осталась последняя единица. В WooCommerce это лучше решать кодом, а не ручным переключением методов оплаты в каждом заказе.
Ниже разберем рабочий вариант: по порогу остатка товара скрываем выбранный способ оплаты на этапе оформления заказа. Подход подходит для простых товаров и вариаций, если остаток учитывается в карточке товара.
Когда это действительно нужно
Такое правило полезно не только для «последнего товара на складе». На практике его используют, когда:
- нужно убрать оплату при получении для дефицитных позиций;
- банк или платежный агрегатор не должен принимать заказы на товары с низким остатком;
- для последних единиц нужен только предоплатный сценарий;
- часть способов оплаты зависит от риска отмены или ручной обработки заказа.
Если у вас правило завязано не на остаток, а на категорию, сумму корзины или страну доставки, логика будет похожей, но условие в коде нужно менять отдельно.
Диагностика проблемы: что проверить до внедрения
Прежде чем вносить код, проверьте базовые настройки WooCommerce. Иначе можно долго искать ошибку там, где ее нет.
Проверьте учет остатков
В карточке товара должен быть включен учет склада. Если остаток не ведется, WooCommerce не сможет надежно отдать число доступных единиц.
Для простого товара это обычно выглядит так: Товар → Запасы → Управление запасами. Для вариаций — у каждой вариации отдельно.
Проверьте, какой способ оплаты нужно скрывать
В WooCommerce ID метода оплаты не всегда совпадает с его названием в интерфейсе. Например, у «Оплата при доставке» часто используется ID cod, у банковского перевода — bacs, у чеков — cheque. Если вы не уверены, сначала посмотрите список активных методов в настройках платежей или временно выведите массив доступных способов в лог.
Проверьте, не вмешивается ли плагин доставки или оплаты
Некоторые платежные плагины сами скрывают методы в зависимости от страны, суммы корзины или статуса заказа. Если правило не срабатывает, отключите конфликтующие плагины на тестовой копии и проверьте поведение еще раз.
Решение через фильтр WooCommerce
Самый практичный вариант — использовать фильтр woocommerce_available_payment_gateways. Он позволяет убрать ненужный способ оплаты уже на странице оформления заказа.
Код лучше добавить в мини-плагин или в functions.php дочерней темы. Для продакшена мини-плагин надежнее: обновление темы не затрет правку.
<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpfront_hide_payment_gateway_for_low_stock' );
function wpfront_hide_payment_gateway_for_low_stock( $gateways ) {
if ( is_admin() ) {
return $gateways;
}
if ( ! function_exists( 'WC' ) || ! WC()->cart ) {
return $gateways;
}
$threshold = 3; // Порог остатка
$target_gateway_id = 'cod'; // Например, оплата при получении
$lowest_stock = null;
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( empty( $cart_item['data'] ) || ! is_a( $cart_item['data'], 'WC_Product' ) ) {
continue;
}
$product = $cart_item['data'];
if ( ! $product->managing_stock() ) {
continue;
}
$stock_quantity = $product->get_stock_quantity();
if ( $stock_quantity === null ) {
continue;
}
if ( $lowest_stock === null || $stock_quantity < $lowest_stock ) {
$lowest_stock = $stock_quantity;
}
}
if ( $lowest_stock !== null && $lowest_stock <= $threshold && isset( $gateways[ $target_gateway_id ] ) ) {
unset( $gateways[ $target_gateway_id ] );
}
return $gateways;
}Что делает этот код:
- проходит по товарам в корзине;
- ищет минимальный остаток среди товаров, где включен учет склада;
- если остаток меньше или равен порогу, убирает указанный способ оплаты;
- не трогает админку и не ломает оформление заказа в бэкенде.
Если нужно скрывать оплату только для конкретного товара
Иногда правило нужно не для всей корзины, а только для одного SKU или ID товара. Тогда условие лучше привязать к конкретному товару.
<?php
add_filter( 'woocommerce_available_payment_gateways', 'wpfront_hide_cod_for_specific_product' );
function wpfront_hide_cod_for_specific_product( $gateways ) {
if ( is_admin() || ! function_exists( 'WC' ) || ! WC()->cart ) {
return $gateways;
}
$target_product_id = 123;
$target_gateway_id = 'cod';
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( (int) $cart_item['product_id'] === $target_product_id ) {
if ( isset( $gateways[ $target_gateway_id ] ) ) {
unset( $gateways[ $target_gateway_id ] );
}
break;
}
}
return $gateways;
}Этот вариант проще и предсказуемее, если у вас один проблемный товар или ограниченная группа товаров.
Сравнение подходов
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Код через фильтр | Нужно точное правило по остатку, товару, категории | Гибко, без лишних плагинов | Нужно аккуратно тестировать |
| Плагин для условий оплаты | Нужны правила без разработки | Быстро настраивается | Зависимость от плагина и его логики |
| Ручное отключение метода | Редкие разовые случаи | Не требует кода | Не масштабируется и легко забывается |
Как проверить, что решение сработало
Проверка должна быть не на глаз, а по сценарию.
- Создайте тестовый товар с учетом остатка.
- Поставьте остаток ниже порога, например 1 или 2.
- Добавьте товар в корзину и откройте оформление заказа.
- Проверьте, что целевой способ оплаты исчез из списка.
- Поднимите остаток выше порога и повторите проверку.
Если способ оплаты не исчезает, проверьте три вещи: правильный ID метода, включен ли учет склада у товара, и не кешируется ли страница оформления заказа сторонним плагином или серверным кешем.
Частые ошибки и как их исправить
Неверный ID способа оплаты
Самая частая причина. В коде указан cod, а на сайте нужно скрыть другой метод. Сверьте ID в настройках платежного шлюза или временно выведите массив $gateways в лог.
Проверка остатка не работает для вариаций
У вариативных товаров остаток может храниться на уровне вариации, а не родительского товара. Если корзина содержит вариации, проверяйте именно объект товара из корзины, а не только ID родителя.
Код добавлен в неправильное место
Если вставить фрагмент в активную тему, он может исчезнуть после обновления. Для стабильной работы используйте дочернюю тему или отдельный мини-плагин.
Сайт кеширует страницу checkout
Страницу оформления заказа обычно кешировать нельзя. Если у вас агрессивный кеш, исключите /checkout/, /cart/ и /my-account/ из правил кеширования.
Остаток не уменьшается автоматически
Если заказы не списывают склад, проверьте настройки WooCommerce: учет запасов должен быть включен глобально и для конкретного товара.
Безопасность и производительность
Сам фильтр легкий, но есть несколько практических моментов.
- не используйте тяжелые запросы к базе внутри фильтра оформления заказа;
- не обращайтесь к внешним API на каждом рендере checkout;
- не храните критичную бизнес-логику только в JS — скрытие метода должно происходить на сервере;
- если правило сложное, вынесите его в отдельную функцию и логируйте только на тестовом сайте.
Если вам нужно не только скрывать оплату, но и чистить лишние служебные настройки сайта, имеет смысл посмотреть на Clearfy Pro. Но для самой задачи с оплатой он не обязателен — код выше решает ее напрямую.
Что делать, если правило нужно расширить
На практике этот же фильтр легко доработать под другие сценарии: скрывать оплату по категории товара, по сумме корзины, по стране доставки или по статусу наличия. Главное — не смешивать все условия в один большой блок без структуры. Лучше сначала выделить отдельную функцию, которая возвращает true или false, а уже потом убирать gateway.
Так код проще сопровождать: через месяц вы сами быстро поймете, почему метод оплаты исчезает только для части заказов.