WooCommerce: как заблокировать оплату при наличии товаров с определёнными атрибутами в корзине

Диагностика проблемы: почему нужно блокировать оплату

В интернет-магазинах на WooCommerce часто возникает задача запретить оформление заказа, если в корзине присутствуют товары с определёнными атрибутами. Например, товары с ограниченной доступностью, товары, требующие дополнительных согласований, или товары с нестандартными условиями продажи.

Без блокировки пользователь может оформить заказ, который магазин не готов обработать, что приводит к ошибкам, возвратам и негативному опыту.

Как определить наличие товаров с нужными атрибутами в корзине

WooCommerce хранит товары в корзине с объектами WC_Cart_Item. У каждого товара можно проверить атрибуты через свойства товара.

function has_product_with_attribute( $attribute_name, $attribute_value ) {
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $product = $cart_item['data'];
        $attributes = $product->get_attributes();

        foreach ( $attributes as $attr ) {
            if ( $attr->is_taxonomy() ) {
                $terms = wp_get_post_terms( $product->get_id(), $attr->get_name(), array('fields' => 'names') );
                if ( in_array( $attribute_value, $terms, true ) ) {
                    return true;
                }
            } else {
                if ( $attr->get_options() && in_array( $attribute_value, $attr->get_options(), true ) ) {
                    return true;
                }
            }
        }
    }
    return false;
}

Этот код проверяет, есть ли в корзине товар с заданным атрибутом и значением.

Пошаговое решение: блокируем кнопку оплаты

1. Добавляем проверку в хук woocommerce_checkout_process, чтобы прервать оформление при наличии запрещённых товаров.

2. Выводим сообщение пользователю о причине блокировки.

add_action( 'woocommerce_checkout_process', 'block_checkout_if_attribute_in_cart' );
function block_checkout_if_attribute_in_cart() {
    $attribute_name = 'pa_special'; // замените на свой slug атрибута
    $attribute_value = 'restricted'; // значение атрибута, при котором блокируем

    if ( has_product_with_attribute( $attribute_name, $attribute_value ) ) {
        wc_add_notice( 'Оплата заблокирована: в корзине есть товары с ограниченной продажей.', 'error' );
    }
}

3. Для улучшения UX можно скрыть кнопку оплаты на странице корзины с помощью фильтра woocommerce_proceed_to_checkout или через JavaScript.

add_filter( 'woocommerce_proceed_to_checkout', 'disable_checkout_button_if_attribute' );
function disable_checkout_button_if_attribute( $button_html ) {
    $attribute_name = 'pa_special';
    $attribute_value = 'restricted';

    if ( has_product_with_attribute( $attribute_name, $attribute_value ) ) {
        return '<p class="woocommerce-error">Оплата временно недоступна из-за ограничений по товарам в корзине.</p>';
    }
    return $button_html;
}

Проверка результата после внедрения

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

Частые ошибки и их исправление

  • Неверный slug атрибута: В WooCommerce атрибуты товаров имеют префикс pa_. Проверьте правильность названия.
  • Атрибут задан не как таксономия: Если атрибут не зарегистрирован глобально, используйте другие методы для получения значения.
  • Кэширование корзины: Некоторые сайты с кэшированием могут не обновлять состояние кнопок. Отключите кэширование страниц корзины и оформления.
  • Ошибка в функции проверки: Убедитесь, что функция has_product_with_attribute подключена и доступна в текущем контексте.

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

  • Используйте хук woocommerce_checkout_process для серверной проверки, чтобы нельзя было обойти блокировку через клиентский код.
  • Минимизируйте количество запросов к базе, кэшируя результаты проверки при вызове в рамках одного запроса.
  • Добавьте клиентскую проверку (на JS), чтобы пользователь сразу видел ограничение без повторного запроса.
  • Не выводите подробности об ошибках, которые могут раскрыть структуру магазина или бизнес-логику.

Сравнение вариантов реализации блокировки оплаты

МетодПлюсыМинусыПример использования
Серверная проверка в woocommerce_checkout_process Надёжная, нельзя обойти, информирует на этапе оформления Пользователь узнаёт об ошибке поздно Пример кода выше
Клиентская проверка (JS) Мгновенный фидбек, улучшенный UX Можно обойти, нужен серверный контроль Скрытие кнопки, показ уведомления
Плагин для условий корзины Готовое решение, гибкие настройки без кода Может нагружать сайт, ограничена кастомизация WooCommerce Conditional Shipping and Payments
Как автоматически удалять старые черновики в WordPress
02.03.2026
Как создать простой плагин для автоматического очищения базы данных WordPress
09.02.2026
WooCommerce: автоматическое удаление неактивных заказов
26.07.2026
Как создать свой шорткод для WordPress
27.11.2025
Как создать автоматическую резервную копию WordPress с помощью PHP
18.12.2025