Типичный сценарий: магазин на WooCommerce должен работать как каталог для всех, но цену и кнопку покупки видят только зарегистрированные пользователи. На практике это нужно для B2B, оптовых прайсов, закрытых витрин и магазинов с ручным согласованием доступа.
Задача кажется простой, но в WooCommerce есть нюанс: если скрыть только кнопку, цена всё равно останется в карточке товара и в списках. Если убрать цену только через шаблон, она может вернуться из мини-карточек, блоков каталога или сторонней темы. Поэтому лучше решать задачу на уровне фильтров WooCommerce, а не правкой шаблонов.
Когда это действительно нужно
Сценарий подходит, если вы хотите:
- показывать ассортимент всем посетителям, но не раскрывать прайс;
- давать доступ к ценам только после регистрации или входа;
- оставить товары индексируемыми, но убрать коммерческие элементы для гостей;
- заменить кнопку покупки на текст вроде «Войдите, чтобы увидеть цену».
Если вам нужно полностью скрыть каталог от гостей, это уже другая задача: там лучше ограничивать архивы, карточки и поиск отдельно. Здесь разбираем именно частичный доступ.
Диагностика проблемы: что именно нужно скрывать
Перед внедрением проверьте, где у вас выводятся цена и кнопка. В WooCommerce они могут появляться в нескольких местах:
- карточка товара;
- страница каталога и категории;
- виджеты и блоки с товарами;
- мини-корзина и связанные товары;
- шаблоны темы, которые переопределяют стандартный вывод.
Если тема уже вмешивается в шаблоны WooCommerce, сначала проверьте, не дублирует ли она вывод цены собственными функциями. В таком случае один фильтр может не закрыть все точки отображения.
Что проверить в админке и на фронтенде
- Откройте товар в режиме гостя и в режиме авторизованного пользователя.
- Сравните карточку товара, архив категории и блоки на главной.
- Посмотрите, не осталась ли цена в JSON-LD или в микроразметке темы, если это важно для вашего проекта.
- Проверьте кэш страницы: иногда после правки код уже работает, но старый HTML всё ещё отдается кэшем.
Рабочее решение через хуки WooCommerce
Надежнее всего использовать фильтры woocommerce_get_price_html и woocommerce_is_purchasable. Первый отвечает за HTML цены, второй — за возможность купить товар. В связке они закрывают и цену, и кнопку покупки.
Добавьте код в functions.php дочерней темы или в собственный мини-плагин. Если проект живой и код должен переживать смену темы, мини-плагин безопаснее.
<?php
add_filter( 'woocommerce_get_price_html', 'wpexperts_hide_price_for_guests', 10, 2 );
add_filter( 'woocommerce_is_purchasable', 'wpexperts_disable_purchase_for_guests', 10, 2 );
function wpexperts_hide_price_for_guests( $price, $product ) {
if ( is_user_logged_in() ) {
return $price;
}
return '<span class="price price--hidden">Войдите, чтобы увидеть цену</span>';
}
function wpexperts_disable_purchase_for_guests( $purchasable, $product ) {
if ( is_user_logged_in() ) {
return $purchasable;
}
return false;
}Что делает этот код:
- для гостей цена заменяется на текст-заглушку;
- для гостей товар становится непокупаемым;
- для авторизованных пользователей WooCommerce работает как обычно.
Если вам нужно скрыть цену полностью, а не заменять текстом, можно вернуть пустую строку. Но на практике это хуже для UX: пользователь не понимает, почему карточка пустая.
Как показать вместо цены форму входа или ссылку на регистрацию
Если магазин закрытый, лучше не просто писать «Войдите», а дать понятный путь. Например, ссылку на страницу входа и регистрации. Это особенно полезно, если у вас B2B-магазин или доступ выдается после модерации.
<?php
add_filter( 'woocommerce_get_price_html', 'wpexperts_price_login_link_for_guests', 10, 2 );
function wpexperts_price_login_link_for_guests( $price, $product ) {
if ( is_user_logged_in() ) {
return $price;
}
$login_url = wp_login_url( get_permalink( $product->get_id() ) );
$register_url = wp_registration_url();
return sprintf(
'<span class="price price--hidden">Цена доступна после <a href="%s">входа</a> или <a href="%s">регистрации</a></span>',
esc_url( $login_url ),
esc_url( $register_url )
);
}Здесь важно не забыть про экранирование URL через esc_url(). Даже если ссылки формируются функциями WordPress, это нормальная практика для фронтенда.
Сравнение подходов: плагин, код или правка шаблона
| Подход | Плюсы | Минусы | Когда выбирать |
|---|---|---|---|
| Плагин | Быстро, без разработки | Лишняя зависимость, возможны конфликты | Если нужен простой запуск без поддержки кода |
| Код через хуки | Контролируемо, прозрачно, легко доработать | Нужен доступ к теме или мини-плагину | Если проект поддерживает разработчик |
| Правка шаблона | Можно точечно изменить верстку | Сложнее поддерживать, ломается при обновлениях | Если тема сильно кастомная и фильтров недостаточно |
Если у вас уже стоит плагин для удаления дублей и чистки интерфейса, например Clearfy Pro, часть визуальных задач можно закрыть настройками. Но для логики «показывать только после входа» код обычно надежнее и предсказуемее.
Пошаговая настройка без лишних рисков
- Создайте резервную копию файлов и базы.
- Добавьте код в дочернюю тему или мини-плагин.
- Очистите кэш сайта, CDN и браузера.
- Проверьте гостевой режим в инкогнито.
- Проверьте авторизованный аккаунт с ролью покупателя.
- Убедитесь, что кнопка «Купить» исчезла и товар не добавляется в корзину.
Если нужен доступ только для части товаров
Иногда скрывать цены нужно не на весь каталог, а только на отдельные категории или товары. Тогда добавьте проверку по ID товара, категории или метке. Пример ниже скрывает цену только для товаров из категории private.
<?php
add_filter( 'woocommerce_get_price_html', 'wpexperts_hide_price_for_private_category', 10, 2 );
add_filter( 'woocommerce_is_purchasable', 'wpexperts_disable_purchase_for_private_category', 10, 2 );
function wpexperts_is_private_product( $product ) {
return has_term( 'private', 'product_cat', $product->get_id() );
}
function wpexperts_hide_price_for_private_category( $price, $product ) {
if ( is_user_logged_in() || ! wpexperts_is_private_product( $product ) ) {
return $price;
}
return '<span class="price price--hidden">Цена доступна после входа</span>';
}
function wpexperts_disable_purchase_for_private_category( $purchasable, $product ) {
if ( is_user_logged_in() || ! wpexperts_is_private_product( $product ) ) {
return $purchasable;
}
return false;
}Такой вариант удобен, если у вас публичный каталог и закрытый прайс-лист в одной установке WooCommerce.
Проверка результата после внедрения
После сохранения кода не ограничивайтесь визуальной проверкой одной страницы. Нужно пройтись по нескольким точкам вывода.
- Откройте карточку товара в режиме гостя: цена должна быть заменена или скрыта.
- Проверьте архив категории: там не должно остаться старой цены в карточках.
- Нажмите на товар из блока «Похожие товары» или «Рекомендуемое»: логика должна быть той же.
- Авторизуйтесь и убедитесь, что цена снова отображается.
- Попробуйте добавить товар в корзину как гость: кнопка не должна работать.
Если используете кэширование страниц, проверьте отдельно гостевой и авторизованный кэш. Иногда проблема не в коде, а в том, что кэш отдает старую версию HTML для всех пользователей.
Частые ошибки и как их исправить
Цена скрылась не везде
Причина обычно в теме или конструкторе, который выводит цену не через стандартный фильтр WooCommerce. В этом случае ищите переопределенные шаблоны woocommerce/content-product.php или собственные функции темы. Иногда помогает только точечная правка шаблона.
Кнопка «Купить» осталась активной
Если товар всё ещё покупаемый, значит фильтр woocommerce_is_purchasable не сработал или был переопределен другим кодом. Проверьте, нет ли в теме или плагине дополнительной логики для кнопки. Также убедитесь, что код не добавлен в файл, который не загружается.
После правки сайт показывает белый экран
Чаще всего причина в синтаксической ошибке в functions.php или вставке кода без открывающего/закрывающего PHP-тега в неподходящем месте. Если доступ к админке потерян, отключите проблемный код через FTP или файловый менеджер хостинга.
Гость видит старую версию страницы
Это почти всегда кэш. Очистите кэш плагина, сервера и CDN. Если используется отдельный кэш для мобильных устройств или разных ролей, проверьте и его.
Безопасность и производительность
Сама логика скрытия цены не тяжелая, но есть несколько практических моментов:
- не храните такой код в случайном сниппет-плагине без контроля версий, если проект рабочий;
- не отключайте покупку только визуально, если товар реально должен быть недоступен — используйте
woocommerce_is_purchasable; - не полагайтесь на CSS-скрытие: цена останется в HTML и может быть прочитана;
- если у вас большой каталог, избегайте лишних тяжелых проверок внутри фильтра на каждом товаре;
- для закрытых магазинов продумайте, как будут работать поиск, sitemap и индексация.
Если нужна не только логика, но и аккуратная подача закрытого каталога, имеет смысл дополнить решение страницей входа, понятной формой регистрации и коротким текстом о том, как получить доступ. Это лучше, чем просто пустые карточки.
В проектах, где важна редакционная чистота интерфейса, можно дополнительно использовать блоки внимания или FAQ, чтобы объяснить пользователю, почему цена скрыта и как ее получить. Но сама бизнес-логика должна оставаться в коде, а не в визуальном трюке.