Skip to content

Automatically apply WooCommerce coupons based on cart quantity

Automatically apply WooCommerce coupons based on cart quantity

Whilst working on the brand new Hildon website I encountered an issue with WooCommerce coupons.

You can’t create quantity-based coupons out of the box and whilst this functionality is available through plugins such as Dynamic Pricing, I’m a cheap-skate who doesn’t want to pay for plugins when I can do something for free – plus programmatically creating/amending coupons allows for greater control.

The principle

In case you’re unaware, Hildon produce some of the purest Natural Mineral Water in the UK and you can find bottles of Hildon in some of the finest establishments and restaurants around the World. They sell their bottles of Natural Mineral Water in cases and that is how quantities are measured online.

Hildon only have two products – Delightfully Still Natural Mineral Water and Gently Sparkling Natural Mineral Water but there are up to 19 variations of those products.

A generous offer

Hildon like to reward their customers and they have a fantastic offer whereby if you order six or more cases of Natural Mineral Water, you get a 5% discount applied to your basket. If you order 12 or more cases, this offer increases to 10% off.

In practice

As mentioned already, discount-based coupons are not available in WooCommerce out of the box. Fear not – we can fix this issue quite easily.

Firstly – Create a WooCommerce coupon:

  1. Log in to WordPress and create a new coupon;
  2. Add a title for the coupon – this is important as it will be referenced in code;
  3. You can now set up the rest of the coupon as you normally would – i.e. Discount type, Discount amount etc; and finally
  4. Don’t set any “Usage restrictions” or “Usage limits” for the coupon as they’ll likely be ignored by our code.

Secondly – Check for individual use coupons:

I have created a function that checks whether or not a coupon set to “Individual use” is currently applied to the customer cart. It simply returns true if an individual use coupon is applied and a false if not. We’ll use this function in upcoming code.

You can grab this code from my GistYou’ll probably want to rename the function to something more meaningful to your theme or plugin.

Thirdly – Set our conditions and apply coupons:

Grab the gist for our second function.

Hook the function:

You’ll need to create a function that you can hook in to wp_head. We only want the code to run on the cart and checkout pages though – I’d recommend using the is_cart() and is_checkout() conditionals that ship with WooCommerce.

Check for individual use coupons:

I have then set up an additional conditional statement to check whether or not an “Individual use” coupon is currently applied to the cart – if it is, we don’t to apply the 5% or 10% discounts. A simple check using the hildon_is_individual_coupon_applied() function is all that’s required here.

Custom conditions for coupon use:

After this, you’ll need to set up the conditions in which you wish the coupon(s) to be applied. In my code sample you can see that we have two coupons (5% discount and 10% discount) which are applied under certain circumstances.

My code example works as follows:

  • If cart contains five or less units (cases of Natural Mineral Water for Hildon) –
    remove both coupons;
  • If cart contains between 6 and 11 cases
    apply the 5% discount and remove the 10% discount (only if applied); or
  • If cart contains 12 or more cases
    remove the 5% discount (if applied) and add the 10% discount.

Worth noting:

I have referenced the coupon names in variables so that if they change I only need update one location and not several.

The perfect solution?

I make no claim that this is the perfect solution for discount-based coupons in WooCommerce but it does have its advantages. It’s worked for our needs and has performed pretty well since the site has launched.

Have you got a better solution? Tweet us your ideas or comment on this post.

Code samples

Individual use coupon check:

<?php

	/**
	 * Automatically apply coupons for bulk discounts
	 *
	 * hildon_is_individual_coupon_applied()
	 * 		[a]	Get global class for woocommerce
	 * 		[b]	Get all Woo coupons that are set to individual use
	 * 		[c]	Loop through the coupons from [b]
	 * 		[d]	Get the title for each coupon
	 * 		[e]	Find out whether this coupon is currently applied in cart
	 * 			[f]	If coupon is applied, return true
	 * 			[g]	If coupon is not applied, return false
	 */
	
	function hildon_is_individual_coupon_applied() {
		global 	$woocommerce; // [a]
		

		$coupon_args = array(
			'posts_per_page'	=> -1,
			'orderby'			=> 'title',
			'order'				=> 'asc',
			'post_type'			=> 'shop_coupon',
			'post_status'		=> 'publish',
			'meta_key'			=> 'individual_use',
			'meta_value'		=> 'yes',
		);
		

		$coupons = get_posts($coupon_args); // [b]
		

		foreach ($coupons as $coupon) : // [c]
			$coupon_title = get_the_title($coupon); // [d]
			
			if ($woocommerce->cart->has_discount($coupon_title)) : return true; // [e][f]
			else : return false; // [e][g]
			endif;
		endforeach;
	}

