I have a 3 shipping methods in my Woocommerce store and I want to disable the tax rate when customer choose the 3rd shipping method.
How can I do that?
As settings doesn't seem to be working to remove taxes from specific shipping methods, try the following code that will set zero taxes to your specific defined shipping methods:
add_filter('woocommerce_package_rates', 'null_specific_shipping_method_taxes', 12, 2);
function null_specific_shipping_method_taxes( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
// HERE define your targeted shipping methods IDs (in this array)
$shipping_methods_ids = array( 'flat_rate:2', 'flat_rate:12', 'flat_rate:3', 'shipping_by_rules:5' );
// Loop through shipping rates
foreach ( $rates as $rate_key => $rate ){
$has_taxes = false;
// Only for your defined Shipping method IDs
if( in_array( $rate->id, $shipping_methods_ids ) ){
$taxes = [];
// Loop through the shipping taxes array (as they can be many)
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 ){
// Set each tax cost to zero
$taxes[$key] = 0;
$has_taxes = true;
}
}
// Set the new taxes array
if( $has_taxes )
$rates[$rate_key]->taxes = $taxes;
}
}
return $rates;
}
This code goes on function.php file of your active child theme (or theme). Tested and works (if settings are made in a correct way, regarding related shipping methods and taxes in Woocommerce)…
Related
In Woocommerce, I am keeping prices the same regardless of tax rate using the filter:
add_filter('woocommerce_adjust_non_base_location_prices', '__return_false');
Now, I'd like to exclude a few countries that are exempt of tax.
This function works fine:
add_filter( 'woocommerce_adjust_non_base_location_prices', 'custom_eu_vat_number_country_codes' );
function custom_eu_vat_number_country_codes( $boolean ) {
// Avoiding errors on admin and on other pages
if( is_admin() || WC()->cart->is_empty() )
return $boolean;
// Defined array of countries where the boolean value should be "false"
$countries = array( 'CH','GB','GF','NO','UK');
// Remove field $countries
if ( in_array( WC()->customer->get_shipping_country(), $countries ) ) {
$boolean = true;
}else{
$boolean = false;
}
return $boolean;
}
I need to replace $countrie = array('CH','GB','GF','NO','UK'); by an automatic list of countries with VAT tax set as 0.000% in woocommerce parameters.
Is it possible ?
someone gives me a suggestion to understand how to correctly write the shipping function in woocommerce to get this result:
a) Shipping costs are € 10 and are free for orders over € 100
b) I have two categories A and B
c) if in the cart there are products of ONLY CATEGORY B, the rule of free shipping for orders over € 100 must not be applied. So the shipping must be 10 €.
For point c) I have entered this function in function.php, but there is something wrong:
// Disable Woocommerce shipping methods based on specific category
add_filter( 'woocommerce_package_rates', 'hide_shipping_for_categories', 10, 2 );
function hide_shipping_for_categories( $rates, $package ) {
// Add your own Woocommerce categories here (either category ID, slug or name)
$terms = array( 'I nostri sottoli' );
$taxonomy = 'product_cat'; // If you need to hide shipping based on tags, then change it to product_tag
// Add shipping methods to be removed (like "local_pickup:8")
$method_instances_ids = array('free_shipping:4');
$found = false;
// Loop through cart items checking for defined product IDs
foreach( $package['contents'] as $cart_item ) {
if ( has_term( $terms, $taxonomy, $cart_item['product_id'] ) ){
$found = true;
break;
}
}
if ( ! $found ) return $rates; // If not found we exit
// Loop through your active shipping methods
foreach( $rates as $rate_id => $rate ) {
// Remove all other shipping methods other than your defined shipping method
if ( in_array( $rate_id, $method_instances_ids ) ){
unset( $rates[$rate_id] );
}
}
return $rates;
}
I am excluding virtual products from free shipping, with the working code below. However the 'flexible_shipping_12_1 and _12_2 rates are being problematic because they get removed when the free shipping threshold is crossed.
For example a user buys a virtual product worth $20 and other products worth $26, this makes the order total $46 which would qualify them for free shipping. Because they qualify for free shipping, the other rates are removed.
The code below checks to see that the non-virtual total is actually only $26 so they shouldn't get free shipping. They do qualify for the $26-$44.99 rate. This part is working.
If free shipping is removed they should get the next tier of shipping which is: ID= flexible_shipping_12_2. This method has removed itself because it thinks the order total is $46.
I need to 're-insert', not create, that method and # _12_1 into the available shipping methods at the spots indicated in the code below.
I can't figure out how to re-insert a shipping method:
//Exclude virtual products from free shipping
add_filter('woocommerce_package_rates', 'custom_shipping_option', 20, 2 );
function custom_shipping_option($rates, $package){
$non_virtual_total = 0;
// Get the cart content total excluding virtual products
foreach( WC()->cart->get_cart() as $cart_item )
if( ! $cart_item['data']->is_virtual( ) ){
$non_virtual_total += $cart_item['line_total'];
}
// Disabling methods based on non_virtual_total
if( $non_virtual_total < 45 && $non_virtual_total >= 25 ){
foreach ( $rates as $rate_key => $rate )
if( 'free_shipping' == $rate->method_id )
unset( $rates[ $rate_key ] );
if( 'flexible_shipping_12_1' == $rate->method_id )
unset( $rates[ $rate_key ] );
//insert flexible_shipping_12_2 method here
}
if( $non_virtual_total < 25 ){
foreach ( $rates as $rate_key => $rate )
if( 'free_shipping' == $rate->method_id )
unset( $rates[ $rate_key ] );
if( 'flexible_shipping_12_2' == $rate->method_id )
unset( $rates[ $rate_key ] );
//insert flexible_shipping_12_1 method here
}
return $rates;
}
I believe you just want to re-add flexible_shipping_12_1 or flexible_shipping_12_2 shipping method to the $rates array, correct?
This should be all you need:
//insert flexible_shipping_12_1 method here
array_push($rates, "flexible_shipping_12_1");
//insert flexible_shipping_12_2 method here
array_push($rates, "flexible_shipping_12_2");
The array_push method just adds the new value to the array.
using XPS for Shipping rates. How can I add handling charges in shipping.
like if the shipping charges rates $39.52, it should add 3$ in shipping rates ( like 42.52 ) even we can code in function.php.
How do I accomplish this?
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_handling' );
function woocommerce_custom_handling() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$shipping_method = WC()->session->get( 'chosen_shipping_methods' );
if($shipping_method[0]){
$handling = 3.00;
$woocommerce->cart->add_fee('Handling', $handling, true, 'standard');
}
}
To add directly to shipping costs: Since I don't know the shipping key for XPS this is my best guess to add it to all shipping methods, including XPS. See if this works
add_filter( 'woocommerce_package_rates','woocommerce_custom_handling' );
function woocommerce_custom_handling($rates, $package) {
$handling = 3.00;
foreach( $rates as $rate_key => $rate ){
$rates[$rate_key]->cost = ($handling + $rates[$rate_key]->cost);
}
return $rates;
}
I'm building a WooCommerce e-shop and I need to tweak my checkout page by doing the following:
Hide a certain shipping method (only one) if the order total > 100€.
Hide the cash on delivery payment method if local pickup is selected.
Does anyone know how to do that? I have the Code Snippets plugin so I can easily add any custom code.
To hide specific shipping method based on the cart total, you can use below code snippet. You need to update your shipping method name in the code.
Disable shipping method as per cart total
Add this snippet in your theme's functions.php file or custom plugin file.
add_filter( 'woocommerce_package_rates', 'shipping_based_on_price', 10, 2 );
function shipping_based_on_price( $rates, $package ) {
$total = WC()->cart->cart_contents_total;
//echo $total;
if ( $total > 100 ) {
unset( $rates['local_delivery'] ); // Unset your shipping method
}
return $rates;
}
Disable Payment Gateway For Specific Shipping Method
Use below code snippet. Update code as per your payment method & shipping method.
add_filter( 'woocommerce_available_payment_gateways', 'x34fg_gateway_disable_shipping' );
function x34fg_gateway_disable_shipping( $available_gateways ) {
global $woocommerce;
if ( !is_admin() ) {
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
if ( isset( $available_gateways['cod'] ) && 0 === strpos( $chosen_shipping, 'local_pickup' ) ) {
unset( $available_gateways['cod'] );
}
}
return $available_gateways;
}
There are a number of plugins that will do this for you, take a look at this one WooCommerce Conditional Shipping and Payments
You'll want to tie in to the "woocommerce_payment_gateways" action
Something along these lines:
function alter_payment_gateways( $gateways ){
$chosen_rates = ( isset( WC()->session ) ) ? WC()->session->get( 'chosen_shipping_methods' ) : array();
if( in_array( 'local-pickup:6', $chosen_rates ) ) {
$array_diff = array('cod');
$list = array_diff( $list, $array_diff );
}
return $list;
}
add_action('woocommerce_payment_gateways', 'alter_payment_gateways', 50, 1);
The number on the end of 'local-pickup' on line 4 will depend on your woocommerce setup. You can find the string you need to put in here by adding something to a basket, going to the checkout, right clicking on the "Local Pickup" option in the delivery methods and looking at the value attribute.