I created a function for adding a fee to the Woocommerce cart. It works partially, but displays the lowest fee. It just ignores the condition of <= 550 and the highest fee. Does anyone have an idea how to fix this?
function verzendkosten( $cart_object ) {
global $woocommerce;
$laag = 37.50;
$hoog = 57.50;
$vala = 550.00;
$prijs = $woocommerce->cart->total;
if($prijs <= $vala) {
$woocommerce->cart->add_fee( 'Verzendkosten', $hoog, true, 'standard' );
}
if($prijs > $vala) {
$woocommerce->cart->add_fee( 'Verzendkosten', $laag, true, 'standard' );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'verzendkosten' );
Related
Found exactly the snippet I was looking for to add a fixed fee amount to each individual cart item regardless of price. This site sells tires. So each tire will be charged 3$.
Here is the code I'm using and works:
add_action('woocommerce_cart_calculate_fees', function() {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
$feetot = WC()->cart->get_cart_contents_count();
WC()->cart->add_fee(__('Specific Duty on New Tires', 'txtdomain'), 3 * $feetot);
});
I'm not very good with PHP and I'm learning as I go. I did spend 3 hours trying to modify this code so that the $3 fee would be TAXED as well. But I couldn't figure it out.
Below is what I tried as one of the attempts to have the fee taxed as well but it doesn't work:
add_action('woocommerce_cart_calculate_fees', function() {
if (is_admin() && !defined('DOING_AJAX')) {
return;
}
$feetot = WC()->cart->get_cart_contents_count();
WC()->cart->add_fee(__('Specific Duty on New Tires', 'txtdomain', $taxable = true, $tax_class = ''), 3 * $feetot);
});
What I am doing wrong? Any help please.
To make it work, replace in your code the line:
WC()->cart->add_fee(__('Specific Duty on New Tires', 'txtdomain', $taxable = true, $tax_class = ''), 3 * $feetot);
with the following code line (see WC_Cart add_fee() method):
WC()->cart->add_fee( __('Specific Duty on New Tires', 'text_domain'), $feetot * 3, true, '' );
So your correct hooked function code will be:
add_action('woocommerce_cart_calculate_fees', 'custom_cart_items_fee' );
function custom_cart_items_fee( $cart ) {
if ( is_admin() && ! defined('DOING_AJAX') ) {
return;
}
$fee_amount = $cart->get_cart_contents_count() * 3;
$cart->add_fee( __('Specific Duty on New Tires', 'text_domain'), $fee_amount, true, '' );
}
Code goes in functions.php file of the active child theme (or active theme). It should works.
By default when woocommerce cart quantity is changed it updates the item price by multiplying it by the quantity. I would like to change the default behaviour and ensure that when in the cart when the quantity is changed it doesnt change the default price passed when add to cart is clicked
I have added this action hook but i cannot figure out how to stop price change when quantity is changed in a cart.
add_action( 'woocommerce_after_cart_item_quantity_update', 'on_quantity_changed_in_cart', 20, 4 );
function on_quantity_changed_in_cart( $cart_item_key, $quantity, $old_quantity, $cart){
if( ! is_cart() ) return; // Only on cart page
//here stop price from been changed by default
}
Looking to "Disable Woocommerce cart line item quantity price calculation" answer thread, I found out I need to override an action hook to replace the final cost per line:
add_filter('woocommerce_cart_product_subtotal', [$this, 'filter_woocommerce_cart_product_subtotal'], 10, 4);
public function filter_woocommerce_cart_product_subtotal($product_subtotal, $product, $quantity, $cart){
$sub_value = 0;
foreach ($cart->cart_contents as $hash => $value) {
if ($value["product_id"] === wc_get_product($product)->get_id()) {
$sub_value = $value["wcform-custom_price"];
//wcform-custom_price is passed from when adding to the cart.
}
};
return wc_price($sub_value);
}
Now on the totals as well I overriden the following
add_action( 'woocommerce_calculate_totals', [$this,'custom_item_price'],20,1);
add_filter( 'woocommerce_calculated_total', [$this,"calculateFinalTotal"], 20, 2 );
public function custom_item_price( $wc_cart ) {
$cart_contents_total = 0;
foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item ){
$cart_contents_total += $cart_item["wcform-custom_price"];
}
$wc_cart->subtotal = $cart_contents_total;
}
public function calculateFinalTotal($total,$cart){
$cart_contents_total = 0;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ){
$cart_contents_total += $cart_item["wcform-custom_price"];
}
return $cart_contents_total;;///print_r($cart->get_cart());
}
I've created a webshop in Woocommerce (wordpress). It's a wine shop and I need to add an extra cost: 0,08 euro per bottle (product).
I've found this and adjusted it, but I cannot get the number of products (bottles) to multiply with 0.08 euro.
In the cart I do get an extra line but the value is 0.
Can anyone explain me what I'm doing wrong?
function get_cart_contents_count() {
return apply_filters( 'woocommerce_cart_contents_count', $this->cart_contents_count );
}
function woo_add_cart_fee() {
global $woocommerce;
$woocommerce->cart->add_fee( __('Custom', 'woocommerce'), $get_cart_contents_count * 0.08 );
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
Try this code in your functions.php but it will be applied on over all cart
// Hook before adding fees
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
function add_custom_fees( WC_Cart $cart ){
$fees = 0.08;
$cart->add_fee( 'Handling fee', $fees);
}
EDIT:
To multiply it with each product do something like
add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees');
function add_custom_fees( WC_Cart $cart ){
$fees = 0;
foreach( $cart->get_cart() as $item ){
$fees += $item[ 'quantity' ] * 0.08;
}
if( $fees != 0 ){
$cart->add_fee( 'Handling fee', $fees);
}
}
You are talking about adding surcharge to the cart. You can get all the related information from the Woocommerce Doc in here.
Got a (hopefully quick!) question on updating stock levels for products when they are added to the cart (and preferably "releasing" them back to stock if they are removed from the cart prior to checkout) - how easy is it to achieve something like this, and what would the best steps be?
I can see there are a few functions/filters that could be called in to play like woocommerce_stock_amount, wc_update_product_stock and add_to_cart_class and so forth, but I'd love any guidance you could spare on how to bring it all together :)
So far, this is what has been arrived at, and it's working well, but with one rather important issue! If a product is a "one-off", in other words, only has one available in stock before it is added to the cart, the visitor cannot checkout as the script below has reduced the stock to zero!
Thanks in advance for any help with this :)
add_action('woocommerce_add_to_cart', 'update_product_stock_on_add', 10, 6);
function update_product_stock_on_add($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
global $woocommerce;
$product = get_product($product_id);
$woocommerce->cart->cart_contents[$cart_item_key]['old_stock_quantity'] = $product->get_stock_quantity();
$woocommerce->cart->cart_contents[$cart_item_key]['add_time'] = time();
wc_update_product_stock($product_id, $product->get_stock_quantity() - $quantity);
}
add_action('woocommerce_after_cart_item_quantity_update', 'update_product_stock_on_update', 10, 2);
function update_product_stock_on_update($cart_item_key, $quantity) {
global $woocommerce;
$cart_item = $woocommerce->cart->cart_contents[$cart_item_key];
wc_update_product_stock($cart_item['product_id'], $cart_item['old_stock_quantity'] - $quantity);
}
add_action('woocommerce_before_cart_item_quantity_zero', 'update_product_stock_on_zero', 10, 2);
function update_product_stock_on_zero($cart_item_key, $quantity) {
global $woocommerce;
$cart_item = $woocommerce->cart->cart_contents[$cart_item_key];
wc_update_product_stock($cart_item['product_id'], $cart_item['old_stock_quantity']);
}
add_filter('woocommerce_get_cart_item_from_session', 'load_old_stock_from_session', 10, 3);
function load_old_stock_from_session($cart_item, $values, $key) {
$cart_item['old_stock_quantity'] = $values['old_stock_quantity'];
$cart_item['add_time'] = $values['add_time'];
return $cart_item;
}
add_action('woocommerce_cart_loaded_from_session', 'check_cart_item_timeout');
function check_cart_item_timeout($cart) {
foreach ($cart->get_cart() as $cart_item_key => $values) {
if ((time() - $values['add_time']) >= 10) {
wc_add_notice( sprintf( __( '%s has been removed from your cart because it can no longer be purchased. Please contact us if you need assistance.', 'woocommerce' ), $values['data']->get_title() ), 'error' );
unset($cart->cart_contents[$cart_item_key]);
wc_update_product_stock($values['product_id'], $values['old_stock_quantity']);
}
}
}
$replace_order = new WC_Cart();
$replace_order->empty_cart( true );
$replace_order->add_to_cart( "256", "1");
The above code add product 256 to the Cart 1 time. But the issue I'm having is that I want to be able to completely override the product price... as far as I can tell, the only thing I can do it apply a coupon to the Cart.
Is there a way to completely override the price to something totally custom?
Here is the code for overriding price of product in cart
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
$custom_price = 10; // This will be your custome price
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom_price;
// for WooCommerce version 3+ use:
// $value['data']->set_price($custom_price);
}
}
Hope it will be useful...
You need to introduce an if statement for checking product id, in above code:
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
$custom_price = 10; // This will be your custome price
$target_product_id = 598;
foreach ( $cart_object->cart_contents as $value ) {
if ( $value['product_id'] == $target_product_id ) {
$value['data']->price = $custom_price;
}
/*
// If your target product is a variation
if ( $value['variation_id'] == $target_product_id ) {
$value['data']->price = $custom_price;
}
*/
}
}
Add this code anywhere and make sure that this code is always executable.
After adding this code, when you'll call:
global $woocommerce;
$woocommerce->cart->add_to_cart(598);
Only this product will be added with overridden price, other products added to cart will be ignored for overriding prices.
Hope this will be helpful.
I have tried all above code samples and latest woocommerce 3.0 is not support any of the above example. Use below code and working perfectly for me.
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
$custom_price = 10; // This will be your custom price
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$cart_item['data']->set_price($custom_price);
}
}
After release of woocommerce version 3.0.0 product price is update on add to cart using set_price($price) function. The example is given as below :
add_action( 'woocommerce_before_calculate_totals', 'mj_custom_price' );
function mj_custom_price( $cart_object ) {
$woo_ver = WC()->version;
$custom_price = 10;
foreach ( $cart_object->cart_contents as $key => $value )
{
if($woo_ver < "3.0.0" && $woo_ver < "2.7.0")
{
$value['data']->price = $custom_price;
}
else
{
$value['data']->set_price($custom_price);
}
}
}
Many Thanks
For the Wordpress and Woocommerce latest version,Please use like this
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
foreach ( $cart_object->cart_contents as $key => $value ) {
$custom_price = 5;
$value['data']->set_price($custom_price);
}
}
For eveeryone that got here from Google. The above is now deprecated as i found out updating to WooCommerce 3.0.1.
Instead of the above you now need to use set_price instead of price
Here is an example:
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
$custom_price = 10; // This will be your custome price
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->set_price = $custom_price;
}
}
I hope this helps people in the future :)
This is how i did it, first i add my custom price to cart_item_data witch can save custom data to cart items, then i use woocommerce_before_calculate_totals, loop the cart and add the previously added price.
function add_donation_to_cart() {
$cart_item_data = array('price' => $_REQUEST['donate_amount']);
$woocommerce->cart->add_to_cart( 5395, 1, '', array(), $cart_item_data);
}
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart ) {
foreach ( $cart->cart_contents as $key => $value ) {
$value['data']->price = $value['price'];
}
}
With WooCommerce 2.5 I found this to be a 2-part process. The first step is to change the run-time display of pricing when added to the cart via the woocommerce_add_cart_item filter. The second part is to set the persistent session data which is read during checkout via the woocommerce_get_cart_item_from_session filter. This seems to be faster than hooking the calculate totals filters (such as woocommerce_before_calculate_totals) as they are run very frequently in WooCommerce.
More details here:
woocommerce change price while add to cart
To make it dynamic ( override price for each item in cart separately ), you need to save the override product price in session with cart item key as session key using woocommerce_add_to_cart hook.
by using these session values you can calculate correct Cart Total and make the altered price appear in the Order Item as well
You can use the following
add_filter( 'woocommerce_cart_item_price', 'kd_custom_price_message' );
function kd_custom_price_message( $price ) {
$textafter = ' USD';
return $price . $textafter;
}