How to add Free Gifts on Woocommerce Programmatically

how to add free gifts to woocommerce automatically with functions and php and love

A client wanted a free pack of blades to be automatically added to when a customer added 20 knives to their cart.

This seemed like good information to share for aspiring “woocommerce store owners / developers”.

If you have any questions, please feel free to reach out.

Planning

So here is what we have to do to get this to work.

  1. Write down the ID’s of the items you wish to target and the reward.
  2. Create a check for the condition (20 of the target in the cart)
  3. Add the reward if not already in the cart
  4. Make the reward free and check bugs.

Find the product ID’s

So first we need to learn which item’s we want to target. An easy way to find the ID is to login to the backend and go to the products tab.

Simple Products

Hover a product in the products tab to display the ID. Use that to target.

For simple products we need only to over the product to see it’s ID.

Variations

Variations as you know are individual products that make up a variable product.

To find the ID of a variation, edit a variable product, go to the variations tab and they will be listed on the left hand side.

Edit a variable product and go to the variations tab to find variation ID’s

So for our example, we are going to keep it simple and just use Pants, Shirts & a Hat.

  • Pants – ID: 553, Type: Variable
  • Hat – ID: 562, Type: Simple

I suggest you write your target & reward ID’s before proceeding, it will make customizing your code to work with your setup much easier, IMO.

Target the product ID’s

Now we will jump into the code.

First add this helper function we will use later to check if a product is in the cart.

function gerrg_get_product_cart_key( $product_id ){
	$product = wc_get_product( $product_id );

	if( ! $product ) return;

	return ( $product->is_type( 'variation' ) ) ? WC()->cart->generate_cart_id( $product->get_parent_id(), $product->get_id() ) : 
												  WC()->cart->generate_cart_id( $product->get_id() );
}

We are hooking into wp because we want this to run on every page load.

add_action( 'wp', 'gerrg_programically_add_to_cart' );

Open up your function and include a check to prevent this from running on the admin side (it causes an error).

function gerrg_programically_add_to_cart(){
	/**
	 * Looks for hard coded ID's in $targets array, check if ID meets product quantity and adds reward if so
	 */
	if( is_admin() ) return;

Next create a targets array, include the ID of all items you wish to target.

For variable products you must use the variation ID’s. I am targeting all sizes of a specific shirt.

These are the variations I am targetting. All sizes of a shirt.
// setup needles
$targets = array( 558, 559, 560, 561 );

Next set the reward, for me I am targeting a hat.

// free gift ID
$reward = 562;

This next bit is just a fancy woocommerce method of checking if something is in the cart.

We will use the helper method you added earlier to generate a cart key to pass to woocommerce to check for the item we are rewarding (otherwise they’d get so many!).

// key for quick searching in cart
$reward_item_key = WC()->cart->find_product_in_cart( gerrg_get_product_cart_key( $reward ) );

Now we will loop through the cart and look at EACH item in the cart.

foreach( WC()->cart->get_cart() as $cart_item ){

We make sure to use the ID given, sometimes working between different product types can cause problems.

// get real ID
$id = ( $cart_item['variation_id'] === 0 ) ? $cart_item['product_id'] : $cart_item['variation_id'];

Now we will loop through each ID in our $targets array.

// loop needles
foreach( $targets as $target ){

Now we are going to add the condition. In this specific circumstance, I need 3 things to be true.

  • The target ID is in the cart
  • That item has a quantity of 3 or more.
  • and finally, the reward is not ALREADY in the cart.
// if needle in haystack, quantity over 20 && reward not in cart
if( $target === $id && $cart_item['quantity'] >= 20 && ! $reward_item_key ){

Add the reward to the cart.

// Add reward
WC()->cart->add_to_cart( $reward );

Close everything up.

Discount the free gift

Now we are going to need to make that free gift free.

We have to hook into woocommerce_cart_calculate_fees to discount the free gift.

// this is where fees are calculated
		add_action('woocommerce_cart_calculate_fees', 'gerrg_discount_free_gift' ) );

Then add the following function

function discount_free_gift( $cart ){
		/**
		 * Look for free gift in cart, discount item if in cart.
		 * @param WC_Cart
		 */
	
		$product = wc_get_product( $this->reward );
	
		if( ! $product ) return;
		
		$reward_item_key = WC()->cart->find_product_in_cart( $this->get_product_cart_key( $this->reward ) );
	
		foreach( WC()->cart->get_cart() as $cart_item ){

			$id = ( $cart_item['variation_id'] === 0 ) ? $cart_item['product_id'] : $cart_item['variation_id'];

			foreach( $this->targets as $target ){

				if( $target === $id && $cart_item['quantity'] >= 20 && $reward_item_key ){

					// Meets all condititions? Add discount (fee).
					$cart->add_fee( 'Free Gift', ( $product->get_price() * -1), true  );
				}
			}
		}
	}

Very similar to the last function we loop the cart and check if the targets are in the cart, the quantity is met AND the reward is in the cart as well.

TL;DR

If you want to skip to the chase, download the plugin.

Table of Contents