Woocommerce Free shipping method not working with multiple currencies. I define the Minimum order amount 100 for free shipping in Europe Zone.
The primary currency is set EURO and it's working fine but then I switch country (Norway) free shipping automatically applied (because Norway currency KR is very lower to EURO and free shipping consider only minimum mount number, not currency ), it's not applied based on the currency. converter.
add_filter('woocommerce_package_rates', function ($methods, $rates) {
$currency = get_woocommerce_currency();
foreach ((array)$methods as &$method) {
if ($currency != 'USD' && $currency != 'GBP' && $currency != 'CHF') {
// echo "Hello";
// print_r($method->get_cost());
$method->set_cost(round(get_exchanged_currency($currency, $method->get_cost(), true, 'EUR', '', true), 2));
}
}
return $methods;
}, 10, 2);
The above code working fine to calculate the flat rate shipping cost.
I want to implement free shipping based on user local currency converter (IE free shipping minimum order value = 100 EURO if a user chooses Norway country then free shipping applied only if the order value is 1062.19 Kr).
I appreciate it if someone can help me with this.
As I don't really know how get_exchanged_currency()
function works I am not sure about conversion amount usage, but the logic is in the code below.
To handle free shipping for a minimal amount using currency conversion
Also to handle multiple currencies as a condition on IF / ELSE statements use in_array()
instead.
The code:
add_filter('woocommerce_package_rates', 'filter_package_rates', 10, 2 );
function filter_package_rates( $rates, $package ) {
$currency = get_woocommerce_currency();
$free = array();
foreach ( $rates as $rate_key => $rate ) {
// For "flat_rate" (or "local_pickup") and NOT for 'USD', 'GBP', 'CHF' currencies
if ( ! in_array( $currency, array('USD', 'GBP', 'CHF') ) && 'free_shipping' !== $rate->method_id ) {
$rates[$rate_key]->cost = round( get_exchanged_currency( $currency, $rate->cost, true, 'EUR', '', true ), 2 );
}
// For "free_shipping
elseif ( 'free_shipping' === $rate->method_id ) {
$cart_total = WC()->cart->subtotal; // (or WC()->cart->get_subtotal() without taxes)
$min_amount = 100; // Free shipping min amount in EUR currency
$min_amount = round( get_exchanged_currency( $currency, $min_amount, true, 'EUR', '', true ), 2 ); // Min amount convversion
$free_shipping = new \WC_Shipping_Free_Shipping( $rate->instance_id );
$applied_coupons = WC()->cart->get_applied_coupons();
if ( 'either' === $free_shipping->requires && ! empty($applied_coupons) && $cart_total < $min_amount ) {
foreach ( $applied_coupons as $coupon_code ) {
$coupon = new WC_Coupon( $coupon_code );
if( $coupon->get_free_shipping() ) {
$coupon_free_ship = true;
break;
}
}
}
// Enable free shipping for a minimal cart amount or a coupon with free shipping option
if( $cart_total < $min_amount && ! isset($coupon_free_ship) ) {
unset($rates[$rate_key]);
} else {
$free[$rate_key] = $rate;
break;
}
}
}
return ! empty( $free ) ? $free : $rates;
}
Code goes in functions.php file of your active child theme (or active theme). It should works.
When order subtotal is less than the minimal required amount and a coupon with free shipping is applied, Free shipping method is enabled hiding other shipping methods.
Refresh the shipping caches:
- This code is already saved on your functions.php file.
- In a shipping zone settings, disable / save any shipping method, then enable back / save.
You are done and you can test it.
Related: WooCommerce - Hide other shipping methods when FREE SHIPPING is available