Automatically add coupons to WooCommerce Basket

This article will take you through the process of how to extend WooCommerce coupons and automatically add them to customers basket if the conditions are met. The code in this article is a good base which can easily be extend to add extra conditions. WooCommerce has been built to easily allow developers to extend  and create useful extensions, as i previously showed you how to add a donation in woocommerce’s shopping basket.

Automatically add coupons to WooCommerce basket

When a users adds an item to the basket we want to check to see if they qualify for any coupons that are available, to do this we need to hook into WooCommerce’s woocommerce_cart_updated action, this is called when any modifications are made to the basket. Now we have identified how we can hook into WooCommerce basketed updates, we want to first check that coupons have been enabled and secondly only if they have do we want to fetch all the available coupons and apply those which are valid.

Lets go ahead and scaffold out the Auto Coupon extension class.

<?php
/**
 * Automatically add valid coupons to woocommerce basket
 *
 * @author James Collings <[email protected]>
 */
class JC_Auto_Coupon{
 
	/**
	 * Setup Auto coupon once woocommerce has been loaded
	 *
	 * @return void
	 */
	public function __construct(){
 
		add_action( 'woocommerce_init', array( $this, 'on_init' ) );
	}
 
	/**
	 * Setup Auto Coupon hooks
	 *
	 * @return void
	 */
	public function on_init(){
 
		add_action( 'woocommerce_cart_updated', array( $this, 'update_basket' ) );
	}
 
	/**
	 * Automatically add coupons to basket
	 *
	 * on basket update, check to see if any auto enabled coupons
	 * are valid for adding
	 *
	 * @return  void
	 */
	public function update_basket(){
 
		// check to see if coupons are enabled
		if(WC()->cart->coupons_enabled() !== true){
			return;
		}
 
		// stop nesting
		remove_action('woocommerce_cart_updated', array( $this, 'update_basket' ) );
 
		// plugin code goes here
	}
}
 
new JC_Auto_Coupon();

The above code automatically loads the JC_Auto_Coupon class, but only when WooCommerce has been initialized will the code be loaded by hooking into the “woocommerce_init” action, next as mentioned previously we hook into woocommerce basket updates and exit if coupons are disabled, otherwise we execute our auto coupon code. Now using WP_Query we can fetch all created coupons under the post_type shop_coupon, also we need to check that auto coupons have been enabled, to do this we check to see if a postmeta value has been set called “auto_enable_coupon”, once we have a list of coupons we can loop through them and check to see if they can be applied. The update basket function should now look like:

/**
 * Automatically add coupons to basket
 *
 * on basket update, check to see if any auto enabled coupons
 * are valid for adding
 *
 * @return  void
 */
public function update_basket(){
 
	// check to see if coupons are enabled
	if(WC()->cart->coupons_enabled() !== true){
		return;
	}
 
	// stop nesting
	remove_action('woocommerce_cart_updated', array( $this, 'update_basket' ) );
 
	// fetch all auto enabled coupons
	$query = new WP_Query(array(
		'post_type' => 'shop_coupon',
		'meta_query' => array(
			array(
				'key' => 'auto_coupon_enable',
				'value' => 'yes'
			)
		)
	));
 
	$coupons = array();
 
	while($query->have_posts()){
		$query->the_post();
 
		// get coupon code
		$coupon_code = get_the_title();
 
		// load coupon
		$coupon = new WC_Coupon($coupon_code);
 
		// check to see if coupon has not been already added and if it can be applied
		if($coupon->is_valid() && !WC()->cart->has_discount($coupon_code)){
			WC()->cart->add_discount($coupon_code);
		}
	}
 
	wp_reset_postdata();
}

To check that this works, all you need to do is comment out the meta_query argument passed to WP_Query, as this will fetch all coupons, even ones that have not had auto coupon enabled.

Updating WooCommerce admin screens to show automatic coupons settings

Now that coupons are automatically added to customers basket , we need to modify WooCommerce Coupon Management screens and display settings per coupon to enable automatic coupons and also hook into coupon save function and add the settings into WordPress postmeta table with the key auto_coupon_enable.

To start with lets update the on_init function to hook into woocommerce_coupon_data_tabs to add our new tab to the list, next hook into woocommerce_coupon_data_panels and output our enable automatic coupons checkbox when the automatic coupons tab is chosen, and last but not least hook into woocommerce_coupon_options_save to save our checkbox setting into the WordPress postmeta table.

<?php
public function on_init(){
 
	add_action( 'woocommerce_cart_updated', array( $this, 'update_basket' ) );
 
	// load admin hooks only when in admin area
	if(is_admin()){
 
		add_filter( 'woocommerce_coupon_data_tabs', array( $this, 'coupon_data_tabs') );
		add_action( 'woocommerce_coupon_data_panels', array( $this, 'coupon_data_panel' ) );
		add_action( 'woocommerce_coupon_options_save', array( $this, 'coupon_data_save' ) );
	}
}

Now that we have added in our hooks we need to create the functions, the following function coupon_data_tabs hooks extends an array of tabs, and adds in our new tab at the end of the list. Label sets the text that is displayed, target is what container the tab displays.

<?php
/**
 * Display coupon settings tab
 *
 * @param  array  $tabs
 * @return array
 */
public function coupon_data_tabs($tabs = array()){
 
	// add auto-coupon tab to list
	$tabs['auto-coupon'] = array(
		'label'  => __( 'Automatic Coupons', 'woocommerce' ),
		'target' => 'auto_coupon_data',
		'class'  => 'auto_coupon_data',
	);
 
	return $tabs;
}

