SkyVerge How-To: Prevent WooCommerce Checkout for Addon-Only Products
Are you using WooCommerce with the popular Product Add-ons plugin from SkyVerge (now part of Automattic) and finding that customers are checking out *only* with add-ons, leaving your core products behind? This can happen, especially if you’re offering substantial discounts on add-ons, or if the add-ons themselves seem valuable enough to stand alone. This article will guide you through preventing WooCommerce checkout when *only* product add-ons are in the cart. We’ll break it down simply, with examples and code you can easily implement.
The Problem: Add-ons Without Products
Imagine you sell high-end watches. You also offer accessories like watch straps, cleaning kits, and gift boxes as add-ons to your watch products. Now, imagine a customer lands on your site, sees a great deal on the watch cleaning kit addon, and adds *only* that to their cart, completely bypassing the watch itself. This can lead to:
- Lost Revenue: You’re missing out on the main product sale.
- Shipping Inefficiencies: Shipping a small, inexpensive add-on alone can be costly.
- Customer Dissatisfaction: The add-on might be less useful without the main product it’s intended for.
The Goal: We want to prevent users from completing the checkout process if their cart *only* contains add-ons. We need to ensure a “core” product is always present.
The Solution: Code Snippet to the Rescue!
We’ll use a simple code snippet that checks the contents of the WooCommerce cart before checkout. If it finds only add-on products, it will display an error message and prevent the customer from proceeding.
Step 1: Access Your `functions.php` File
The easiest way to add custom code to your WordPress/WooCommerce site is through your theme’s `functions.php` file. Important: Before making any changes to your `functions.php` file, create a backup! If you’re uncomfortable editing this file directly, consider using a plugin like “Code Snippets” (available in the WordPress plugin repository), which provides a safer and more organized way to add custom code.
Step 2: Add the Code Snippet
Copy and paste the following code snippet into your `functions.php` file (or the Code Snippets plugin):
/**
function prevent_checkout_with_addons_only() {
// Flag to track if only add-on products are in the cart.
$only_addons = true;
// Loop through each item in the cart.
foreach ( WC()->cart->get_cart() as $cart_item ) {
// Check if the product is *not* an add-on. Adjust this logic based on how your add-ons are configured.
// This example assumes add-on products have a specific product category: ‘addons’
if ( ! has_term( ‘addons’, ‘product_cat’, $cart_item[‘product_id’] ) ) {
// If it’s not an add-on, set the flag to false.
$only_addons = false;
break; // Exit the loop since we found a non-addon product.
}
}
// If only add-on products are in the cart.
if ( $only_addons ) {
// Remove the checkout button by showing an error message.
wc_add_notice( __( ‘Sorry, you can’t checkout with only add-on products. Please add a main product to your cart.’, ‘woocommerce’ ), ‘error’ );
//Disable Checkout button if only addon in cart
remove_action( ‘woocommerce_proceed_to_checkout’, ‘woocommerce_button_proceed_to_checkout’, 20 );
} else {
add_action( ‘woocommerce_proceed_to_checkout’, ‘woocommerce_button_proceed_to_checkout’, 20 );
}
}
add_filter(‘woocommerce_add_to_cart_validation’, ‘filter_product_page_redirect’, 10, 3);
function filter_product_page_redirect( $passed, $product_id, $qty ) {
$only_addons = true;
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( ! has_term( ‘addons’, ‘product_cat’, $cart_item[‘product_id’] ) ) {
$only_addons = false;
break; // Exit the loop since we found a non-addon product.
}
}
if ( $only_addons ) {
wc_clear_messages();
}
return $passed;
}
Step 3: Explanation of the Code
Let’s break down what this code does:
1. `add_action( ‘woocommerce_check_cart_items’, ‘prevent_checkout_with_addons_only’ );`: This line hooks our custom function (`prevent_checkout_with_addons_only`) into the `woocommerce_check_cart_items` action. This action runs just before the checkout process.
2. `$only_addons = true;`: We initialize a variable `$only_addons` to `true`. We’ll use this to track whether all items in the cart are add-ons.
3. `foreach ( WC()->cart->get_cart() as $cart_item ) { … }`: This loop iterates through each item in the customer’s shopping cart.
4. `if ( ! has_term( ‘addons’, ‘product_cat’, $cart_item[‘product_id’] ) ) { … }`: This is the crucial part! This line checks if the current product is *not* an add-on. It uses the `has_term()` function, which checks if a product has a specific term (like a category, tag, or attribute). In this example, we’re assuming that all add-on products belong to the product category “addons.” You’ll need to adjust this line based on how you categorize your add-on products.
- If the product *doesn’t* have the “addons” category (meaning it’s a regular, core product), we set `$only_addons` to `false` and `break` out of the loop because we’ve found a non-addon item.
5. `if ( $only_addons ) { … }`: After the loop completes, if `$only_addons` is still `true` (meaning we only found add-on products), we execute the code inside this `if` statement.
6. `wc_add_notice( __( ‘Sorry, you can’t checkout with only add-on products. Please add a main product to your cart.’, ‘woocommerce’ ), ‘error’ );`: This line adds an error message to the WooCommerce notices. The `__( … , ‘woocommerce’ )` part ensures the message is translatable (good for multilingual sites!).
7. `remove_action( ‘woocommerce_proceed_to_checkout’, ‘woocommerce_button_proceed_to_checkout’, 20 );`: This line removes the proceed to checkout button.
8. `add_action( ‘woocommerce_proceed_to_checkout’, ‘woocommerce_button_proceed_to_checkout’, 20 );`: This line add the proceed to checkout button if only addon is not in the cart.
9. `add_filter(‘woocommerce_add_to_cart_validation’, ‘filter_product_page_redirect’, 10, 3);`: This is to clear notices when clicking Add to Cart button in the product page if only addon is in the cart.
10. `wc_clear_messages();`: This line clears the notice added.
Customization and Considerations
- Adjust the Category/Tag/Attribute: The most important customization is the `has_term()` function. Make sure it accurately reflects how you identify your add-on products. If you use a product tag called “addon-product” instead of a category, you would change the line to:
if ( ! has_term( 'addon-product', 'product_tag', $cart_item['product_id'] ) ) { // ... }
- Specific Add-on Plugin Features: Some advanced Product Add-ons plugins might offer built-in settings to prevent this scenario. Check your plugin’s documentation before implementing this code. It’s possible there’s a simpler configuration option.
- User Experience: While preventing checkout is important, consider the user experience. Make it very clear why the customer cannot proceed. The error message should be informative and helpful. Consider adding a link to related products they might want to purchase.
- More complex logic: If you have more complex logic, let’s say you only want to prevent checkout if *specific* add-ons are the only items in the cart, you’ll need to modify the code to be more selective in its checks, you might need to loop over the add-ons and check its product ID for example.
Testing and Deployment
1. Test Thoroughly: Add only add-on products to your cart and verify that you cannot proceed to checkout and that the error message is displayed correctly. Then, add a core product and ensure that the checkout process works as expected.
2. Staging Environment: It’s always best practice to test any code changes in a staging environment before deploying them to your live website.
In Conclusion
By implementing this simple code snippet, you can effectively prevent customers from checking out with only add-on products in WooCommerce, protecting your revenue and ensuring a better customer experience. Remember to adapt the code to match your specific product setup and always test thoroughly!