menu

Questions & Answers

Add a certain free gift depending on cart amounts in WooCommerce

I want to add a certain free gift, depending on cart amount in WooCommerce.

Let's say:

  • Less than 1500 - no free gift
  • Between or equal to 1500 - 1999 - add a free product (1)
  • Greater than or equal to 2000 - add another free product (2), remove free product (1)

Based on Add free gifted product for a minimal cart amount in WooCommerce answer code, which works if i add 1 element, but if i add more it stop working.

This is my code attempt:

// Add free gifted product for specific cart subtotal
add_action('woocommerce_before_calculate_totals', 'check_free_gifted_product');
function check_free_gifted_product($cart)
{
  if (is_admin() && !defined('DOING_AJAX'))
    return;

  // Settings
  $free_product_id   = 158;
  $targeted_subtotal = 1500;
  $targeted_subtotal_max = 2000;

  $cart_subtotal     = 0; // Initializing

  // Loop through cart items (first loop)
  foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
    // When free product is is cart
    if ($free_product_id == $cart_item['product_id']) {
      $free_key = $cart_item_key;
      $free_qty = $cart_item['quantity'];
      $cart_item['data']->set_price(0); // Optionally set the price to zero
    } else {
      $cart_subtotal += $cart_item['line_total'] + $cart_item['line_tax'];
    }
  }

  // If subtotal match and free product is not already in cart, add it
  if (!isset($free_key) && $cart_subtotal >= $targeted_subtotal && $cart_subtotal <= $targeted_subtotal_max) {
    $cart->add_to_cart($free_product_id);
  }
  // If subtotal doesn't match and free product is already in cart, remove it
  elseif (isset($free_key) && $cart_subtotal < $targeted_subtotal || $cart_subtotal > $targeted_subtotal_max) {
    $cart->remove_cart_item($free_key);
  }
  // Keep free product quantity to 1.
  elseif (isset($free_qty) && $free_qty > 1) {
    $cart->set_quantity($free_key, 1);
  }
}

Any adivce?

Answers(1) :

To add a free gift, depending on cart amount in WooCommerce, you can use the woocommerce_before_calculate_totals action hook

  • If cart amount is less than 1500. no free product(s) will be added
  • If cart amount is between or equal to 1500 - 1999, a free product (1) will be added
  • If cart amount is greater than or equal to 2000, a free product (2) will be added and free product (1) will be removed
function action_woocommerce_before_calculate_totals( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Free product productIDs
    $free_product_id_1 = 819;
    $free_product_id_2 = 821;
    
    // Minimum subtotal needed for free products
    $min_subtotal_free_product_1 = 1500;
    $min_subtotal_free_product_2 = 2000;

    // Initializing
    $cart_subtotal = 0;

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // When free product is is cart
        if ( $free_product_id_1 == $cart_item['product_id'] ) {
            $free_key_1 = $cart_item_key;
            $free_qty_1 = $cart_item['quantity'];
            // Optionally set the price to zero
            $cart_item['data']->set_price(0);
        } elseif ( $free_product_id_2 == $cart_item['product_id'] ) {
            $free_key_2 = $cart_item_key;
            $free_qty_2 = $cart_item['quantity'];
            // Optionally set the price to zero
            $cart_item['data']->set_price(0);
        } else {
            // NOT empty
            if ( ! empty ( $cart_item['line_total'] ) ) {
                $cart_subtotal += $cart_item['line_total'];
            }

            // NOT empty
            if ( ! empty ( $cart_item['line_tax'] ) ) {
                $cart_subtotal += $cart_item['line_tax'];
            }
        }
    }
    
    // If subtotal is less than first subtotal
    if ( $cart_subtotal < $min_subtotal_free_product_1 ) {
        // Free product 1 is already in cart, remove it
        if ( isset( $free_key_1 ) ) {
            $cart->remove_cart_item( $free_key_1 );
        }
        
        // Free product 2 is already in cart, remove it
        if ( isset( $free_key_2 ) ) {
            $cart->remove_cart_item( $free_key_2 );
        }
    }
    // If subtotal is between first and second subtotal
    elseif ( $cart_subtotal >= $min_subtotal_free_product_1 && $cart_subtotal < $min_subtotal_free_product_2 ) {
        // Free product 1 is not already in cart, add it
        if ( ! isset( $free_key_1 ) ) {
            $cart->add_to_cart( $free_product_id_1 );
        }
        
        // Free product 2 is in cart, remove it
        if ( isset( $free_key_2 ) ) {
            $cart->remove_cart_item( $free_key_2 );
        }
    }
    // If subtotal greater than or equal to second subtotal
    elseif ( $cart_subtotal > $min_subtotal_free_product_2 ) {
        // Free product 1 is already in cart, remove it
        if ( isset( $free_key_1 ) ) {
            $cart->remove_cart_item( $free_key_1 );
        }
        
        // Free product 2 is not already in cart, add it
        if ( ! isset( $free_key_2 ) ) {
            $cart->add_to_cart( $free_product_id_2 );
        }
    }   

    // Keep free product 1 quantity to 1.
    if ( isset( $free_qty_1 ) && $free_qty_1 > 1 ) {
        $cart->set_quantity( $free_key_1, 1 );
    }
    
    // Keep free product 2 quantity to 1.
    if ( isset( $free_qty_2 ) && $free_qty_2 > 1 ) {
        $cart->set_quantity( $free_key_2, 1 );
    }
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );