skip to Main Content

I need to force a minimum order amount for just some categories in WooCommerce, and therefore set an alert in the cart and checkout pages.

So far I managed to set an alert if the total amount in the cart is lower than the minimum amount set, but I can’t manage to create a category based filter. Actually any other product is added in the cart the alert is overtaken and the user is allowed to buy the product of that category I want to limit.

Here is the code:

/**
 * Set a minimum order amount for checkout
 */
add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_cart' , 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_checkout' , 'wc_minimum_order_amount' );
 
function wc_minimum_order_amount() {
    // Set this variable to specify a minimum order value
    $minimum = 30;
    // set array with cat IDs
    $category_ids = array( 336, 427, 433 );
    // set bool that checks is minimum amount has been reached
    $needs_minimum_amount = false; // Initializing

    $subTotal_amount = WC()->cart->subtotal; // Items subtotal including taxes
    $total_amount = WC()->cart->total; // Items subtotal excluding taxes

            if ( $total_amount < $minimum ) { 
              
              // Loop through cart items
              foreach ( WC()->cart->get_cart() as $cart_item ) {
                $product_id   = $cart_item['product_id'];
                $variation_id = $cart_item['variation_id']; 

                // Check for matching product categories
                  if( sizeof($category_ids) > 0 ) {
                      $taxonomy = 'product_cat';
                      if ( has_term( $category_ids, $taxonomy, $product_id ) ) { 
                          $needs_minimum_amount = true;
                          break; // Stop the loop
                      }
                  }
              }

              if( $needs_minimum_amount ) {

                  if( is_cart()) {

                    wc_print_notice( 
                        sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order ' , 
                            wc_price( WC()->cart->total ), 
                            wc_price( $minimum )
                        ), 'error' 
                    );

                  } else {

                    wc_add_notice( 
                        sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order' , 
                            wc_price( WC()->cart->total ), 
                            wc_price( $minimum )
                        ), 'error' 
                    );

                  }

              }
    }
}

References:

Any help?

2

Answers


  1. Chosen as BEST ANSWER

    Finally I found the solution working a little on the code provided by @LoicTheAztec.

    Below the final code. Tested and working.

    // Set a minimum order amount for checkout
    add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
    add_action( 'woocommerce_before_cart' , 'wc_minimum_order_amount' );
    // add_action( 'woocommerce_before_checkout' , 'wc_minimum_order_amount' );
     
    function wc_minimum_order_amount() {
        $min_amount = 30; // Set this variable to specify a minimum order value
        $taxonomies = array('product_cat'); // Product category taxonomy | For product tags use 'product_tag'
        $term_ids = array( 336, 427, 433 ); // Category terms (can be Ids, slugs, or names)
      
        $found = false; // Initializing // set bool that checks if minimum amount has been reached
        
        $subtotal  = 0; // Initializing // set subtotal formed by specific category total (incl. taxes)
        $subTotal_amount = WC()->cart->subtotal; // Items subtotal including taxes
        $total_amount = WC()->cart->total; // Items subtotal including taxes    
    
        // 1 - Loop through cart items targeting those having that specific category
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            if ( has_term( $term_ids, $taxonomies[0], $cart_item['product_id'] ) ) {
                $subtotal += $cart_item['line_subtotal'] + $cart_item['line_subtotal_tax'];                      
            }
        }
    
        // 2 - Check if at least one product of that category is in the cart
        if($subtotal > 0){
          $found = true;
        }
    
        // 2 - check if subtotal is below the min amount set
         if ( $subtotal < $min_amount ) { 
    
                if( $found ) {
    
                    $message = sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order ' , 
                        wc_price( $subtotal ), 
                        wc_price( $min_amount )
                    );
    
                    if( is_cart()) {
    
                      wc_print_notice( $message, 'error' );
    
                    } else {
    
                      wc_add_notice( $message, 'error' );
    
                    }
    
                
             }
        }
    }
    

  2. There are some mistakes in your code… Use the following instead:

    add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
    add_action( 'woocommerce_before_cart', 'wc_minimum_order_amount' );
    add_action( 'woocommerce_before_checkout_form', 'wc_minimum_order_amount' );
    function wc_minimum_order_amount() {
        $min_amount = 30; // Min subtotal required
        $taxonomy   = 'product_cat'; // Product category taxonomy | For product tags use 'product_tag'
        $terms      = array( 336, 427, 433 ); // Category terms (can be Ids, slugs, or names)
        $found      = false; // Initializing
    
        $subtotal   = WC()->cart->subtotal; // Incl. taxes
        $total      = WC()->cart->total; // Incl. taxes
    
        if ( $total < $min_amount ) { 
            // Loop through cart items
            foreach ( WC()->cart->get_cart() as $cart_item ) {
                if ( has_term( $terms, $taxonomy, $cart_item['product_id'] ) ) { 
                    $found = true;
                    break; // Stop the loop
                }
                
                if( $found ) {
                    $message = sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order ' , 
                        wc_price( $total ), 
                        wc_price( $min_amount )
                    );
                    
                    if( is_cart()) {
                        wc_print_notice( $message, 'error' );
                    } else {
                        wc_add_notice( $message, 'error' );
                    }
                }
            }
        }
    }
    

    Code goes in functions.php file of the active child theme (or active theme). It should work.


    Addition: Based on specific subtotal incl. taxes

    This code version is based on items subtotal belonging to specific defined categories:

    add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
    add_action( 'woocommerce_before_cart', 'wc_minimum_order_amount' );
    add_action( 'woocommerce_before_checkout_form', 'wc_minimum_order_amount' );
    function wc_minimum_order_amount() {
        $min_amount = 30; // Min subtotal required
        $taxonomy   = 'product_cat'; // Product category taxonomy | For product tags use 'product_tag'
        $terms      = array( 336, 427, 433 ); // Category terms (can be Ids, slugs, or names)
        
        $subtotal   = 0; // Initializing
    
        // Loop through cart items
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            if ( has_term( $terms, $taxonomy, $cart_item['product_id'] ) ) {
                $subtotal += $cart_item['line_subtotal'] + $cart_item['line_subtotal_tax'];
            }
        }
    
        if ( $subtotal < $min_amount ) {
            if( $found ) {
                $message = sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order ' ,
                    wc_price( $total ),
                    wc_price( $min_amount )
                );
    
                if( is_cart()) {
                    wc_print_notice( $message, 'error' );
                } else {
                    wc_add_notice( $message, 'error' );
                }
            }
        }
    }
    

    It should works.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search