2

I am looking for solution where I can find user's country in woocommerce checkout page. I am doing it via geolocation. However, the user can change that. I want to restrict it.

I am using a paid plugin to give coupons to users from a specific country. The country gets loaded perfectly and coupon is applied or rejected based on country. However, the user manually can change the country at the checkout page and avail the discount. My service is online thus there is no delivery of physical goods so entering wrong country wouldn't cause anything to the user.

I have tried 2-3 different coupon restriction plugins but all has the same problem. Does anyone has faced similar issue?

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
mandar
  • 35
  • 1
  • 12

1 Answers1

2

Updated

You can make checkout country dropdown fields disabled (read only) as follows:

add_filter( 'woocommerce_checkout_fields', 'checkout_country_fields_disabled' );
function checkout_country_fields_disabled( $fields ) {
    $fields['billing']['billing_country']['custom_attributes']['disabled'] = 'disabled';
    $fields['billing']['shipping_country']['custom_attributes']['disabled'] = 'disabled';

    return $fields;
}

As disabled select fields doesn't get posted, you need additionally the following duplicated hidden fields with the correct values set in. It will avoid an error notice notifying that country required fields values are empty. So add this too:

// Mandatory for disable fields (hidden billing and shipping country fields with correct values)
add_filter( 'woocommerce_after_checkout_billing_form', 'checkout_country_hidden_fields_replacement' );
function checkout_country_hidden_fields_replacement( $fields ) {
    $billing_country = WC()->customer->get_billing_country();
    $shipping_country = WC()->customer->get_shipping_country();
    ?>
    <input type="hidden" name="billing_country" value="<?php echo $billing_country; ?>">
    <input type="hidden" name="shipping_country" value="<?php echo $shipping_country; ?>">
    <?php
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.


Notes:

You will need to disable shipping calculator in cart page, if it's not done.

If you want to make country dropdown read only in Checkout and in My account Edit Address too, use the following instead:

add_filter( 'woocommerce_billing_fields', 'checkout_billing_country_field_disabled' );
function checkout_billing_country_field_disabled( $fields ) {
    $fields['billing_country']['custom_attributes']['disabled'] = 'disabled';

    return $fields;
}

add_filter( 'woocommerce_shipping_fields', 'checkout_shipping_country_field_disabled' );
function checkout_shipping_country_field_disabled( $fields ) {
    $fields['shipping_country']['custom_attributes']['disabled'] = 'disabled';

    return $fields;
}

// Mandatory for disable fields (hidden billing and shipping country fields with correct values)
add_filter( 'woocommerce_after_checkout_billing_form', 'checkout_country_hidden_fields_replacement' );
function checkout_country_hidden_fields_replacement( $fields ) {
    $billing_country = WC()->customer->get_billing_country();
    $shipping_country = WC()->customer->get_shipping_country();
    ?>
    <input type="hidden" name="billing_country" value="<?php echo $billing_country; ?>">
    <input type="hidden" name="shipping_country" value="<?php echo $shipping_country; ?>">
    <?php
}
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • I tried this. The country is getting disabled properly. However when I place order I am getting this error. Billing Country / Region is a required field. – mandar Jan 23 '21 at 16:28
  • Thanks buddy for the quick reply. Sorry, I didn't give full picture. After applying your code, country got disabled. It is showing the correct country as per geolocation and state dropdown is also getting populated properly (based on geolocation country). In next step when I submit I am getting this error. As I have mentioned in the question, I want to restrict the user from changing the country. Your solution works perfectly but if the user can't complete the order then it is of no use. – mandar Jan 23 '21 at 17:37
  • It seems the geolocation is setting the value properly. If I inspect the country element, I can see India as selected. The state list is also getting populated based on country. Now I dont know whether billing country variable which is required to complete the order is different from the one which is shown on the screen. If I use unset($fields['billing']['billing_country']); unset($fields['shipping']['shipping_country']); then the whole functionality is working. The only thing is user can't view the country selected. – mandar Jan 23 '21 at 17:56
  • Disabled fields will not be submitted. This the problem for giving the error while placing the order. https://stackoverflow.com/questions/368813/html-form-readonly-select-tag-input – mandar Jan 23 '21 at 18:10
  • thanks buddy. The solution initially didn't work. But after a bit googling around I changed the hook from woocommerce_after_checkout_shipping_form to woocommerce_after_checkout_billing_form and it worked. I will go ahead with it as of now. However there is a loophole which I need to tackle. The user can remove disabled attribute from browser's developer tools, change the country and proceed. I will work on it. Thanks for your time and effort. – mandar Jan 24 '21 at 17:22