?>

Coupon conditions code:

<?php

	/**
	 * Automatically apply coupons for bulk discounts
	 */

	function hildon_bulk_discount_coupons() {
		global 	$woocommerce; // [a]
		

		if (is_cart() || is_checkout()) :
			if (hildon_is_individual_coupon_applied() != true) :
				$coupon_five_percent = '5% discount'; // [b]
				$coupon_ten_percent  = '10% discount'; // [b]
				$cart_contents_count = $woocommerce->cart->cart_contents_count; // Get cart contents
				

				/**
				 * Check quantities and add coupons if valid
				 *
				 * [1]	If cart has 5 or less items
				 * 		[a]	Remove 5% coupon
				 * 		[b]	Remove 10% coupon
				 *
				 * [2]	If cart has between 6 and 11 items
				 * 		[a]	If 5% coupon is applied, do nothing
				 * 		[b]	If 10% coupon is applied
				 * 			[i]		Apply 5% coupon
				 * 			[ii]	Remove 10% coupon
				 * 		[c]	If neither coupon is applied
				 * 			[i]		Add 5% coupon
				 *
				 * [3]	If cart has 12 or more items
				 * 		[a]	If 5% coupon is applied
				 * 			[i]		Remove 5% coupon
				 * 			[ii]	Apply 10% coupon
				 * 		[b]	If 10% coupon is applied, do nothing
				 * 		[c]	If neither coupon is applied
				 * 			[i]		Add 10% coupon
				 */
				
				if ($cart_contents_count <= 5) : // [1]
					if ($woocommerce->cart->has_discount($coupon_five_percent)) : $woocommerce->cart->remove_coupon($coupon_five_percent); endif; // [1][a]
					if ($woocommerce->cart->has_discount($coupon_ten_percent)) :  $woocommerce->cart->remove_coupon($coupon_ten_percent); endif; // [1][b]
				

				elseif ($cart_contents_count >= 6 && $cart_contents_count <= 11) : // [2]
					if ($woocommerce->cart->has_discount($coupon_five_percent)) : // [2][a]
						// do nothing();
					
					elseif ($woocommerce->cart->has_discount($coupon_ten_percent)) : // [2][b]
						$woocommerce->cart->add_discount($coupon_five_percent); // [2][b][i]
						$woocommerce->cart->remove_coupon($coupon_ten_percent); // [2][b][ii]
					else : // [2][c]
						$woocommerce->cart->add_discount($coupon_five_percent); // [2][c][i]
					endif;
				

				else : // [3]
					if ($woocommerce->cart->has_discount($coupon_five_percent)) : // [3][a]
						$woocommerce->cart->remove_coupon($coupon_five_percent); // [3][a][i]
						$woocommerce->cart->add_discount($coupon_ten_percent); // [3][a][ii]
					
					elseif ($woocommerce->cart->has_discount($coupon_ten_percent)) : // [3][b]
						// do nothing();
					else : // [3][c]
						$woocommerce->cart->add_discount($coupon_ten_percent); // [3][c][i]
					endif;
				endif;
			

			else : // If individual coupons are applied, remove default coupons
				if     ($woocommerce->cart->has_discount($coupon_five_percent)) : $woocommerce->cart->remove_coupon($coupon_five_percent);
				elseif ($woocommerce->cart->has_discount($coupon_ten_percent)) :  $woocommerce->cart->remove_coupon($coupon_ten_percent);
				endif;
			endif;
		endif;
	}
	
	
	add_action('wp_head', 'hildon_bulk_discount_coupons');
	
?>

No comments

Add a comment

Start the conversation.
Be the first to comment.

Popular topics

On development

On best practice

On content strategy