3

What I'm NOT trying to do:

  • Remove or hide checkout (billing/shipping) country fields

What I'm trying do to:

  • Show only ONE country in checkout (billing/shipping) country fields, depending on geolocation (geolocation is already done)
  • OR, Remove countries I don't want to show to user from checkout (billing/shipping) country fields

Facts:

  • My Woocommerce Selling Location(s) settings are: Germany, Andorra, Austria, Bulgaria, Belgium, Croatia, Denmark, Slovakia, Slovenia, Spain, Estonia, Finland, France, Greece, Hungary, Ireland, Latvia, Lithuania, Luxembourg, Monaco, Netherlands, Poland, Portugal, United Kingdom (UK), Czech Republic, Romania, Sweden and Switzerland
  • I want to sell to all of these countries, so removing countries from Selling Location(s) list is not a solution.
  • I need a hook/filter solution, please.

What have I've done so far:

  • I've tried out several hooks/filters to achieve that: woocommerce_checkout_get_value, woocommerce_shipping_fields, woocommerce_billing_fields, woocommerce_default_address_fields and woocommerce_checkout_fields. None of them seems to work...

Code I've written:

// NOT WORKING! SHOWS ALL Selling Location(s) (allowed countries)
function override_checkout_fields( $fields ) {
    $fields['shipping']['shipping_country'] = array(
        'type'         => 'country',
        'label'        => __( 'Country / Region', 'woocommerce' ),
        'required'     => true,
        'class'        => array( 'form-row-wide', 'address-field', 'update_totals_on_change' ),
        'autocomplete' => 'country',
        'priority'     => 40,
        'options'      => array( $user_country_code => __( $user_country_name, 'woocommerce' ) )
    );
    
    //Same for billing_country...
    
    return $fields;
}
add_filter( 'woocommerce_checkout_fields' , 'override_checkout_fields', 10, 1 );

// NOT WORKING! SHOWS ALL Selling Location(s) (allowed countries)
function edit_billing_fields( $fields ) {
    $fields['billing']['billing_country'] = array(
        'type'         => 'country',
        'label'        => __( 'Country / Region', 'woocommerce' ),
        'required'     => true,
        'class'        => array( 'form-row-wide', 'address-field', 'update_totals_on_change' ),
        'autocomplete' => 'country',
        'priority'     => 40,
        'options'      => array( $user_country_code => __( $user_country_name, 'woocommerce' ) )
    );
    return $fields;
}
add_filter( 'woocommerce_billing_fields', 'edit_billing_fields' );

... And more

NOTE: If I change 'type' => 'country' by 'type' => 'select' it works, but then if I change country (showing two countries for testing), the state dropdown do not update whith the states for that new selected country. Also the dropdown is shown without Select2 appeareance.

Further Explanation: I am selling now to 28 countries. For example, if a user is accessing the web from France, when the user arrives at checkout form, I only want to let you send the product to France. This is the reason why I want to show only the user country (previously geolocated) in the (billing/shipping) country dropdown.

I would appreciate your help! Thanks

1
  • I believe, there is no 'type' as 'country'. Can you change 'type' to 'text' and apply a css class that will make it disabled ?
    – ViralP
    Jun 20 '20 at 17:41
1

If 'type' => 'select' works for you then to solve state selection, you can try woocommerce_states and woocommerce_countries_allowed_country_states filter to list states only for the user's country.

Reference : https://wordpress.stackexchange.com/a/320548/163113

1
  • Hi @ViralP! Appreciate your time to answer the question. Yes, I could do it as the way you say. But also, I've found another way, through the filter woocommerce_countries_allowed_countries. I'll show you that in a new answer. Thanks again!
    – hormigaz
    Jun 25 '20 at 11:18
0

I've managed to fix it by focusing to a different filter, one that doesn't have to do with the checkout directly. The filter in question is woocommerce_countries_allowed_countries. This filter is in the get_allowed_countries() function and gets the countries the store sells to. So limiting the countries the store sells to, I fix the country listing problem at checkout. In this way, a french user will only see France in the country dropdown, an australian user will only see Australia in the country dropdown and so on... Here is the code:

/**
 * @param array $countries
 * @return array
 */
function custom_update_allowed_countries( $countries ) {

    // Only on frontend
    if( is_admin() ) return $countries;

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

        if ( isset( $location['country'] ) ) {
            $countryCode = $location['country'];
        } else {
            // If there is no country, then return allowed countries
            return $countries;
        }
    } else {
        // If you can't geolocate user country by IP, then return allowed countries
        return $countries;
    }

    // If everything went ok then I filter user country in the allowed countries array
    $user_country_code_array = array( countryCode );

    $intersect_countries = array_intersect_key( $countries, array_flip( $user_country_code_array ) );

    return $intersect_countries;
}
add_filter( 'woocommerce_countries_allowed_countries', 'custom_update_allowed_countries', 30, 1 );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.