WooCommerce Hide Price Generator
Generate a snippet that hides prices and the Add to cart button until a shopper logs in, by role, by category, or store-wide as a catalogue.
Your details
Your snippet
<?php
/**
* Hide WooCommerce prices and Add to cart until a shopper logs in.
*/
add_filter( 'woocommerce_get_price_html', 'ea_hide_price_html', 10, 2 );
function ea_hide_price_html( $price_html, $product ) {
if ( ea_hide_price_should_apply( $product ) ) {
return '<span class="ea-hidden-price">' . esc_html( 'Log in to see pricing' ) . '</span>';
}
return $price_html;
}
add_filter( 'woocommerce_is_purchasable', 'ea_hide_price_is_purchasable', 10, 2 );
function ea_hide_price_is_purchasable( $purchasable, $product ) {
if ( ea_hide_price_should_apply( $product ) ) {
return false;
}
return $purchasable;
}
function ea_hide_price_should_apply( $product ) {
return ! is_user_logged_in();
}
add_filter( 'woocommerce_loop_add_to_cart_link', 'ea_hide_price_loop_button', 10, 2 );
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
add_action( 'woocommerce_single_product_summary', 'ea_hide_price_single_button_action', 30 );
function ea_hide_price_loop_button( $html, $product ) {
if ( ! ea_hide_price_should_apply( $product ) ) {
return $html;
}
return sprintf( '<a href="%s" class="button">%s</a>', esc_url( '/contact/' ), esc_html( 'Request a quote' ) );
}
function ea_hide_price_single_button_action() {
global $product;
if ( ! ( $product instanceof WC_Product ) || ! ea_hide_price_should_apply( $product ) ) {
woocommerce_template_single_add_to_cart();
return;
}
printf( '<a href="%s" class="button single_add_to_cart_button alt">%s</a>', esc_url( '/contact/' ), esc_html( 'Request a quote' ) );
}is_purchasable() being false also blocks WooCommerce's add-to-cart handler, so a direct add-to-cart link fails safely instead of adding the item.
How the snippet hides pricing
The snippet uses two real WooCommerce filters on every WC_Product: woocommerce_get_price_html, which controls what's printed where the price normally shows, and woocommerce_is_purchasable, which controls whether the Add to cart button and checkout are available at all. Both templates (the shop loop and the single product page) already check is_purchasable() before showing a buy button, so filtering it hides the button everywhere without touching a template file.
“Catalogue mode” is the same mechanism with the condition always true: nobody, logged in or not, sees a price or can buy. Pair it with an Enquire button so visitors can still contact you.
Adding it to WooCommerce
- 01
Find your role and category slugs
Roles → Users → Add New shows role slugs in the dropdown value (not the display name). Category slugs are under Products → Categories, in the Slug column.
- 02
Paste the snippet
Add it to a site-specific plugin or your child theme's functions.php.
- 03
Test logged out and logged in
Open the shop in a private window to see the logged-out view, then log in with each role you listed to confirm pricing reappears.
This hides the price display and blocks the button; it doesn't stop a determined visitor from reaching /checkout/?add-to-cart=123 directly. is_purchasable being false also blocks WooCommerce's own add-to-cart handler, so a direct link fails safely with a notice, but it's still worth combining this with a members-only catalogue plugin if pricing is genuinely confidential.
Questions people ask
Will this hide prices in search results and Google Shopping too?
No. This only changes what WooCommerce prints on your site. If you also submit a product feed, update or pause those listings separately so cached prices don't mislead shoppers.
Can I hide prices for wholesale customers only, and show them to everyone else?
Yes, invert the logic: set “Hide until” to a role, and use it as the one role that should NOT be hidden by wrapping the condition in !. It's simpler to keep a wholesale price hidden from the public and shown to the wholesale role, which is what the role mode already does.
Does this work with variable products?
Yes. woocommerce_get_price_html and woocommerce_is_purchasable both run on the product object, whether it's simple, variable or grouped.
Will this break WooCommerce's REST API or product feeds?
It can. Both get_price_html() and is_purchasable() are also read by some feed plugins and the REST API's computed fields. If you export a feed, check that it isn't now sending your hidden message as a price.
Is there a plugin instead of a snippet?
Yes, several (Wholesale Suite, B2B/Wholesale Store, YITH's login-to-see-prices addon). A plugin is worth it if you need per-role pricing rules, not just hiding; this snippet is for a simple hide/show rule.
Related tools
Last reviewed 30 September 2026.
Sources: WooCommerce source: abstract-wc-product.php · WooCommerce Code Reference: Hooks
