Skip to content
Advertisement

Disable default country in WooCommerce if geolocation fails

WooCommerce has settings for what the default country should be for customer. It can be disabled, set to shop address country, or set by geolocation.

My issue is that when using the geolocation option, if that fails to return a country that’s permissible on the store, it will now revert to using the shop address country.

What I would like is to not have a default selected country when geolocation fails.

I know this should be possible via some code in functions.php. I’ve worked with code that changes the default country, such as that found here. It also had the advantage of testing if it’s an existing customer with a country on their account (something I’d like to include). I also found some code that will test if geolocation set a country, such as the following:

function get_customer_geo_location_country(): ?string {
    if ( class_exists( 'WC_Geolocation' ) ) {
        $location = WC_Geolocation::geolocate_ip();

        if ( isset( $location['country'] ) ) {
            return $location['country'];
        }
    }

    return null;
}

Source: WooCommerce: Set default Country in Billing (using Geo Location) but not in Shipping in checkout page answer code.

I tried piecing these things together, but it hasn’t worked.

E.g.

add_filter( 'default_checkout_billing_country', 'change_default_checkout_country', 10, 1 );

function change_default_checkout_country( $country ) {
    // If the user already exists, don't override country
    if ( WC()->customer->get_is_paying_customer() ) {
        return $country;
    }

    elseif ( class_exists( 'WC_Geolocation' ) ) {
        $location = WC_Geolocation::geolocate_ip();

        if ( isset( $location['country'] ) ) {
            return $location['country'];
        }
    }

    else {
        return null;
    }
}

This didn’t work. Although I suspect it’s close. My knowledge of PHP is fairly basic, so I’ve likely made some glaring mistakes.

Advertisement

Answer

In itself there is nothing wrong with your code, only if the elseif condition is met, but then not the if condition that is in the elseif you should not assume that your else condition is executed.

Basically, an else is missing in your elseif condition

So you get:

function filter_default_checkout_billing_country( $default ) {  
    // If the user already exists, don't override country
    if ( WC()->customer->get_is_paying_customer() ) {
        return $default;
    } elseif ( class_exists( 'WC_Geolocation' ) ) {
        // Get location country
        $location = WC_Geolocation::geolocate_ip();
        
        if ( isset( $location['country'] ) ) {
            return $location['country'];
        } else {
            $default = null;
        }
    } else {
        $default = null;
    }
    
    return $default;
}
add_filter( 'default_checkout_billing_country', 'filter_default_checkout_billing_country', 10, 1 );
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement