You can redirect logged in customers away from a product page once they’ve already purchased it by checking their purchase history on template_redirect and sending them to a custom URL, useful for one-off items like courses or unique goods.
Why Redirect Customers Who Already Bought
- Prevents duplicate purchases of one-off items like lifetime access or unique physical pieces
- Sends returning buyers straight to a “my courses” or account area instead of the sales page
- Keeps the sales page focused on converting new visitors, not confusing existing owners
- Works for any product ID, so it scales across multiple non-repeatable products
Step 1: Check Purchase History and Redirect
The snippet checks whether the current page is a single product, whether the visitor is logged in, and whether they’ve already bought that exact product ID.
/** Send customers who already own this product away from its page */
add_action( 'template_redirect', 'redirect_existing_owners_from_product' );
function redirect_existing_owners_from_product() {
if ( ! is_product() || ! is_user_logged_in() ) {
return;
}
$current_user = wp_get_current_user();
$viewed_product_id = get_queried_object_id();
if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $viewed_product_id ) ) {
wp_safe_redirect( home_url( '/my-account/orders/' ) );
exit;
}
}

Limiting the Redirect to Specific Products
If only certain products should trigger this (rather than every purchasable item), add an ID check first.
/** Only redirect for a specific list of one-off product IDs */
$one_off_products = array( 842, 917 );
if ( in_array( $viewed_product_id, $one_off_products, true )
&& wc_customer_bought_product( $current_user->user_email, $current_user->ID, $viewed_product_id ) ) {
wp_safe_redirect( home_url( '/my-account/orders/' ) );
exit;
}Troubleshooting
The redirect creates a loop
Make sure the destination URL itself isn’t a single product page that also has this redirect logic attached, or you’ll create an infinite redirect loop.
Redirect doesn’t trigger for a known buyer
Guest checkouts and orders placed under a different email than the current account won’t match — wc_customer_bought_product() checks both the user ID and billing email tied to completed/processing orders.
Frequently Asked Questions
Does this block the customer from ever viewing the page again?
Yes, as written it redirects every time they visit that product page while logged in — adjust the logic if you only want it to happen once per session.
Can I show a message instead of redirecting?
Yes, replace the redirect with a wc_add_notice() call and let the page load normally with a banner instead of sending them elsewhere.
Does this affect logged-out visitors?
No, the check exits immediately for logged-out visitors since there’s no account to check purchase history against.
Conclusion
A short template_redirect snippet is all you need to redirect logged in customers away from a product page they’ve already purchased. Test it with a real test account and a real completed order before relying on it for one-off or non-repeatable products.
See also How to Hide Price and Add to Cart for Logged Out Users in WooCommerce. Then read How to Let a Customer Purchase a WooCommerce Product Only Once.
Prefer no code? All-in-One Utilities Woo Add-on adds over 50 WooCommerce features, so you can switch them on without code.