3

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.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Rigal
  • 611
  • 2
  • 6
  • 25
  • Please add in your question the plugin that you are using for multi currency and currency conversion… – LoicTheAztec Aug 06 '20 at 07:50
  • I used the WPML plugin. The below code is working fine https://pastebin.com/0ZJjXY5E but the free shipping method not applied automatically. I want to hide all shipping methods and apply free shipping automatically. Would you please let me know if you have any Idea to fix this issue? – Rigal Aug 06 '20 at 13:35

1 Answers1

2

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

  • You will first need to set a minimal amount of zero for your Free shipping method settings.
  • The code will handle free shipping for applied coupons with the option enablled
  • You will set in the code the minimal amount in the default currency.

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.


Applied coupon with free shipping option enabled:

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.

enter image description here

Refresh the shipping caches:

  1. This code is already saved on your functions.php file.
  2. 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

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • @ LoicTheAztec Thank you so much for your help. below code is working fine https://pastebin.com/0ZJjXY5E but free shipping method not applied automatically. I want to hide all shipping methods and apply free shipping automatically. – Rigal Aug 06 '20 at 13:29
  • @ LoicTheAztec thank you so much. if possible give me a little hint so I can fix the issue and deliver it to the client. – Rigal Aug 06 '20 at 13:50
  • Would you please check https://stackoverflow.com/questions/63344887/woocommerce-free-shipping-coupon-not-working-if-unsethide-free-shipping-method ? – Rigal Aug 10 '20 at 18:05
  • @Rigal Sorry I have tested again my code on last WooCommerce version under storefront theme and it also works perfectly for applied coupons with free shipping, so there is something else that is making trouble in your case. It can be another custom code, your theme or a plugin. – LoicTheAztec Aug 10 '20 at 23:08