coupon_data_panel function outputs our checkbox, we wrap our settings in a div with the same id as we setup as the target for our tab auto_coupon_data, the id of the woocommerce_wp_checkbox argument sets the name given to the value submitted from the form, this is the value we need to grab and insert into the WordPress postmeta table.

<?php
/**
 * Display coupon settings panel
 *
 * @return void
 */
public function coupon_data_panel(){
	?>
	<div id="auto_coupon_data" class="panel woocommerce_options_panel">
		<?php woocommerce_wp_checkbox( array(
			'id' => 'auto_coupon_enable',
			'label' => __( 'Allow auto adding of coupon', 'woocommerce' ),
			'description' => __( 'Check this option if you wish this coupon to be applied automatically when all conditions are met.', 'woocommerce')
		) ); ?>
	</div>
	<?php
}

To save our checkbox setting to the currently edited coupon we need to add capture the $_POST data save it, only when the checkbox has been checked will the post data be submitted so we check to see if it has been set, and save the strings yes or no into the database.

<?php
/**
 * Save auto_coupon_enable field
 *
 * @param  int $post_id
 * @return void
 */
public function coupon_data_save($post_id = null){
 
	$auto_coupon_enable = isset( $_POST['auto_coupon_enable'] ) ? 'yes' : 'no';
	update_post_meta( $post_id, 'auto_coupon_enable', $auto_coupon_enable );
}

Now if eveything works correctly you should see a new tab under the WooCommerce coupon edit screen.

Edit Coupon ‹ WP Dev — WordPress

Automatically Add Coupons to WooCommerce basket – Source Code

If you have managed to get confused along the way of this article, or would like to copy the whole code:

<?php
/**
 * Automatically add valid coupons to woocommerce basket
 *
 * @author James Collings <[email protected]>
 */
class JC_Auto_Coupon{
 
	/**
	 * Setup Auto coupon once woocommerce has been loaded
	 *
	 * @return void
	 */
	public function __construct(){
 
		add_action( 'woocommerce_init', array( $this, 'on_init' ) );
	}
 
	/**
	 * Setup Auto Coupon hooks
	 *
	 * @return void
	 */
	public function on_init(){
 
		add_action( 'woocommerce_cart_updated', array( $this, 'update_basket' ) );
 
		// load admin hooks only when in admin area
		if(is_admin()){
 
			add_filter( 'woocommerce_coupon_data_tabs', array( $this, 'coupon_data_tabs') );
			add_action( 'woocommerce_coupon_data_panels', array( $this, 'coupon_data_panel' ) );
			add_action( 'woocommerce_coupon_options_save', array( $this, 'coupon_data_save' ) );
		}
	}
 
	/**
	 * Automatically add coupons to basket
	 *
	 * on basket update, check to see if any auto enabled coupons
	 * are valid for adding
	 *
	 * @return  void
	 */
	public function update_basket(){
 
		// check to see if coupons are enabled
		if(WC()->cart->coupons_enabled() !== true){
			return;
		}
 
		// stop nesting
		remove_action('woocommerce_cart_updated', array( $this, 'update_basket' ) );
 
		// fetch all auto enabled coupons
		$query = new WP_Query(array(
			'post_type' => 'shop_coupon',
			'meta_query' => array(
				array(
					'key' => 'auto_coupon_enable',
					'value' => 'yes'
				)
			)
		));
 
		$coupons = array();
 
		while($query->have_posts()){
			$query->the_post();
 
			// get coupon code
			$coupon_code = get_the_title();
 
			// load coupon
			$coupon = new WC_Coupon($coupon_code);
 
			// check to see if coupon has not been already added and if it can be applied
			if($coupon->is_valid() && !WC()->cart->has_discount($coupon_code)){
				WC()->cart->add_discount($coupon_code);
			}
		}
 
		wp_reset_postdata();
	}
 
	/**
	 * Display coupon settings tab
	 *
	 * @param  array  $tabs
	 * @return array
	 */
	public function coupon_data_tabs($tabs = array()){
 
		// add auto-coupon tab to list
		$tabs['auto-coupon'] = array(
			'label'  => __( 'Automatic Coupons', 'woocommerce' ),
			'target' => 'auto_coupon_data',
			'class'  => 'auto_coupon_data',
		);
 
		return $tabs;
	}
 
	/**
	 * Display coupon settings panel
	 *
	 * @return void
	 */
	public function coupon_data_panel(){
		?>
		<div id="auto_coupon_data" class="panel woocommerce_options_panel">
			<?php woocommerce_wp_checkbox( array(
				'id' => 'auto_coupon_enable',
				'label' => __( 'Allow auto adding of coupon', 'woocommerce' ),
				'description' => __( 'Check this option if you wish this coupon to be applied automatically when all conditions are met.', 'woocommerce')
			) ); ?>
		</div>
		<?php
	}
 
	/**
	 * Save auto_coupon_enable field
	 *
	 * @param  int $post_id
	 * @return void
	 */
	public function coupon_data_save($post_id = null){
 
		$auto_coupon_enable = isset( $_POST['auto_coupon_enable'] ) ? 'yes' : 'no';
		update_post_meta( $post_id, 'auto_coupon_enable', $auto_coupon_enable );
	}
}
 
new JC_Auto_Coupon();
?>


Liked this article? help spread the word.