Blog

Prevent WooCommerce Checkout for Add-on Products

Today’s Ask SkyVerge question comes from Ian (I’m paraphrasing it a bit though):

Is there a way to prevent purchase if a customer only has certain products in the cart? I sell ink cartridges as add-ons for printers, but these should not be purchased alone. I tried using a grouped product, but a customer could only order cartridges or remove the main product from the cart. Can checkout require another category to be present?


Sure thing, this can be done! However, it’s not very straight-forward, so you’ll need a bit of familiarity with PHP to be able to achieve something like this. We’ll give you a starting point here, and if you wanted to take this further, the developers at Codeable do a great job with these sort of customizations.

This tutorial requires basic WordPress and PHP development skills.

A great example of this kind of set up is Amazon’s “Add on Items”. For smaller item purchases, Amazon won’t let you check out with only add-on items (such as personal care products) or other small purchases in your cart. You must purchase another item type, or meet a cart minimum.

If you want to set up a cart minimum value for purchase, this tutorial at Sell with WP can show you how the Min / Max Quantities plugin can be used to set minimums or sell product groups.

The category check is the tougher part here — we’ll need some custom code to check the categories of the products in the cart, and if only our “accessories” or “add-on items” category (in Ian’s case, ink-catridges) is present, we’ll block checkout.

Step 1: Check the WooCommerce Cart for a Product Category

We’ve got a previous tutorial that will help us out here: Checking if the WooCommerce cart contains a category

The second example in that tutorial can be used to check if all products in the cart are from a specific category. We’ll apply something similar to that here to see if the cart contains only products in the add-on category, and if so, block checkout until another category is present.

We’ll create a helper function called sv_wc_is_category_alone_in_cart() for checking the cart for our desired product category, and return true if all products are in our “Add on” category (the one we don’t want to allow checkout for).

function sv_wc_is_category_alone_in_cart( $category ) {
        
    // check each cart item for our category
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        
        // if a product is not in our category, bail out since we know the category is not alone
        if ( ! has_term( $category, 'product_cat', $cart_item['data']->id ) ) {
            return false;
        }
    }
        
    // if we're here, all items in the cart are in our category
    return true;
}

Step 2: Block Checkout if the Category is Alone

WooCommerce provides a simple way to block checkout: display an “error”-type notice.

The checkout class checks if any error notices are present, and if so, it throws an exception that lets WooCommerce block the checkout from happening.

This means all we need to do is check if our accessory or add-on product category is the only thing in the cart, and if so, display an error notice to stop checkout.

Here’s a snippet that uses our helper function from the previous step, and adds an error notice to the checkout if our category is alone in the cart. To use this snippet you’d replace the $category = 'clothing'; to use your category slug instead of clothing.

function sv_wc_prevent_checkout_for_category() {
    
    // set the slug of the category for which we disallow checkout
    $category = 'clothing';
    
    // get the product category
    $product_cat = get_term_by( 'slug', $category, 'product_cat' );
    
    // sanity check to prevent fatals if the term doesn't exist
    if ( is_wp_error( $product_cat ) ) {
        return;
    }
    
    $category_name = '<a href="' . get_term_link( $category, 'product_cat' ) . '">' . $product_cat->name . '</a>';
    
    // check if this category is the only thing in the cart
    if ( sv_wc_is_category_alone_in_cart( $category ) ) {
        
        // render a notice to explain why checkout is blocked
        wc_add_notice( sprintf( 'Hi there! Looks like your cart only contains products from the %1$s category – you must purchase a product from another category to check out.', $category_name ), 'error' );
    }
}
add_action( 'woocommerce_check_cart_items', 'sv_wc_prevent_checkout_for_category' );

Woohoo! Let’s walk through what this will look like. If the “Clothing” category is the only thing in my cart, the cart page will render a notice explaining this can’t be purchased alone.

WooCommerce cart: add-on products only

The checkout page also renders this notice, and does not allow the purchase to occur until the notice goes away.

WooCommerce Checkout: Add-on products only

Once another category is in the cart, the notice is now gone, and checkout can proceed.

WooCommerce Checkout: Add-on product with other category

You can have a look at the full code snippet here to prevent WooCommerce checkout if only add-on or “accessory” type products are being purchased — you just need to be sure these products are all in one category you can check for.

3 Comments

  • […] has a tutorial on blocking the WooCommerce checkout if the cart only contains a particular […]

  • Mike Devitt 5 months ago Reply

    Hi Beka, This is exactly what I was looking for except I cannot make the code work for me at all. I’ve added the disallowed category from the slug but there is no error message and I can still proceed to the checkout and buy the item. In effect, I’ve copied your full code snippet into my test wordpress install using the code snippet plugin and substituted your slug for the one I’d like to disallow. I’ve turned on debugging and there are no error messages either. I’m not using add-on products or accessories though. I’ve just created a normal product with it’s own category. Looking at the code I see no reason why this wouldn’t work though? Am I missing something?

  • frankikos 5 months ago Reply

    Hello, it’s a great article but I have a question: how can I limit one product by brand in the cart, using your logic this ?? I would like to do this?

    thank you
    Kiko – direct from Brazil

Submit a Comment