Сценарий типичный: в каталоге WooCommerce нужно показывать одну цену гостям, другую — зарегистрированным клиентам, а для оптовиков вообще скрывать стоимость до входа в аккаунт. На уровне магазина это уже не косметика, а рабочая логика продаж: не все покупатели должны видеть одинаковые условия.
Есть три реалистичных пути: плагин, код в теме или отдельном мини-плагине. Если задача простая и нужна без разработки — можно взять готовое решение. Если важны контроль и предсказуемость, лучше сделать через хуки WooCommerce. Ниже — именно такой вариант: без вымышленных API, с проверяемыми шагами и понятной диагностикой.
Когда проблема проявляется и что именно ломается
Чаще всего запрос выглядит так:
- гость видит цену, хотя должен видеть только кнопку «Войти, чтобы увидеть цену»;
- для роли
wholesale_customerнужна отдельная цена; - на карточке товара цена скрыта, но в корзине или в JSON-LD она всё равно остается;
- после установки плагина цена пропадает везде, включая админку и письма.
Перед правкой кода проверьте, где именно нужно менять поведение: архив товаров, карточка товара, корзина, мини-корзина, письма, структурированные данные. Это важно, потому что один и тот же фильтр не всегда влияет на все места вывода.
Быстрая диагностика
- Откройте товар в режиме гостя и под тестовой ролью.
- Проверьте, выводится ли цена в шаблоне темы или через блоки/конструктор.
- Посмотрите, не кешируется ли страница для гостей и авторизованных пользователей одинаково.
- Если используется плагин кеша или CDN, временно отключите кеш для проверки.
Если цена меняется только на странице товара, а в каталоге нет — значит, тема выводит цену отдельным шаблоном. Если скрытие работает в карточке, но не в корзине, значит, нужно дополнительно обработать корзину и checkout.
Плагин или код: что выбрать
| Подход | Когда подходит | Минусы |
|---|---|---|
| Плагин | Нужно быстро запустить без разработки | Может конфликтовать с темой и кешем, меньше контроля |
| Код через хуки | Нужна точная логика по ролям и страницам | Требует проверки после обновлений темы и WooCommerce |
| Комбинированный вариант | Часть логики через плагин, часть — через код | Сложнее сопровождать, если нет документации |
Если у вас уже есть плагин для скрытия цен — сначала проверьте его настройки. Но если нужна прозрачная и воспроизводимая логика, код обычно надежнее: вы сами определяете, кто видит цену, а кто — нет.
Пошаговое решение через код
Ниже пример, который скрывает цену и кнопку покупки для гостей, а для авторизованных пользователей с ролью wholesale_customer подставляет свою цену из метаполя товара _wholesale_price. Если метаполе пустое, показывается обычная цена.
Добавлять код лучше в мини-плагин или в functions.php дочерней темы. Для продающего сайта мини-плагин безопаснее: при смене темы логика не потеряется.
<?php
add_filter( 'woocommerce_get_price_html', 'wp_course_role_based_price_html', 10, 2 );
function wp_course_role_based_price_html( $price_html, $product ) {
if ( is_admin() && ! wp_doing_ajax() ) {
return $price_html;
}
if ( ! $product instanceof WC_Product ) {
return $price_html;
}
if ( ! is_user_logged_in() ) {
return '<span class="price-login-required">Войдите, чтобы увидеть цену</span>';
}
$user = wp_get_current_user();
if ( in_array( 'wholesale_customer', (array) $user->roles, true ) ) {
$wholesale_price = $product->get_meta( '_wholesale_price', true );
if ( $wholesale_price !== '' ) {
return wc_price( (float) $wholesale_price );
}
}
return $price_html;
}
add_filter( 'woocommerce_is_purchasable', 'wp_course_hide_purchase_for_guests', 10, 2 );
function wp_course_hide_purchase_for_guests( $purchasable, $product ) {
if ( is_admin() && ! wp_doing_ajax() ) {
return $purchasable;
}
if ( ! is_user_logged_in() ) {
return false;
}
return $purchasable;
}
add_filter( 'woocommerce_loop_add_to_cart_link', 'wp_course_replace_add_to_cart_for_guests', 10, 2 );
function wp_course_replace_add_to_cart_for_guests( $html, $product ) {
if ( is_user_logged_in() ) {
return $html;
}
$login_url = wp_login_url( get_permalink( $product->get_id() ) );
return '<a class="button" href="' . esc_url( $login_url ) . '">Войти для покупки</a>';
}Что делает этот код:
woocommerce_get_price_htmlменяет HTML цены на витрине;woocommerce_is_purchasableзапрещает покупку гостям;woocommerce_loop_add_to_cart_linkподменяет кнопку в каталоге.
Если вам не нужно скрывать покупку, а нужно только менять цену для роли, уберите фильтр woocommerce_is_purchasable. Тогда товар останется доступным, но цена будет отображаться по вашей логике.
Если нужна отдельная цена для нескольких ролей
Когда ролей больше одной, удобнее хранить правило в массиве. Например, для оптовиков и менеджеров можно задать разные коэффициенты или разные метаполя. Пример ниже показывает принцип без привязки к конкретному плагину ролей:
<?php
add_filter( 'woocommerce_get_price_html', 'wp_course_price_by_role_map', 10, 2 );
function wp_course_price_by_role_map( $price_html, $product ) {
if ( ! is_user_logged_in() || ! $product instanceof WC_Product ) {
return $price_html;
}
$user = wp_get_current_user();
$role_prices = array(
'wholesale_customer' => '_wholesale_price',
'vip_customer' => '_vip_price',
);
foreach ( $role_prices as $role => $meta_key ) {
if ( in_array( $role, (array) $user->roles, true ) ) {
$custom_price = $product->get_meta( $meta_key, true );
if ( $custom_price !== '' ) {
return wc_price( (float) $custom_price );
}
}
}
return $price_html;
}Такой подход удобен, если у вас B2B-магазин и условия зависят от сегмента клиента. Но не стоит раздувать логику в одном файле: если правил становится много, лучше вынести их в отдельный класс или мини-плагин.
Как проверить, что решение сработало
Проверка должна быть не визуальной «вроде работает», а по конкретным сценариям:
- Откройте товар как гость — цена должна скрываться или заменяться на ваш текст.
- Авторизуйтесь под обычным клиентом — проверьте, что отображается стандартная цена.
- Войдите под ролью
wholesale_customer— убедитесь, что подставляется цена из_wholesale_price. - Добавьте товар в корзину и проверьте, что цена в корзине соответствует той же логике.
- Очистите кеш страницы и объектный кеш, если они включены.
Если цена в каталоге изменилась, а в карточке товара нет, значит, тема переопределяет шаблон цены. Тогда нужно смотреть, не выводится ли цена через кастомный шаблон WooCommerce в теме.
Частые ошибки и как их исправить
Цена скрывается только на части страниц
Причина обычно в кешировании или в том, что тема использует разные шаблоны для архива и карточки товара. Решение: очистить кеш, проверить шаблоны темы и убедиться, что фильтр применяется в нужном месте.
Скрылась цена в админке
Это происходит, если забыли защиту is_admin() и код срабатывает в бэкенде. Для WooCommerce это особенно неприятно: можно сломать редактирование товаров и массовые действия.
Покупка пропала у всех пользователей
Частая ошибка — слишком агрессивный фильтр woocommerce_is_purchasable без проверки роли. Если нужно ограничить только гостей, не трогайте авторизованных клиентов.
Цена не меняется у вариативных товаров
У вариативных товаров цена может браться из вариации, а не из родительского товара. В таком случае проверяйте метаполя у вариаций, а не только у основного товара.
Безопасность и производительность
Если логика зависит от ролей, не храните критичные правила в случайных сниппетах из интернета. Лучше один раз оформить код в мини-плагин и версионировать его в репозитории. Это проще сопровождать и легче откатить.
Не выводите цену через прямую подстановку без экранирования, если в HTML попадает пользовательский текст. В примерах выше текст для гостей задан статически, а цена формируется через wc_price(), что безопаснее, чем собирать HTML вручную.
Если у вас большой каталог, проверьте влияние на кеш. Логика по ролям может ломать общий кеш страниц, если один и тот же URL должен показывать разный контент разным пользователям. Для таких страниц кеш лучше настраивать отдельно или исключать их из full-page cache.
Когда лучше взять плагин вместо кода
Если нужно не только скрыть цену, но и управлять каталогом B2B, запросами на прайс, регистрацией по ролям и индивидуальными скидками, готовый плагин может сэкономить время. Но перед установкой проверьте, как он работает с кешем, вариативными товарами и шаблонами вашей темы.
Если вы уже используете решения WPShop, то для смежных задач иногда полезно посмотреть на Clearfy Pro — не для скрытия цен, а для чистки лишних дублей и технических настроек сайта, если они мешают поддержке магазина.
В итоге рабочая схема простая: сначала определяете, кому и где показывать цену, потом выбираете способ реализации, затем проверяете каталоги, карточки и корзину под разными ролями. Если логика сложнее стандартного сценария, код через хуки WooCommerce обычно дает больше контроля, чем универсальный плагин.