Skip to content

Recently I came across an interesting problem while creating a Holiday Catering ordering system for Gus’s Market using WooCommerce. The page uses the WooCommerce One Page Checkout extension as well as a custom checkout template to move the checkout onto a second page. The page also has multiple products with minimum quantities. 

Unfortunately the Min/Max Quantities extension is not fully compatible with One Page Checkout at the time of writing, so that wasn’t an option.  (It requires that every product with a minimum quantity be ordered. So if you’ve got a minimum quantity of 5 pounds for the roast beef, you can’t just not order roast beef even though you’re a vegetarian and just wanted 10 pounds of mashed potatoes.)

In looking for quick, existing code to use online, I came across several references to a custom spyr_set_min_qty_per_product function which I’ve included below for search purposes. Do yourself a favor and keep reading however, as the code doesn’t work correctly.

// Set minimum quantity per product before checking out
add_action( 'woocommerce_check_cart_items', 'spyr_set_min_qty_per_product' );
function spyr_set_min_qty_per_product() {
	// Only run in the Cart or Checkout pages
	if( is_cart() || is_checkout() ) {	
		global $woocommerce;

		// Product Id and Min. Quantities per Product
		$product_min_qty = array( 
			array( 'id' => 20, 'min' => 100 ),
			array( 'id' => 30, 'min' => 100 ),
			array( 'id' => 40, 'min' => 100 ),
			array( 'id' => 50, 'min' => 100 ),
		);

		// Will increment
		$i = 0;
		// Will hold information about products that have not
		// met the minimum order quantity
		$bad_products = array();

		// Loop through the products in the Cart
		foreach( $woocommerce->cart->cart_contents as $product_in_cart ) {
			// Loop through our minimum order quantities per product
			foreach( $product_min_qty as $product_to_test ) {
				// If we can match the product ID to the ID set on the minimum required array
				if( $product_to_test['id'] == $product_in_cart['product_id'] ) {
					// If the quantity required is less than than the quantity in the cart now
					if( $product_in_cart['quantity'] < $product_to_test['min'] ) { // Get the product ID $bad_products[$i]['id'] = $product_in_cart['product_id']; // Get the Product quantity already in the cart for this product $bad_products[$i]['in_cart'] = $product_in_cart['quantity']; // Get the minimum required for this product $bad_products[$i]['min_req'] = $product_to_test['min']; } } } // Increment $i $i++; } // Time to build our error message to inform the customer // About the minimum quantity per order. if( is_array( $bad_products) && count( $bad_products ) > 1 ) {
			// Lets begin building our message
			$message = '<strong>A minimum quantity per product has not been met.</strong>';
			foreach( $bad_products as $bad_product ) {
				// Append to the current message
				$message .= get_the_title( $bad_product['id'] ) .' requires a minimum quantity of '
						 . $bad_product['min_req'] 
						 .'. You currently have: '. $bad_product['in_cart'] .'.';
			}
			wc_add_notice( $message, 'error' );
		}
	}
}

The code almost works correctly – in that it works occasionally based on having multiple “bad products” in your cart at the same time. We’ve fixed the issue and provided updated, working code below following the same logic:

  • Go through the products in the cart.
  • Check if any of them requires a minimum quantity.
  • When a product below the minimum quantity is found, add it to a list of “bad” products.
  • If the “bad” list contains at least one product, show the error message.
// Set minimum quantity per product before checking out
function razorfrog_set_min_qty_per_product() {
	// Only run in the Cart or Checkout pages
	if( is_cart() || is_checkout() ) {
		// Product Id and Min. Quantities per Product
		$product_min_qty = array(
			20 => 100,
			30 => 100,
			40 => 100,
			50 => 100,
		);

		// Will hold information about products that have not
		// met the minimum order quantity
		$bad_products = array();

		// Loop through the products in the Cart
		foreach( wc()->cart->cart_contents as $product_in_cart ) {
			$product_id = $product_in_cart['product_id'];

			// If there is a minimum quantity for the product and the cart item is below such quantity, add the cart item's product to the "bad" list
			if( isset( $product_min_qty[$product_id] ) && ( $product_in_cart['quantity'] < $product_min_qty[$product_id] ) ) { $bad_products[] = array( 'id' => $product_id,
					'in_cart' => $product_in_cart['quantity'],
					'min_req' => $product_min_qty[$product_id],
				);
			}
		}

		// Time to build our error message to inform the customer about the minimum quantity per order.
		if( !empty( $bad_products ) ) {
			// Lets begin building our message
			$message = '<strong>A minimum quantity per product has not been met.</strong>
';
			foreach( $bad_products as $bad_product ) {
				// Append to the current message
				$message .= get_the_title( $bad_product['id'] ) .' requires a minimum quantity of '
						 . $bad_product['min_req']
						 .' lbs. You currently have: '. $bad_product['in_cart'] .'
';
			}
			wc_add_notice( $message, 'error' );
		}
	}
}
add_action( 'woocommerce_check_cart_items', 'razorfrog_set_min_qty_per_product' );

Feel free to let us know in the comments if you find the code useful or have any questions!

Max Elman is Razorfrog's Founder and Project Manager. He is a tech-savvy internet guru and has led Razorfrog's award-winning web design team since 2008. View Max's bio for more details.

Toggle light/dark mode

Back To Top