3
votes

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.

1
Please add in your question the plugin that you are using for multi currency and currency conversion…LoicTheAztec
I used the WPML plugin. The below code is working fine 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

1 Answers

2
votes

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