Search code examples
phpwordpresswoocommerceproductcart

Add free gifted product for a minimal cart amount in WooCommerce


I want to give customers with orders above $50 a free gift. Not if a specific product is in the cart (there are some examples here on stackoverflow and below).

After some research I found the following code to add a free product if another specific product is added to the cart.

add_action( 'template_redirect', 'bbloomer_add_gift_if_id_in_cart' );
 
function bbloomer_add_gift_if_id_in_cart() {
 
   if ( is_admin() ) return;
   if ( WC()->cart->is_empty() ) return;
 
   $product_bought_id = 32;
   $product_gifted_id = 57;
 
   // see if product id in cart
   $product_bought_cart_id = WC()->cart->generate_cart_id( $product_bought_id );
   $product_bought_in_cart = WC()->cart->find_product_in_cart( $product_bought_cart_id );
 
   // see if gift id in cart
   $product_gifted_cart_id = WC()->cart->generate_cart_id( $product_gifted_id );
   $product_gifted_in_cart = WC()->cart->find_product_in_cart( $product_gifted_cart_id );
 
   // if not in cart remove gift, else add gift
   if ( ! $product_bought_in_cart ) {
      if ( $product_gifted_in_cart ) WC()->cart->remove_cart_item( $product_gifted_in_cart );
   } else {
      if ( ! $product_gifted_in_cart ) WC()->cart->add_to_cart( $product_gifted_id );
   }
}

Found here: https://www.businessbloomer.com/woocommerce-buy-1-product-add-free-product-cart-programmatically/

I also tried this code but it doesn't update if the cart changes:

function aapc_add_product_to_cart() {
    global $woocommerce;
    
    $cart_total = 50;   

    if ( $woocommerce->cart->total >= $cart_total ) {
        if ( ! is_admin() ) {
            $free_product_id = 12989;  // Product Id of the free product which will get added to cart
            $found      = false;

            //check if product already in cart
            if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
                foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
                    $_product = $values['data'];
                    if ( $_product->get_id() == $free_product_id )
                        $found = true;                  
                }
                // if product not found, add it
                if ( ! $found )
                    WC()->cart->add_to_cart( $free_product_id );
            } else {
                // if no products in cart, add it
                WC()->cart->add_to_cart( $free_product_id );
            }        
        }
    }        
}

add_action( 'template_redirect', 'aapc_add_product_to_cart' );

Is there any way to change that code to work with any product and limit only to the cart total?


Solution

  • Updated

    With the following, a free gifted product will be added to cart if subtotal is up to a specific amount:

    // 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   = 37;
        $targeted_subtotal = 50;
    
        $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->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->remove_cart_item( $free_key );
        }
        // Keep free product quantity to 1.
        elseif ( isset($free_qty) && $free_qty > 1 ) {
            $cart->set_quantity( $free_key, 1 );
        }
    }
    
    // Display free gifted product price to zero on minicart
    add_filter( 'woocommerce_cart_item_price', 'change_minicart_free_gifted_item_price', 10, 3 );
    function change_minicart_free_gifted_item_price( $price_html, $cart_item, $cart_item_key ) {
        $free_product_id   = 27;
        
        if( $cart_item['product_id'] == $free_product_id ) {
            return wc_price( 0 );
        }
        return $price_html;
    }
    

    Code goes in functions.php file of the active child theme (or active theme). Tested and works.


    On cart page (the free gifted product is "Beanie"):

    enter image description here

    On mini cart:

    enter image description here