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.
Related
I would like to know how I can modify the code so that all transactions have a percentage surcharge and exclude France?
* Add a standard $ value surcharge to all transactions in cart / checkout
*/
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 = 1.00;
if ( in_array( WC()->customer->get_shipping_country(), $county ) ) :
$woocommerce->cart->add_fee( 'Surcharge', $fee, true, 'standard' );
endif;
}
I found the code on the woocommerce site
Thank you for your response.
I got what I wanted by reworking the code, is it gives this:
//Ajouter un supplément à votre paiement en fonction du pays de livraison exclu france
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );
function woocommerce_custom_surcharge() {
global $woocommerce;
if ( is_admin() && !defined( 'DOING_AJAX' ) ) return;
$county = ['FR']; //france
// change the $fee to set the surcharge to a value to suit
$percentage = 0.025;
if ( !in_array( WC()->customer->get_shipping_country(), $county ) ){
$surcharge = ( $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total ) * $percentage;
$woocommerce->cart->add_fee( 'Frais de transaction', $surcharge, true, '' );
}
}
All that's left is to change the following country for those they don't want to put charges on their country!
Something like this based off how I am reading the code at least. Can't really test it but it seemed simple enaugh.
* Add a standard $ value surcharge to all transactions in cart / checkout
*/
add_action( 'woocommerce_cart_calculate_fees','wc_add_surcharge' );
function wc_add_surcharge() {
global $woocommerce;
if ( is_admin() && !defined( 'DOING_AJAX' ) ) return;
$county = ['FR']; //france
// change the $fee to set the surcharge to a value to suit
$fee = 1.00;
if ( !in_array( WC()->customer->get_shipping_country(), $county ) ){ //add the ! to exclude only countries in the list
$woocommerce->cart->add_fee( 'Surcharge', $fee, true, 'standard' );
}
}
Overload fees are fixed, ideally there should be price tiers
Example from 01€ to 55€ =0.35€
56 to 150€ = 1.00€ ...
In any case the code works on my site and excludes France.
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.
I am trying to get it so that if a customer were to add a coupon code (Any of them) the Free Shipping option would go away and the flat rate fee would be implemented. - You would think this would be an easy thing to implement, there would be 100's of plugins and ways described to do this, but I have not found any. I do not want to pay $89 for the plugin to do this one thing
A side bonus would be if they are using a coupon but are spending over $249 they can still qualify for Free shipping. I read some where how to do this, but it requires me to get the POST ID, which with the latest WooCommerce is not possible like it was before, I do not know the shipping ID so I am at a lost Here is the code
add_filter( 'woocommerce_shipping_packages', function( $packages ) {
$applied_coupons = WC()->session->get( 'applied_coupons', array() );
if ( ! empty( $applied_coupons ) ) {
$free_shipping_id = 'free_shipping:2';
unset($packages[0]['rates'][ $free_shipping_id ]);
}
return $packages;
} );
Thanks
Edited
add_filter( 'woocommerce_package_rates', 'coupons_removes_free_shipping',
10, 2 );
function coupons_removes_free_shipping( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
$min_total = 250; // Minimal subtotal allowing free shipping
// Get needed cart totals
$total_excl_tax = WC()->cart->get_total();
$discount_excl_tax = WC()->cart->get_discount_total();
// Calculating the discounted subtotal including taxes
$discounted_subtotal_incl_taxes = $total_excl_tax - $discount_excl_tax;
$applied_coupons = WC()->cart->get_applied_coupons();
if( sizeof($applied_coupons) > 0 && $discounted_subtotal_incl_taxes < $min_total ) {
foreach ( $rates as $rate_key => $rate ){
// Targeting "Free shipping"
if( 'free_shipping' === $rate->method_id ){
unset($rates[$rate_key]);
}
}
}
return $rates;
}
The below code will enable "Free shipping" for applied coupons only if cart subtotal reaches a minimal amount (discounted including taxes):
add_filter( 'woocommerce_package_rates', 'coupons_removes_free_shipping', 10, 2 );
function coupons_removes_free_shipping( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
$min_subtotal = 250; // Minimal subtotal allowing free shipping
// Get needed cart subtotals
$subtotal_excl_tax = WC()->cart->get_subtotal();
$subtotal_incl_tax = $subtotal_excl_tax + WC()->cart->get_subtotal_tax();
$discount_excl_tax = WC()->cart->get_discount_total();
$discount_incl_tax = $discount_total + WC()->cart->get_discount_tax();
// Calculating the discounted subtotal including taxes
$discounted_subtotal_incl_taxes = $subtotal_incl_tax - $discount_incl_tax;
$applied_coupons = WC()->cart->get_applied_coupons();
if( sizeof($applied_coupons) > 0 && $discounted_subtotal_incl_taxes < $min_subtotal ){
foreach ( $rates as $rate_key => $rate ){
// Targeting "Free shipping"
if( 'free_shipping' === $rate->method_id ){
unset($rates[$rate_key]);
}
}
}
return $rates;
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
Original answer:
The below code will remove "Free shipping" shipping methods when any coupon is applied without any settings need. There is some mistakes in your actual code. Try the following:
add_filter( 'woocommerce_package_rates', 'coupons_removes_free_shipping', 10, 2 );
function coupons_removes_free_shipping( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
$applied_coupons = WC()->cart->get_applied_coupons();
if( sizeof($applied_coupons) > 0 ){
// Loop through shipping rates
foreach ( $rates as $rate_key => $rate ){
// Targeting "Free shipping" only
if( 'free_shipping' === $rate->method_id ){
unset($rates[$rate_key]); // Removing current method
}
}
}
return $rates;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
By default WooCommerce will still allow a free shipping method to be selected if the coupon code is filled in and active in the shopping cart. The following code can be added to your child’s functions.php page to hook in and hide any free shipping option if a coupon code is used.
add_filter( 'woocommerce_shipping_packages', function( $packages ) {
$applied_coupons = WC()->session->get( 'applied_coupons', array() );
if ( ! empty( $applied_coupons ) ) {
$free_shipping_id = 'free_shipping:2';
unset($packages[0]['rates'][ $free_shipping_id ]);
}
return $packages;
} );
Simply change the $free_shipping_id in the above code to the ID of your free shipping option. You may find your ID by going to WooCommerce > Settings > Shipping Options and then click on your Free Shipping option. The post ID will be in the URL of the page that displays the Free Shipping details/settings.
i.e www.yourdomain.com/wp-admin/post.php?post=40107&action=edit
Where 40107 is the shipping ID in this example. Your shipping ID will be different.
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);
}
In WooCommerce, I am using the code below to add a $12 surcharge to sales for Canadian Customers in the functions.php file of the child theme for one of my client.
But I need to remove the charge for all pdf downloads.
Is this possible altering the code I used?
Here is my code:
add_action( 'woocommerce_cart_calculate_fees','xa_add_surcharge' );
function xa_add_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$county = array('CA');
$fee = 12.00;
if ( in_array( $woocommerce->customer->get_shipping_country(), $county ) ) :
$surcharge = + $fee;
$woocommerce->cart->add_fee( 'Surcharge for International Orders', $surcharge, true, '' );
endif;
}
It's possible checking in cart items for non downloadable product (or depending ion your PDF products settings for non virtual products).
Additionally I have revisited your code a bit:
add_action( 'woocommerce_cart_calculate_fees','add_custom_surcharge', 10, 1 );
function add_custom_surcharge( $wc_cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$countries = array('CA'); // Defined countries
// Continue only for defined countries
if( ! in_array( WC()->customer->get_shipping_country(), $countries ) ) return;
$fee_cost = 12; // The Defined fee cost
$downloadable_only = true;
// Checking cart items for NON downloadable products
foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item ) {
// Checks if a product is not downloadable.
if( ! $cart_item['data']->is_downloadable( ) ){ // or cart_item['data']->is_virtual()
$downloadable_only = false;
break;
}
}
// If one product is not downloadable and if customer shipping country is Canada we add the fee
if ( ! $downloadable_only )
$wc_cart->add_fee( "Surcharge for International Orders", number_format( $fee_cost, 2 ), true );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
All code is tested on Woocommerce 3+ and works.