Add a calculated fee based on total after discounts in WooCommerce - php

I'm trying to add a fee to my woocommerce cart based on the subtotal after discounts have been applied:
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );
function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$percentage = 0.01;
$surcharge = $woocommerce->cart->subtotal - $woocommerce->cart->get_cart_discount_total();
$woocommerce->cart->add_fee( 'Surcharge', $surcharge, true, '' );
}
I don't believe calls like $woocommerce->cart->get_cart_discount_total() can be used in an action hook, which is why I keep getting 0.00 for the fee.
I also read around some WC values are deprecated and will always show zero, but it doesn't explain why those amounts appear in filters and not actions.
What else can I use in an action to get the same number and add a percent fee to?

The WC_Cart object argument is included in woocommerce_cart_calculate_fees action hook. I also use the percentage amount calculation, as I suppose you just forgot it in your code.
So you should try this instead:
add_action( 'woocommerce_cart_calculate_fees','wc_custom_surcharge', 10, 1 );
function wc_custom_surcharge( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// HERE set your percent rate
$percent = 1; // 1%
// Fee calculation
$fee = ( $cart->subtotal - $cart->get_cart_discount_total() ) * $percent / 100;
// Add the fee if it is bigger than O
if( $fee > 0 )
$cart->add_fee( __('Surcharge', 'woocommerce'), $fee, true );
}
Code goes in function.php file of your active child theme (or theme).
Tested and works perfectly.
Note: Also global $woocommerce; with $woocommerce->cart has been replaced by WC()->cart since a long time. The WC() woocommerce object already include itself global $woocommerce;…
Specific update:
add_action( 'woocommerce_cart_calculate_fees','wc_custom_surcharge', 10, 1 );
function wc_custom_surcharge( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// HERE set your percent rate and your state
$percent = 6;
$state = array('MI');
$coupon_total = $cart->get_discount_total();
// FEE calculation
$fee = ( $cart->subtotal - $coupon_total ) * $percent / 100;
if ( $fee > 0 && WC()->customer->get_shipping_state() == $state )
$cart->add_fee( __('Tax', 'woocommerce'), $fee, false);
}
Code goes in function.php file of your active child theme (or theme).
Tested and works.

the plugin i was using to create coupons was hooking into after_calculate_totals and adjusting the amount afterwards. anything that fires before the plugin wasn't counted into that adjusted total. i was able to call specific amounts using variables in the plugin to create the fee amount i needed
for anyone else who is interested: i am using the ignitewoo gift certificates pro plugin and wanted to create a fee based on the remaining balance after coupons. this is Loic's code with some modifications:
add_action( 'woocommerce_cart_calculate_fees','wc_custom_surcharge', 10, 1 );
function wc_custom_surcharge( $cart) {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$state = array('MI');
// HERE set your percent rate
$percent = 6;
$coupTotal = 0;
foreach ( $woocommerce->cart->applied_coupons as $cc ) {
$coupon = new WC_Coupon( $cc );
$amount = ign_get_coupon_amount( $coupon );
$coupTotal += $amount;
}
// Fee calculation
$fee = ($cart->subtotal - $coupTotal) * $percent/100;
if (( $fee > 0 ) AND (in_array( WC()->customer->shipping_state, $state ) ))
$cart->add_fee( __('Tax', 'woocommerce'), $fee, false);
}

Related

Add percentage to the total (including shipping cost) in woocommerce

In Woocommerce I would like to add 3.5% on the Grand Total (including shipping fee). For now im using these code, but this only calculate without shipping fee.
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_donation' );
function woocommerce_custom_donation() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$percentage = 0.035; // 3.5%
// uncomment the line below to include shipping fees in the donation/surcharge calculation
// $donation = ( $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total ) * $percentage;
$donation = $woocommerce->cart->cart_contents_total * $percentage;
$woocommerce->cart->add_fee( 'Administration Fees', $donation, true, '' );
}
You can also try this.
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_donation',10, 1 );
function woocommerce_custom_donation() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$percentage = 3.5;
$cart_total = $woocommerce->cart->cart_contents_total;
$shipping_total = $woocommerce->cart->get_shipping_total() ?: 0;
$tax_total = $woocommerce->cart->get_taxes_total() ?: 0;
$grand_total = $cart_total + $shipping_total + $tax_total;
$donation = $grand_total * $percentage / 100;
$woocommerce->cart->add_fee( 'Administration Fees', $donation, true, '' );
}
I believe that when the product is in the cart, the delivery method (and related fees) are not known/applied until checkout.
So I would add a "checkout fee" on checkout, and so after the user selected a checkout method (and why not a payment method)
If you enable tax calculation in Woocommerce settings, you could also set up a tax for everyone that also applies on shipping fees:

Apply a fee via Url variable (GET) in WooCommerce

