In WooCommerce, I would like to make a discount without using coupons, and the discount calculation will be based on product price, with something like "take 3 products for the price of 2.
In function.php of my active theme I am using this code:
function promo () {
if (is_cart()) {
$woocommerce->cart->add_fee( __('des', 'woocommerce'), -50.00`enter code here`, true, '');
}
}
add_action ('woocommerce_cart_calculate_fees', 'promo');
My problem: This code doesn't work on checkout page.
If I force in review-order the discount appears, but the total value don't change. I think its not saving the fee.
How can I make it work (on checkout page)?
Thanks
This hook is made for cart fees (or discounts), so you have to remove if (is_cart()) { condition, that why it's not working…
Here is the correct functional code to achieve a "Buy 2 take 3" discount, that will make a discount based on line item quantity:
add_action('woocommerce_cart_calculate_fees' , 'discount_2_for_3', 10, 1);
function discount_2_for_3( $cart_object ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Initialising variable
$discount = 0;
// Iterating through cart items
foreach( $cart_object->get_cart() as $cart_item ){
// Getting item data from cart object
$item_id = $cart_item['product_id']; // Item Id or product ID
$item_qty = $cart_item['quantity']; // Item Quantity
$product_price = $cart_item['data']->price; // Product price
$line_total = $cart_item['line_total']; // Price x Quantity total line item
// THE DISCOUNT CALCULATION
if($item_qty >= 3){
// For each item quantity step of 3 we add 1 to $qty_discount
for($qty_x3 = 3, $qty_discount = 0; $qty_x3 <= $item_qty; $qty_x3 += 3, $qty_discount++);
$discount -= $qty_discount * $product_price;
}
}
// Applied discount "2 for 3"
if( $discount != 0 ){
// Note: Last argument is related to applying the tax (false by default)
$cart_object->add_fee( __('Des 2 for 3', 'woocommerce'), $discount, false);
}
}
This will work for simple products, but not for product variations…
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Code is tested and works.
Related
My WP site sells customized t-shirts. The customization plugin makes each customized shirt a line item in the woocommerce cart. If there are 2 shirts ordered of one design (quantity of 2 on that line item) I want to discount. But if there is just 1 item per line I dont want to discount.
I found this solution
Adding a discount by cart items conditionally based on the item quantity
But this seems to change the product price in the db, so after the discount kicks in for say 2 blue shirts because there were 2 ordered on 1 line, if I add a 3rd shirt on a separate line it also gets the discount, which I dont want.
Since woocommerce version 3+ the linked answer code doesn't work. It needs something different and can even be done in a better way.
The code will apply a cart item discount based on the cart item quantity. In this code example, it will apply a discount of 5% on the cart item, when the quatity is equal or more than 2 (two).
The cart item unit price displayed is always the real product price. The discount will be effective and displayed on the cart item subtotal.
Additionally the product name will be appended with a discount mention.
The code:
add_filter('woocommerce_add_cart_item_data', 'add_items_default_price_as_custom_data', 20, 3 );
function add_items_default_price_as_custom_data( $cart_item_data, $product_id, $variation_id ){
$product_id = $variation_id > 0 ? $variation_id : $product_id;
## ----- YOUR SETTING ----- ##
$discount_percentage = 5; // Discount (5%)
// The WC_Product Object
$product = wc_get_product($product_id);
// Only for non on sale products
if( ! $product->is_on_sale() ){
$price = (float) $product->get_price();
// Set the Product default base price as custom cart item data
$cart_item_data['base_price'] = $price;
// Set the Product discounted price as custom cart item data
$cart_item_data['new_price'] = $price * (100 - $discount_percentage) / 100;
// Set the percentage as custom cart item data
$cart_item_data['percentage'] = $discount_percentage;
}
return $cart_item_data;
}
// Display the product original price
add_filter('woocommerce_cart_item_price', 'display_cart_items_default_price', 20, 3 );
function display_cart_items_default_price( $product_price, $cart_item, $cart_item_key ){
if( isset($cart_item['base_price']) ) {
$product = $cart_item['data'];
$product_price = wc_price( wc_get_price_to_display( $product, array( 'price' => $cart_item['base_price'] ) ) );
}
return $product_price;
}
// Display the product name with the discount percentage
add_filter( 'woocommerce_cart_item_name', 'append_percetage_to_item_name', 20, 3 );
function append_percetage_to_item_name( $product_name, $cart_item, $cart_item_key ){
if( isset($cart_item['percentage']) && isset($cart_item['base_price']) ) {
if( $cart_item['data']->get_price() != $cart_item['base_price'] )
$product_name .= ' <em>(' . $cart_item['percentage'] . '% discounted)</em>';
}
return $product_name;
}
add_action( 'woocommerce_before_calculate_totals', 'custom_discounted_cart_item_price', 20, 1 );
function custom_discounted_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
## ----- YOUR SETTING ----- ##
$targeted_qty = 2; // Targeted quantity
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
// For item quantity of 2 or more
if( $cart_item['quantity'] >= $targeted_qty && isset($cart_item['new_price']) ){
// Set cart item discounted price
$cart_item['data']->set_price($cart_item['new_price']);
}
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
To display the discounted product price instead of the original product price, just remove woocommerce_cart_item_price() function (and hook)…
Newest similar: Cart item quantity progressive percentage discount in Woocommerce 3
I came here from this question here looking to find a solution for my WooCommerce site. I am looking for a way to get a discount in my cart only for even number of items in the cart.
For example:
If there's only 1 item in the cart: Full Price
2 Items in the cart: - (minus) 2$ for both of it
5 Items in the cart: - (minus) 2$ for 4 of it (if there's odd number of items in the cart. 1 item will always have the full price)
By the way, all of my products are having the same price.
Would someone be able to help me on this, as someone helped for the guy on the question link I've mentioned?
Here is your custom function hooked in woocommerce_cart_calculate_fees action hook, that will do what you are expecting:
add_action( 'woocommerce_cart_calculate_fees','cart_conditional_discount', 10, 1 );
function cart_conditional_discount( $cart_object ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$cart_count = 0;
foreach($cart_object->get_cart() as $cart_item){
// Adds the quantity of each item to the count
$cart_count += $cart_item["quantity"];
}
// For 0 or 1 item
if( $cart_count < 2 ) {
return;
}
// More than 1
else {
// Discount calculations
$modulo = $cart_count % 2;
$discount = (-$cart_count + $modulo);
// Adding the fee
$discount_text = __('Discount', 'woocommerce');
$cart_object->add_fee( $discount_text, $discount, false );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.
In my WooCommerce website I have a few products with the same price of 80$.
I want to add a Discount by the products quantity.
The logic is like that:
if (Products Quantity is 2){
// the original product price change from 80$ to 75$ each.
}
if(Products Quantity is 3 or more){
//the original product price change from 80$ to 70$ each.
}
for example,
if a customer pick 2 products, the original price will be (80$ x 2) => 160$.
But after the discount, it will be: (75$ x 2) => 150$.
And…
if visitor pick 3 products, the original price will be (80$ x 3) => 240$.
But after the fee, it will be: (70$ x 3) => 210$.
Any help, please?
Thanks
This custom hooked function should do what you expect. You can set in it your progressive discount limit based on individual item quantity.
Here is the code
## Tested and works on WooCommerce 2.6.x and 3.0+
add_action( 'woocommerce_cart_calculate_fees', 'progressive_discount_by_item_quantity', 10, 1 );
function progressive_discount_by_item_quantity( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
# Progressive quantity until quantity 3 is reached (here)
# After this quantity limit, the discount by item is fixed
# No discount is applied when item quantity is equal to 1
// Set HERE the progressive limit quantity discount
$progressive_limit_qty = 3; // <== <== <== <== <== <== <== <== <== <== <==
$discount = 0;
foreach( $cart->get_cart() as $cart_item_key => $cart_item ){
$qty = $cart_item['quantity'];
if( $qty <= $progressive_limit_qty )
$param = $qty; // Progressive
else
$param = $progressive_limit_qty; // Fixed
## Calculation ##
$discount -= 5 * $qty * ($param - 1);
}
if( $discount < 0 )
$cart->add_fee( __( 'Quantity discount' ), $discount); // Discount
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Tested and works on WooCommerce 2.6.x and 3.0+
In WooCommerce, I would like to give a discount of 10% specifically for those products that are not on sale. If cart item count is 5 or more items and not on sale, then I give a discount of 10%.
I use the following code to get a discount based on cart item count restriction here:
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
/**
* Add custom fee if more than three article
* #param WC_Cart $cart
*/
function add_custom_fees( WC_Cart $cart ){
if( $cart->cart_contents_count < 5 ){
return;
}
// Calculate the amount to reduce
$discount = $cart->subtotal * 0.1;
$cart->add_fee( '10% discount', -$discount);
}
But I don't know how to apply the discount only for items that are not in sale. How can I achieve it?
Thanks.
Here is a custom hooked function that will apply to cart a discount, if there is 5 or more items in cart and no products on sale:
add_action('woocommerce_cart_calculate_fees' , 'custom_discount', 10, 1);
function custom_discount( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Only when there is 5 or more items in cart
if( $cart->get_cart_contents_count() >= 5):
// Initialising variable
$is_on_sale = false;
// Iterating through each item in cart
foreach( $cart->get_cart() as $cart_item ){
// Getting an instance of the product object
$product = $cart_item['data'];
// If a cart item is on sale, $is_on_sale is true and we stop the loop
if($product->is_on_sale()){
$is_on_sale = true;
break;
}
}
## Discount calculation ##
$discount = $cart->subtotal * -0.1;
## Applied discount (no products on sale) ##
if(!$is_on_sale )
$cart->add_fee( '10% discount', $discount);
endif;
}
This code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works perfectly.
In WooCommerce, I have a category of products called Samples, each sample costs $2.99.
But I'd like a way to automatically change the cost of the Samples from $2.99 to $1 when 5 Samples are added to cart.
So if 4 samples are added to cart, the total would be $11.96… but if 5 were added the total would be $5.
So for every 5 products, the product price would change from $2.99 to $1 but if 6 Samples were added to cart the total would be $7.99 and if 10 were added the total would be $10 etc...
How could I achieve this?
Thanks.
Update — Added Woocommerce 3 compatibility.
Here is something that should be convenient to your requirements.
This function will add discount to cart:
add_action( 'woocommerce_cart_calculate_fees','custom_cart_discount', 20, 1 );
function custom_cart_discount( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Define HERE your targeted product category (id, slug or name are accepted)
$category = 'posters';
// Set the price for Five HERE
$price_x5 = 5;
// initializing variables
$calculated_qty = 0;
$calculated_total = 0;
$discount = 0;
// Iterating through each cart item
foreach($cart->get_cart() as $cart_item):
// Make this discount calculations only for products of your targeted category
if(has_term($category, 'product_cat', $cart_item['product_id'])):
$item_price = version_compare( WC_VERSION, '3.0', '<' ) ? $cart_item['data']->price : $cart_item['data']->get_price(); // The price for one (assuming that there is always 2.99)
$item_qty = $cart_item["quantity"];// Quantity
$item_line_total = $cart_item["line_total"]; // Item total price (price x quantity)
$calculated_qty += $item_qty; // ctotal number of items in cart
$calculated_total += $item_line_total; // calculated total items amount
endif;
endforeach;
// ## CALCULATIONS (updated) ##
if($calculated_qty >= 5):
for($j = 5, $k=0; $j <= $calculated_qty; $j+=5,$k++); // Update $k=0 (instead of $k=1)
$qty_modulo = $calculated_qty % 5;
$calculation = ( $k * $price_x5 ) + ($qty_modulo * $item_price);
$discount -= $calculated_total - $calculation;
endif;
// Adding the discount
if ($discount != 0)
$cart->add_fee( __( 'Quantity discount', 'woocommerce' ), $discount, false );
// Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.