Buy one get second 50% off for WooCommerce product variations
To get a 50% Off on the 2nd item for some specific product variations of a variable product, you will use the following instead:
add_action('woocommerce_cart_calculate_fees', 'add_custom_discount_2nd_at_50', 10, 1 );function add_custom_discount_2nd_at_50( $cart ){ if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; // YOUR SETTINGS: $product_variations_ids = array(1572, 1573); // <== HERE your targeted product variations // Initializing variables $discount = 0; $product_names = array(); // Loop through cart items foreach ( $cart->get_cart() as $key => $cart_item ) { if ( in_array( $cart_item['variation_id'], $product_variations_ids ) ) { $qty = (int) $cart_item['quantity']; $price = (float) $cart_item['data']->get_price(); $name = (string) $cart_item['data']->get_name(); if ( $qty > 1 ) { $discount -= number_format( $price / 2, 2 ); } elseif( $qty = 1 ) { $product_names[] = $name; } } } // Applying the discount if( $discount != 0 ){ $cart->add_fee('Buy one get one 50% off', $discount ); } // Display a custom reminder notice on cart page (otional) if( ! empty($product_names) ){ wc_clear_notices(); // clear other notices on checkout page. if( ! is_checkout() ){ wc_add_notice( sprintf( __( "Add one more to get 50%% off on the 2nd item for %s" ), '"<strong>' . implode(', ', $product_names) . '</strong>"' ), 'notice' ); } }}
Code goes in functions.php file of your active child theme (or active theme) Tested and works.
To get 1 item at 50% OFF for each item purchased, instead of 50% OFF on the 2nd item, replace:
$discount -= number_format( $price / 2, 2 );
by:
$multiplier = ( $qty % 2 ) === 0 ? $qty / 2 : ( $qty - 1 ) / 2;$discount -= number_format( $price / 2 * $multiplier, 2 );
To get the 2nd one Free instead of 50% OFF on the 2nd item, replace the code line:
$discount -= number_format( $price / 2, 2 );
by:
$discount -= $price;
To get 1 item free for each item purchased, instead of 50% OFF on the 2nd item, replace:
$discount -= number_format( $price / 2, 2 );
by:
$multiplier = ( $qty % 2 ) === 0 ? $qty / 2 : ( $qty - 1 ) / 2;$discount -= $price * $multiplier;
You were really close!
The discount amount calculation were wrong
add_action('woocommerce_cart_calculate_fees', 'add_custom_discount_2nd_at_50', 10, 1 );function add_custom_discount_2nd_at_50( $wc_cart ){if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;$discount = 0;$items_prices = array();$qty_notice = 0; // <== Added HERE// Set HERE your targeted variable product ID$targeted_product_id = 1571 ;foreach ( $wc_cart->get_cart() as $key => $cart_item ) { if( $cart_item['product_id'] == $targeted_product_id ){ $qty = intval( $cart_item['quantity'] ); $qty_notice += intval( $cart_item['quantity'] ); // <== Added HERE for( $i = 0; $i < $qty; $i++ ) $items_prices[] = floatval( $cart_item['data']->get_price()); }}$count_items_prices = count($items_prices);//to get the discount of lowest price sorting in descending order rsort($items_prices);if( $count_items_prices > 1 ) foreach( $items_prices as $key => $price ) if( $key % 2 == 1 ) $discount -= number_format($price / 2, 2 );if( $discount != 0 ){ // The discount # Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)$wc_cart->add_fee('50% off de segunda almohada' , (($price/2)*($discount))^⁻1, true ); //EDITED // Displaying a custom notice (optional) wc_clear_notices(); if(!is_checkout()){ wc_add_notice( __("Hurrah!! You got 50% off discount on the 2nd item"), 'notice');}}// Display a custom notice on cart page when quantity is equal to 1.elseif( $qty_notice == 1){ wc_clear_notices(); if(!is_checkout()){ wc_add_notice( __( "Add one more to get 50% off on 2nd item" ), 'notice');}}}