WPBono

Как отключить заказ без регистрации в WooCommerce для отдельных товаров и категорий

Сценарий типичный: в магазине часть ассортимента можно покупать как гость, а для другой части нужен аккаунт — например, для оптовых товаров, закрытых коллекций, предзаказов или позиций с персональными условиями. Глобальная настройка WooCommerce здесь не помогает: если просто выключить гостевой заказ, пострадает весь каталог. Если оставить всё как есть, покупатель обходит нужную вам логику и оформляет заказ без входа.

Ниже — рабочий способ сделать ограничение точечно: по товарам, категориям или любому вашему правилу. Без выдуманных хуков и без сторонних «магических» плагинов.

Когда проблема проявляется и как её диагностировать

Сначала проверьте, действительно ли у вас проблема именно в checkout, а не в настройках товара или доставки. Обычно симптомы такие:

  • гость видит кнопку «Оформить заказ» и спокойно проходит checkout;
  • после оформления заказ создаётся без привязки к пользователю;
  • для части товаров нужна авторизация, но WooCommerce не различает их по умолчанию;
  • после включения «Покупка без регистрации» ограничение стало слишком широким и сломало обычные продажи.

Полезно проверить три точки:

  1. Настройки WooCommerce → Аккаунты и конфиденциальность: включён ли гостевой заказ.
  2. Есть ли у проблемных товаров общая категория, тег или атрибут, по которому можно строить правило.
  3. Не завязан ли доступ к товару на роль пользователя, membership-плагин или отдельную страницу входа.

Если товар должен быть доступен только после входа, лучше ограничивать не только форму заказа, но и саму возможность добавить товар в корзину. Иначе пользователь увидит товар, положит его в корзину и упрётся в ошибку только на финальном шаге.

Что лучше: настройка, плагин или код

Для такой задачи есть три реалистичных подхода. Выбор зависит от того, насколько точечно нужно ограничение и есть ли у вас разработчик под рукой.

ПодходКогда подходитПлюсыМинусы
Глобальная настройка WooCommerceЕсли гостевой заказ нужно отключить для всего магазинаБыстро, без кодаСлишком грубо для частичных ограничений
Плагин для ролей/доступаЕсли уже есть сложная логика доступаМеньше кода, удобнее для менеджераДополнительная нагрузка и зависимость от плагина
Код через хуки WooCommerceЕсли правило простое и должно работать стабильноТочно, прозрачно, без лишнего интерфейсаНужна аккуратность при обновлениях темы

Если задача сводится к «для категории X нужен логин», код обычно надёжнее. Ниже — вариант, который можно положить в мини-плагин или в functions.php дочерней темы. Для продакшена мини-плагин предпочтительнее: так вы не потеряете логику при смене темы.

Пошаговое решение через код

Шаг 1. Определите правило доступа

Сначала решите, по какому признаку блокировать гостя. Самые практичные варианты:

  • категория товара;
  • конкретные ID товаров;
  • метка в метаполе товара;
  • тип доставки или способ оплаты, если ограничение связано не с товаром, а с оформлением.

Для примера ниже используем категорию wholesale. Это удобно, потому что менеджеру не нужно помнить ID каждого товара.

Шаг 2. Запретите добавление в корзину для гостей

Этот вариант лучше, чем блокировать только checkout. Пользователь сразу понимает, что товар доступен только после входа.

add_filter('woocommerce_add_to_cart_validation', function ($passed, $product_id, $quantity) {
    if (is_user_logged_in()) {
        return $passed;
    }

    $restricted_categories = array('wholesale');

    if (has_term($restricted_categories, 'product_cat', $product_id)) {
        wc_add_notice(
            __('Этот товар доступен только после входа в аккаунт.', 'your-textdomain'),
            'error'
        );
        return false;
    }

    return $passed;
}, 10, 3);

Что делает этот код: если пользователь не авторизован и товар находится в категории wholesale, WooCommerce не даст добавить его в корзину и покажет понятное сообщение.

Шаг 3. Подстрахуйте checkout

Даже если товар уже оказался в корзине, нужно не дать оформить заказ без входа. Это особенно важно, если корзина сохранилась из старой сессии или пользователь пришёл по прямой ссылке.

add_action('woocommerce_checkout_process', function () {
    if (is_user_logged_in()) {
        return;
    }

    $restricted_categories = array('wholesale');

    if (!WC()->cart) {
        return;
    }

    foreach (WC()->cart->get_cart() as $cart_item) {
        $product_id = $cart_item['product_id'];

        if (has_term($restricted_categories, 'product_cat', $product_id)) {
            wc_add_notice(
                __('Для оформления этого заказа нужно войти в аккаунт.', 'your-textdomain'),
                'error'
            );
            break;
        }
    }
});

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

