WooCommerce: как разрешить и запретить оплату разными методами для разных товаров

Проблема: ограничение способов оплаты по товарам в WooCommerce

В стандартном WooCommerce нет встроенной функции, которая позволяла бы показывать или скрывать определённые методы оплаты в зависимости от выбранных товаров в корзине. Это часто требуется, например, если вы продаёте цифровые и физические товары, и хотите разрешать оплату по безналу только для физических товаров, а для цифровых — только онлайн-платежи. Или если у товара есть особые условия оплаты.

Диагностика проблемы

Проверить, что WooCommerce не фильтрует способы оплаты по товарам, можно так:

  • Добавьте в корзину разные товары с разными условиями оплаты.
  • Перейдите на страницу оформления заказа.
  • Посмотрите, доступны ли все методы оплаты, которые активированы в настройках WooCommerce.

Если все методы всегда отображаются, несмотря на разные товары в корзине, значит, фильтр не настроен.

Решение: фильтрация методов оплаты через хук woocommerce_available_payment_gateways

WooCommerce позволяет изменить доступные способы оплаты с помощью фильтра woocommerce_available_payment_gateways. Мы можем реализовать логику, которая проверит товары в корзине и отфильтрует методы оплаты.

Пример кода для ограничения способов оплаты по товарам с определённой категорией

add_filter('woocommerce_available_payment_gateways', 'filter_payment_gateways_by_product_category');
function filter_payment_gateways_by_product_category($available_gateways) {
    if (is_admin()) return $available_gateways; // Не трогаем админку

    $restrict_cod_category = 'physical'; // Категория товаров, для которой разрешён COD

    $has_physical = false;
    $has_other = false;

    foreach (WC()->cart->get_cart() as $cart_item) {
        $product_id = $cart_item['product_id'];
        $terms = get_the_terms($product_id, 'product_cat');
        $categories = wp_list_pluck($terms, 'slug');

        if (in_array($restrict_cod_category, $categories)) {
            $has_physical = true;
        } else {
            $has_other = true;
        }
    }

    // Если в корзине есть товары из категории 'physical', разрешаем COD
    if ($has_physical) {
        // Оставляем все методы
    }

    // Если в корзине есть товары вне категории 'physical', отключаем COD
    if ($has_other && isset($available_gateways['cod'])) {
        unset($available_gateways['cod']);
    }

    return $available_gateways;
}

В этом примере метод оплаты «Оплата при получении» (COD) доступен только если в корзине есть товары из категории physical. Если в корзине есть другие товары, COD отключается.

Пример: разрешить оплату картой только для цифровых товаров

add_filter('woocommerce_available_payment_gateways', 'only_card_for_digital_products');
function only_card_for_digital_products($available_gateways) {
    if (is_admin()) return $available_gateways;

    $digital_category = 'digital';

    $has_digital = false;
    $has_non_digital = false;

    foreach (WC()->cart->get_cart() as $cart_item) {
        $product_id = $cart_item['product_id'];
        $terms = get_the_terms($product_id, 'product_cat');
        $categories = wp_list_pluck($terms, 'slug');

        if (in_array($digital_category, $categories)) {
            $has_digital = true;
        } else {
            $has_non_digital = true;
        }
    }

    // Если есть цифровые товары, разрешаем только payment_method_1 (например, card)
    if ($has_digital) {
        foreach ($available_gateways as $gateway_id => $gateway) {
            if ($gateway_id !== 'payment_method_1') {
                unset($available_gateways[$gateway_id]);
            }
        }
    }

    // Если есть нецифровые товары, разрешаем все методы
    if ($has_non_digital) {
        // Ничего не меняем
    }

    return $available_gateways;
}

Пошаговая инструкция для внедрения решения

  1. Определите логику ограничения способов оплаты (по категориям, тегам, метаполям товаров).
  2. Добавьте приведённый код в файл functions.php вашей дочерней темы или в кастомный плагин.
  3. Замените названия категорий и ID методов оплаты на актуальные для вашего магазина.
  4. Очистите кэш сайта и браузера.
  5. Проверьте работу на странице оформления заказа с разными товарами в корзине.

Как проверить, что решение сработало

  • Добавьте в корзину товар из категории, где метод оплаты должен быть доступен, и убедитесь, что он отображается.
  • Добавьте товар из категории, где метод оплаты должен быть запрещён, и проверьте, что метод не показывается.
  • Проверьте комбинации товаров разных категорий — метод оплаты должен показываться/скрываться согласно логике.

Частые ошибки и как исправить

  • Методы оплаты не меняются: убедитесь, что хук подключён правильно, и код не вызывает ошибок. Проверьте, что в корзине есть товары, и что категории заданы верно.
  • Ошибка «Undefined index» для метода оплаты: проверьте, что ID метода оплаты совпадает с тем, что используется в WooCommerce (например, 'cod', 'bacs', 'paypal').
  • Код не работает в админке: добавьте проверку if (is_admin()) return $available_gateways; в начале функции.
  • Методы оплаты исчезают полностью: возможно, условие фильтрации слишком жёсткое, и все методы удаляются. Проверьте логику и отладьте с помощью error_log или дебагера.

Практические советы по безопасности и производительности

  • Не используйте тяжелые запросы в цикле корзины — кешируйте результаты, если нужно.
  • Проверяйте, что фильтр работает только на фронтенде оформления заказа, чтобы не замедлять админку.
  • Используйте корректные ID методов оплаты, чтобы избежать ошибок.
  • Если у вас много продуктов и сложная логика, рассмотрите хранение условий в метаполях и используйте прямые SQL-запросы для оптимизации.

Сравнение способов реализации фильтрации оплаты

МетодПлюсыМинусы
Код в functions.phpБыстро, гибко, бесплатноТребует навыков, возможны ошибки при обновлениях темы
Кастомный плагинИзолированное решение, легко переносить между сайтамиНужно писать и поддерживать плагин
Плагины из репозиторияГотовые решения без кодаМогут быть ограничены в возможностях, нагрузка на сайт
Автоматическое удаление неиспользуемых вариаций товаров в WooCommerce после продажи
09.07.2026
WooCommerce: настройка и решение проблем с отпуском товаров
21.04.2026
Как использовать REST API в WordPress для создания настроек
26.11.2025
Как установить лимит на количество постов в рассылке WordPress
12.04.2026
Как отключить автоматическое обновление плагинов WordPress и управлять версиями
23.12.2025