I'm trying to carry an "add_fee" value over to review order page but it's not working.
I need to enable my check out page to wait for the url parameter "getfee".
If the getfee equals 2, then add the fee.
If it doesn't, then don't add anything.
Here's my code:
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );
function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$fee = $_GET["getfee"];
if( $fee == "2") {
$percentage = 0.01;
$surcharge = ( $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total ) * $percentage;
$woocommerce->cart->add_fee( 'Surcharge', $surcharge, true, '' );
}
}
So far, it adds the fee in the checkout page but when it comes to reviewing the order, it doesn't appear.
I think it could be because the checkout page doesn't have that parameter but not sure.
Any help would be greatly appreciated.
You need to set your Url fee in a WC Session variable to avoid this problem:
// Get URL variable and set it to a WC Session variable
add_action( 'template_redirect', 'getfee_to_wc_session' );
function getfee_to_wc_session() {
if ( isset($_GET['getfee']) ) {
WC()->session->set('getfee', esc_attr($_GET['getfee']));
}
}
// Add a percentage fee
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );
function woocommerce_custom_surcharge( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$fee = WC()->session->get('getfee'); // Get WC session variable value
if( $fee == "2") {
$percentage = 0.01;
$surcharge = ( $cart->cart_contents_total + $cart->shipping_total ) * $percentage;
$cart->add_fee( 'Surcharge', $surcharge, true, '' );
}
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Add a progressive surcharge based on countries in Woocommerce

Can I use a if statement and if so, how? Basically I want it to add 27 as surcharge to SE country and to all other countries 3 as surcharge.
Here is the original code
add_action( 'woocommerce_cart_calculate_fees','wc_add_surcharge' );
function wc_add_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$county = array('US');
// change the $fee to set the surcharge to a value to suit
$fee = 27.00;
if ( in_array( WC()->customer->get_shipping_country(), $county ) ) :
$woocommerce->cart->add_fee( 'Surcharge', $fee, true, 'standard' );
endif;
}
Can I add:
if ( !county = 'SE')
$fee = 3
if ( county = 'SE')
$fee 27
?
Yes you can add many conditions to get different fee amounts, but as your countries are in an array, you will use in_array() php function instead of ==.
There is a shorthand way when using IF / ELSE statements:
The normal way:
if ( 'SE' == $shipping_country )
$fee = 27; // For Sweden
else
$fee = 3; // For others
The shorthand way (which makes the same):
// The fee cost will be 27 for Sweden and 3 for other allowed countries
$fee = 'SE' == $shipping_country ? 27 : 3;
Your code is a little outdated, so here is a revisited version including your conditions:
add_action( 'woocommerce_cart_calculate_fees','wc_add_surcharge', 10, 1 );
function wc_add_surcharge( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$shipping_country = WC()->customer->get_shipping_country();
$subtotal = WC()->cart->subtotal;
// Defined fee amount based on countries
$fee = 'SE' == $shipping_country ? 27 : 3;
// Minimum cart subtotal
$minimum = 300;
if ( $subtotal < $minimum ) {
$cart->add_fee( 'Surcharge', $fee, true );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.

Global surcharge WooCommerce exclude VAT

I made a global surcharge in PHP for WooCommerce, because all of our customers have to pay a fee for special delivery.
Is there a way to make the fee ignore VAT?
When I write 15 it adds VAT to the number. I'd just like for the number I write to be the fee.
TL:DR - MAKE SURCHARGE INCLUDED VAT
// Packing fee
add_action( 'woocommerce_cart_calculate_fees','wc_add_surcharge' );
function wc_add_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$county = array('DK');
// change the $fee to set the surcharge to a value to suit
$fee = 15;
if ( in_array( WC()->customer->get_shipping_country(), $county ) ) :
$woocommerce->cart->add_fee( 'Emballage pant', $fee, true, 'standard' );
endif;
}
To make the fee ignore Vat you need to remove the 2 last arguments as they are related to Taxes (the third argument is false (not taxable) by default ):
Also global $woocommerce; and $woocommerce->cart as there is a missing $cart argument in this hooked function. So try this instead:
// Packing fee
add_action( 'woocommerce_cart_calculate_fees','wc_add_surcharge' );
function wc_add_surcharge( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$county = array('DK');
// change the $fee to set the surcharge to a value to suit
$fee = 15;
if ( in_array( WC()->customer->get_shipping_country(), $county ) ) :
$cart->add_fee( 'Emballage pant', $fee );
endif;
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.

Additional fees based on product type in Woocommerce

What I am trying to do is to add and display, to the checkout page, a new fee if the product type is an "auction". The problem I have with my code is that the new fee is displayed but not added to the total cost.
I've used this code
Change Cart total price in WooCommerce
and customized it with this function:
add_action( 'woocommerce_calculate_totals', 'action_cart_calculate_totals', 10, 1 );
function action_cart_calculate_totals( $cart_object ) {
if ( (is_admin() && ! defined( 'DOING_AJAX')) || WC()->cart->is_empty() )
return;
foreach ( WC()->cart->cart_contents as $key => $values ) {
if ( $values['data']->get_type() == 'auction' ) {
$buyerfee = 0.10; // auction buyer fee
$surcharge = $cart_object->cart_contents_total * $buyerfee;
$cart_object->add_fee( 'Auction Fee (10%)', $surcharge, true, '' );
}
}
}
In this case, you need to use woocommerce_cart_calculate_fees action hook instead:
add_action( 'woocommerce_cart_calculate_fees', 'action_cart_calculate_fees', 10, 1 );
function action_cart_calculate_fees( $cart_object ) {
if ( is_admin() && ! defined('DOING_AJAX') ) return;
$is_auction = false;
foreach ( $cart_object->cart_contents as $item ) {
if ( $item['data']->is_type( 'auction' ) ) {
$is_auction = true;
break;
}
}
if( $is_auction ){
$percent = 10; // auction buyer fee (in percetage)
$fee = $cart_object->cart_contents_total * $percent / 100;
$cart_object->add_fee( "Auction Fee ($percent%)", $fee, true );
}
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Code is tested and works

Categories