Search code examples
phpwordpresswoocommercecategoriescoupon

Mandatory coupon for specific product categories avoiding checkout in Woocommerce


I'm looking to create "invitation codes" using woocommerce smart coupons. To do so I want specific products to REQUIRE a coupon code at cart/ checkout. I have seen ways to to do this however they affect all products, not just the ones I want.

I'm trying to pass a returned variable to another function, however I cannot figure out how to do so.

Here's the latest version:

            //Check to see if user has product with a specific product category in cart    
    function check_product_in_cart() {

        global $woocommerce;

        //assigns a default negative value
        //  categories targeted 87, 18, 19

        $product_in_cart = false;

        // start of the loop that fetches the cart items

        foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
            $_product = $values['data'];
            $terms = get_the_terms( $_product->id, 'product_cat' );

            // second level loop search, in case some items have several categories
            foreach ($terms as $term) {
                $_categoryid = $term->term_id;
                if (( $_categoryid === 87 ) || ( $_categoryid === 18 ) || ( $_categoryid === 19 )) {
                    //category is in cart!
                    $product_in_cart = true;
                }
            }
        }

        return $product_in_cart;
   }  

// Force Coupon codes for Woocommerce
 add_action('woocommerce_check_cart_items', 'force_coupon_code');

    function force_coupon_code( $product_in_cart )
    {
        global $woocommerce;
        if(is_cart() || is_checkout()){
            $my_coupon = $woocommerce->cart->applied_coupons;
            echo $woocommerce->cart->get_applied_coupons;
            if(empty($my_coupon))
            {
                wc_add_notice( '<strong>' . $btn['label'] . '</strong> ' . __( 'A coupon code is mandatory for this product.', 'woocommerce' ), 'error' );
            }
        }
    }

The first part should return the product $product_in_cart and the second part forces the coupon. Here's the sources of the code I'm using. Mandatory Coupon code and Checking products in cart based on category. I read that placing the variable inside the new function args might achieve this like so, however it is by no means working.


Solution

  • Updated on 2018-04-01

    The code you are using is outdated and complicated. This can be done simply in one hooked function using instead Wordpress has_term() conditional function to detect if cart items belongs to specific product categories.

    So your code will be much more compact and efficient:

    // Force Coupon codes for Woocommerce
    add_action('woocommerce_check_cart_items', 'mandatory_coupon_code');
    function mandatory_coupon_code()
    {
            // set Here your categories IDs, slugs or names
            $categories = array(18,19,87);
            $found = false;
    
            // Loop through cart items
            foreach ( WC()->cart->get_cart() as $cart_item ) 
                if( has_term( $categories, 'product_cat', $cart_item['product_id'] ) ){
                    // Product category found in cart items
                    $found = true;
                    // Exit from loop
                    break;
                }
            }
            $coupons = WC()->cart->get_applied_coupons();
    
            // The Notice is displayed for that product categories when no mandatory coupon has been entered
            if( count( $coupons ) > 0 && $found )
                wc_add_notice( __( 'A coupon code is mandatory for this product.', 'woocommerce' ), 'error' );
        }
    }
    

    This code goes in function.php file of your active child theme (or active theme). Tested and works.


    Version for a specific coupon code and without product categories (for all products):

    add_action( 'woocommerce_check_cart_items', 'mandatory_coupon_code' );
    function mandatory_coupon_code() {
        // HERE set your coupon code
        $mandatory_coupon = 'spring10';
    
        $applied_coupons = WC()->cart->get_applied_coupons();
    
        // If coupon is found we exit
        if( in_array( $mandatory_coupon, $applied_coupons ) ) return;
    
        // Not found: display an error notice
        wc_add_notice( __( 'Please enter coupon code to checkout.', 'woocommerce' ), 'error' );
    }
    

    This code goes in function.php file of your active child theme (or active theme). Tested and works.