Шаг 4. Если нужно, скрывайте кнопку покупки для гостей

Иногда логичнее не показывать кнопку «В корзину» вообще. Это уже вопрос UX, а не только безопасности. Для каталога с закрытыми ценами такой вариант часто работает лучше.

add_filter('woocommerce_is_purchasable', function ($purchasable, $product) {
    if (is_user_logged_in()) {
        return $purchasable;
    }

    $restricted_categories = array('wholesale');

    if (has_term($restricted_categories, 'product_cat', $product->get_id())) {
        return false;
    }

    return $purchasable;
}, 10, 2);

Важно: woocommerce_is_purchasable влияет на возможность покупки, но не всегда решает вопрос с уже созданной корзиной. Поэтому его лучше использовать вместе с проверкой на checkout.

Как проверить, что всё работает

После внедрения не ограничивайтесь визуальной проверкой на одной странице товара. Пройдите короткий сценарий тестирования:

  • откройте товар из ограниченной категории в режиме инкогнито;
  • проверьте, что кнопка покупки скрыта или добавление в корзину блокируется;
  • попробуйте перейти на /checkout с пустой корзиной и с корзиной, где есть ограниченный товар;
  • авторизуйтесь под обычным клиентом и убедитесь, что товар снова доступен;
  • проверьте мобильную версию: сообщения об ошибке не должны уезжать за экран.

Если у вас включён кэш страниц, обязательно очистите его. Иначе гостю может показываться старая версия карточки товара или checkout.

Полезно также посмотреть логи WooCommerce, если после внедрения появляются странные ошибки. Иногда проблема не в коде, а в том, что тема переопределяет шаблон корзины и ломает стандартные уведомления.

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

Проверяют только checkout, но не корзину

В этом случае гость всё равно может собрать заказ, а ошибка всплывёт слишком поздно. Исправление простое: добавьте проверку на woocommerce_add_to_cart_validation или woocommerce_is_purchasable.

Используют неправильный ID товара

Если вы ограничиваете не категорию, а конкретные товары, легко перепутать ID вариации и ID родительского товара. Для variable product обычно проверяют именно родительский товар, если правило должно действовать на весь набор вариаций.

Кладут код в активную тему

При обновлении темы правка исчезает. Для стабильности лучше вынести код в маленький плагин или хотя бы в дочернюю тему.

Не учитывают уже сохранённую корзину

Пользователь мог добавить товар до изменения правил. Поэтому проверка на checkout обязательна, даже если добавление в корзину уже заблокировано.

Ставят слишком общий текст ошибки

Сообщение вроде «Ошибка оформления заказа» не помогает пользователю. Лучше сразу писать, что нужно войти в аккаунт, и при необходимости дать ссылку на страницу входа.

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

Если ограничение завязано на роли, не полагайтесь только на фронтенд. Скрыть кнопку недостаточно: прямой POST-запрос или сохранённая корзина могут обойти интерфейс. Проверка должна быть на сервере, как в примерах выше.

Для производительности не делайте тяжёлых запросов к базе на каждом рендере карточки товара. Проверка через has_term() для одной-двух категорий обычно нормальна. Если логика сложнее, подумайте о кэшировании признака в метаполе товара или о предварительной подготовке списка ID.

Если у вас много подобных правил, удобнее собрать их в отдельный мини-плагин и хранить конфигурацию в массиве. Тогда менеджеру не придётся править PHP каждый раз, когда меняется список закрытых категорий.

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

Если нужно ограничить не категорию, а конкретные товары

Тогда вместо has_term() используйте список ID. Это удобно, когда закрытых позиций мало и они не объединены в отдельную категорию.

add_filter('woocommerce_add_to_cart_validation', function ($passed, $product_id) {
    if (is_user_logged_in()) {
        return $passed;
    }

    $restricted_products = array(123, 456, 789);

    if (in_array((int) $product_id, $restricted_products, true)) {
        wc_add_notice(__('Этот товар доступен только после входа.', 'your-textdomain'), 'error');
        return false;
    }

    return $passed;
}, 10, 2);

Такой вариант проще в поддержке, если список закрытых товаров небольшой. Но если ассортимент регулярно меняется, категория обычно удобнее.

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

×

AI-плагин

WPGPT
Сам создает статьи для вашего сайта WordPress

SEO и мета-теги

Парсинг конкурентов

Изображения

Комментарии

Подробнее