We previously wrote up a tutorial on preventing repeat purchases for a particular WooCommerce product, or for any product in your store. However, based on the comments there, some merchants wanted to disable repeat WooCommerce purchases for a set of products, but not all products.
In order to do so, you could use a product category to check whether repeat purchases should be allowed or not. This would let you group all products that shouldn’t allow multiple purchases into your own category (i.e., a “Single Purchase” category), and check for this to see if customers should be able to purchase.
Obviously this will only work for logged-in customers, as without having the customer logged in, we have no way of knowing their email to see if they’ve bought a product.
Let’s take a look at checking for a product category, then disabling purchase if a product is in the desired category. We’ve discussed checking the cart for a particular category, so we’ll do something similar with the has_term()
check here.
A Helper: Check if the Customer Has Purchased Before
First, we’ll set up a helper method that does one thing given a product: checks if the customer has bought it before. Typically the wc_customer_bought_product()
function would do just fine, but we want to see if the product is in a given category before making this check.
Let’s write a helper function whose only purpose is to run this check if the product is in our target category (the one for which repeat purchases are not allowed). Note that to our helper requires WooCommerce 2.5 or newer since it uses the $product->get_id()
method.
/** * Helper function to see if a customer has purchased a product * in a given category * * @param \WC_Product $product the WooCommerce product instance * @return bool - true if product is in category and has been purchased */ function sv_wc_customer_purchased_product_in_cat( $product ) { // enter the category for which a single purchase is allowed $non_repeatable = 'clothing'; // bail if this product is in not in our target category if ( ! has_term( $non_repeatable, 'product_cat', $product->get_id() ) ) { return false; } // the product has our target category, so return whether the customer purchased return wc_customer_bought_product( wp_get_current_user()->user_email, get_current_user_id(), $product->get_id() ); }
Alright, this is a nice small function: give it a product, return whether it’s been purchased and is in our no-repeats category.
Disable Product Purchasing
Next, we’ll use this function to check if the product meets our criteria, and if so, we’ll disable purchase. We did this in more detail in the previous tutorial, but the gist of it is we’ll use the woocommerce_is_purchasable
filter and the woocommerce_variation_is_purchasable
filter.
We probably don’t need the latter one, but in case direct add to cart links are used somewhere for the variation, it’s a good safety net.
/** * Disables repeat purchase for a product category; checks if a product is in the category * and if it's already been purchased, then disables purchasing if so * * @param bool $purchasable true if product can be purchased * @param \WC_Product $product the WooCommerce product * @return bool - the updated is_purchasable check */ function sv_wc_disable_repeat_purchase( $purchasable, $product ) { if ( sv_wc_customer_purchased_product_in_cat( $product ) ) { $purchasable = false; } // double-check for variations: if parent is not purchasable, then variation is not if ( $purchasable && $product->is_type( 'variation' ) ) { $purchasable = $product->parent->is_purchasable(); } return $purchasable; } add_filter( 'woocommerce_variation_is_purchasable', 'sv_wc_disable_repeat_purchase', 10, 2 ); add_filter( 'woocommerce_is_purchasable', 'sv_wc_disable_repeat_purchase', 10, 2 );
Now we’ve disabled repeat purchasing, so the “add to cart” section will be removed from product pages, and the shop loop will say, “Read More” for the product instead of “Add to cart” or “Select Options”.
Let’s add a nicer notice to the product page instead explaining why it can’t be purchased.
Add a “Purchase Disabled” Message
This one is a pretty straight-forward function: use a product page action to check if the product meets our criteria, add a notice on the product page if so.
/** * Shows a "purchase disabled" message to the customer */ function sv_wc_purchase_disabled_message() { // get the current product to check if purchasing should be disabled global $product; // now we know we're in the category, check if we've purchased already if ( sv_wc_customer_purchased_product_in_cat( $product ) ) { // Create your message for the customer here echo '<div class="woocommerce"><div class="woocommerce-info wc-nonpurchasable-message"> You\'ve already purchased this product! It can only be purchased once. </div></div>'; } } add_action( 'woocommerce_single_product_summary', 'sv_wc_purchase_disabled_message', 31 );
Now for products in our target category that have not been purchased before, they’ll look pretty standard:
However, once a product in this category has been purchased, it will have the purchasing disabled and will show our custom message:
Summary
This gives you a way to disable repeat purchases for multiple products by grouping them together into a category. You can view the full code in this gist to see it all put together.
This will not disable purchasing for the entire category if one product is purchased (just the one the customer already bought), as this kind of set up would be more complex — we don’t have a simple way to check, “has the customer bought anything in this category?” so set ups that require disabling purchase for a different product when another is purchased would require a fair bit of customization, for which this can be a starting point.
[…] for developers: you can disable repeat purchases for a WooCommerce product category using this tutorial from […]
YES! Thanks Beka – my client has been waiting on this for a while now, and I’m so grateful you took the time to write it out for other developers.
Thank you,
Josh
Thank you.
This was useful.
Only issue is that if the product has been added to the cart before the user logs in, then after logging in, the item gets removed from the cart with a message: “The item has been removed from the cart because it can no longer be purchased”. This message is little confusing for the user. It will be good to customize it saying that it is a repeat purchase and hence removed from the cart.
Thank you,
Raman
Hey Raman, to target the message to this specific situation would be a little involved to do, but if you wanted to always change that message, you could translate it with a plugin like Say What?.
Thank you very much for the suggestion. I will try.
Thanks Beka,
I have some issue with this solution. After purchase sometimes I got an error msg on the thank you page telling me that the item was removed from my cart because it can’t be purchased. I think it happens because woocommerce leaves the item in the cart after purchase and removes it only as the last step of the checkout. So there is a moment when the item is already purchased but the cart still contains the item. Is there any way to fix this?
Best,
Szilard
Can this script include guest checkout as well?
This would need to be done differently for guest users given that you don’t have access to an email address for them on product pages, so there’s nothing to check against to disable purchasing. Instead, the only place you could do this check is when “Place Order” is clicked and add warnings / empty the cart as needed, so it’s not really something this would assist with directly.
Hey Beka, thank you for the swift response and I can understand where you’re coming from. Looks like more thinking is going to have to go into this.
i try this code and its work well. but how to make Specific Product be able to purchase again after 10 days the user bought that ?
Hi,
First of all, tks a lot for all amazing snippets posted here in SkyVerge.
I tried to use this Disable Repeat WooCommerce Purchases for a Product Category Snippet but it’s not working as expected. Maybe due to changes in Woocommerce 3.3?
The problem is:
It’s just limiting for the same product (not for all products from Categories)
and
In every purchase is showing me an error message in the thankyou page…
Hi
Your snippets work well. But how to make disable purchasing for the entire category if one product is purchased