WooCommerce: Disable Payment Gateway by Country

You might want to disable PayPal for non-local customers or enable a specific gateway for only one country… Either way, this is a very common requirement for all of those who trade internationally.

Here’s a simple snippet you can further customize to achieve your objective. Simply pick the payment gateway “slug” you want to disable/enable (“paypal”, “authorize”, “stripe”, etc.) and the country code (US, ES, IE, etc.) and then apply your conditional rules in the plugin below.

Find payment gateway ID under WooCommerce > Settings > Payments

PHP Snippet: Disable Payment Gateway for Specific Billing Country

/**
 * @snippet       WooCommerce Disable Payment Gateway for a Specific Country
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 7
 * @community     https://businessbloomer.com/club/
 */
 
add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_payment_gateway_disable_country' );
 
function bbloomer_payment_gateway_disable_country( $available_gateways ) {
    if ( is_admin() ) return $available_gateways;
    if ( isset( $available_gateways['authorize'] ) && WC()->customer && WC()->customer->get_billing_country() <> 'US' ) {
        unset( $available_gateways['authorize'] );
    } else {
        if ( isset( $available_gateways['paypal'] ) && WC()->customer && WC()->customer->get_billing_country() == 'US' ) {
            unset( $available_gateways['paypal'] );
        }
    }
    return $available_gateways;
}

Mini-Plugin: Business Bloomer WooCommerce Toggle Payments By Country

You donโ€™t feelย confident with coding?ย You needย more control over your payment/country exclusions? You donโ€™t want to purchase yet another bloated, expensive plugin? Great!

Business Bloomer WooCommerce Toggle Payments By Countryย is aย mini WooCommerce plugin, without the usual hassles. One feature. Lifetime license. No annoying subscriptions. 1 plugin file. A few lines of code. No banners. No up-sells. No WP notifications. Use it on as many websites as you like. Lifetime support. 1-page documentation. A single and easy admin dashboard.

Screenshot of the settings:

Quick demo:

As you can see the settings are pretty straight forward.ย Select a payment method you wish to hide/show from the left, and the country that should trigger that from the right.ย Add more rules if needed. Simple!

Advanced “Payment Gateways by Country” WooCommerce Plugin

If you don’t feel 100% confident with coding, I decided to look for a reliable plugin that achieves the same result of this snippet (and more).

In this case, I found the WooCommerce Conditional Payment Gateways plugin to be the most complete when you need to enable/disable payment gateways based on certain criteria. You can create unlimited “rules” and use, for example, cart totals, billing country, shipping country, user role and much more to define which payment gateway shows and which not.

But in case you don’t want to use plugins and wish to code (or wish to try that), then keep reading ๐Ÿ™‚

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

  • WooCommerce: Cart and Checkout on the Same Page
    This is your ultimate guide – complete with shortcodes, snippets and workarounds – to completely skip the Cart page and have both cart table and checkout form on the same (Checkout) page. But first… why’d you want to do this? Well, if you sell high ticket products (i.e. on average, you sell no more than […]
  • WooCommerce: Disable Payment Method If Product Category @ Cart
    Today we take a look at the WooCommerce Checkout and specifically at how to disable a payment gateway (e.g. PayPal) if a specific product category is in the Cart. There are two tasks to code in this case: (1) based on all the products in the Cart, calculate the list of product categories in the […]
  • WooCommerce: Add Privacy Policy Checkbox @ Checkout
    Here’s a snippet regarding the checkout page. If you’ve been affected by GDPR, you will know you now need users to give you Privacy Policy consent. Or, you might need customer to acknowledge special shipping requirements for example. So, how do we display an additional tick box on the Checkout page (together with the existing […]
  • WooCommerce: Redirect to Custom Thank you Page
    How can you redirect customers to a beautifully looking, custom, thank you page? Thankfully you can add some PHP code to your functions.php or install a simple plugin and define a redirect to a custom WordPress page (as opposed to the default order-received endpoint). This is a great way for you to add specific up-sells, […]
  • WooCommerce: Disable Payment Gateway for Specific User Role
    You may want to disable payment gateways depending on the logged in user role. For example, you may want to disable PayPal for user role “subscriber” or enable a specific gateway for user role “customer”. All you need is to paste the following code in your functions.php or to install a super simple plugin. Enjoy!

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza. Follow @rmelogli

148 thoughts on “WooCommerce: Disable Payment Gateway by Country

  1. How to add more than one country?

    1. Hello Anish, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  2. This is no longer compatible with WooCommerce 6.2.1. If you have the snippet in your functions.php and you try to update from 6.2.0 to 6.2.1 it will try, but won’t work – the update will still be available and your WooCommerce version will remain at 6.2.0. Comment out this snippet and the WooCommerce update suceeds. Any idea what the magic is to make it work correctly with 6.2.1? I think “WC()->customer->get_billing_country()” is causing the issues.

    1. That’s weird, unless 6.2.1 has a bug? Let me know

      1. Yes, I have the same issue.
        This is normal if no customer is loaded. In this case, WC() -> customer is null, instead of the WC_Customer object.
        I recommend adding the following line;

        if(!is_object(WC()->customer) OR !method_exists(WC()->customer,'get_billing_country') ){
        		return $available_gateways;
        	}

        The complete code:

        add_filter('woocommerce_available_payment_gateways', 'bbloomer_payment_gateway_disable_country');
        
        
        
        function bbloomer_payment_gateway_disable_country($available_gateways)
        {
        
        	if (is_admin()) return $available_gateways;
        
        	if(!is_object(WC()->customer) OR !method_exists(WC()->customer,'get_billing_country') ){
        		return $available_gateways;
        	}
        	//Deactivate Invoice if country is not Switzerland
        
        	if (isset($available_gateways['invoice']) && WC()->customer->get_billing_country() <> 'CH') {
        
        		unset($available_gateways['invoice']);
        	}
        
        	return $available_gateways;
        }
  3. Impecable!!
    Thank you!
    I was looking for a way to find the gateways IDs and I found this perfect snippet!

  4. Hi Rodolfo,
    following Your snippet I added the following code:

    add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_payment_gateway_disable_country' );
    function bbloomer_payment_gateway_disable_country( $available_gateways ) {
        if ( is_admin() ) return $available_gateways;
        if ( isset( $available_gateways['authorize'] ) && WC()->customer->get_billing_country() == 'IT' ) {
            unset( $available_gateways['authorize'] );
        } else {
            if ( isset( $available_gateways['paypal'] ) && WC()->customer->get_billing_country() <> 'IT' ) {
                unset( $available_gateways['cod'] );
            }
        }
        return $available_gateways;
    }
    

    but in error log I find the following error:

    08-Nov-2020 20:05:35 UTC] PHP Fatal error: Uncaught Error: Call to a member function get_billing_country() on null

    Any idea?
    Thank You very much for Your attention
    Ale

    1. Uhm, was it a guest order, so there was no “customer”?

      1. I’m having the same error, is there a way to check first if we have a

        WC()->customer 

        and if we do, call

        WC()->customer->get_billing_country()

        ? And get rid of the error?

        Thank you Rodolfo!

        1. Sure!

          if ( WC()->customer ) {
             // code here
          }
          
          1. Hi Rodolfo,
            unfortunatly after the latest update of woocommerce this snippet doesn’t work anymore. In addition (as You wrote before) it doesn’t manage guest checkout.
            I’m so sorry…
            Thx for Your support
            Ale

            1. Sure?

              To troubleshoot, disable all plugins but WooCommerce and also switch temporarily to “Twentytwenty” theme (load the snippet there in functions.php) as explained here: https://www.businessbloomer.com/lesson/trwm4l01/

              Once you do that, does it work? If yes, you have a problem with your current theme or one of the plugins.

              Hope this helps!

              1. Try this code instead (it excludes payment methods based on Geoip user location):

                add_filter( 'woocommerce_available_payment_gateways', 'geo_country_based_available_payment_gateways', 90, 1 );
                function geo_country_based_available_payment_gateways( $available_gateways ) {
                  // Not in backend (admin)
                  if( is_admin() )
                    return $available_gateways;
                
                  // ==> HERE define your country codes
                  $allowed_country_codes = array('PL');
                
                  // Get an instance of the WC_Geolocation object class
                  $geolocation_instance = new WC_Geolocation();
                  // Get user IP
                  $user_ip_address = $geolocation_instance->get_ip_address();
                  // Get geolocated user IP country code.
                  $user_geolocation = $geolocation_instance->geolocate_ip( $user_ip_address );
                
                  // Disable payment gateways for all countries except the allowed defined coutries
                  if (  in_array( $user_geolocation['country'], $allowed_country_codes ) ) {
                    unset( $available_gateways['paypal'] );
                  }
                
                  return $available_gateways;
                }
                
  5. Hi! I am using the following:

    add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_payment_gateway_disable_country' );
      
    function bbloomer_payment_gateway_disable_country( $available_gateways ) {
        if ( is_admin() ) return $available_gateways;
       if ( isset( $available_gateways['wpg_paypal_express'] ) &amp;&amp; WC()-&gt;customer-&gt;get_billing_country() == 'AR' ) {
            unset( $available_gateways['wpg_paypal_express'] );
        }
    	if ( isset( $available_gateways['woo-mercado-pago-basic'] ) &amp;&amp; WC()-&gt;customer-&gt;get_billing_country() != 'AR' ) {
            unset( $available_gateways['woo-mercado-pago-basic'] );
        }
    	if ( isset( $available_gateways['woo-mercado-pago-custom'] ) &amp;&amp; WC()-&gt;customer-&gt;get_billing_country() != 'AR' ) {
    		unset( $available_gateways['woo-mercado-pago-custom'] );
        }
    	if ( isset( $available_gateways['woo-mercado-pago-ticket'] ) &amp;&amp; WC()-&gt;customer-&gt;get_billing_country() != 'AR' ) {
            unset( $available_gateways['woo-mercado-pago-ticket'] );
        }
        return $available_gateways;
    }
    

    But im getting an error, wich is caused by this particular code. Its on the WordPress Rest API. Any way to solve this?

    1. Which error did you get?

      1. Hi, same error here.

        (500) Fatal error: Uncaught Error: Call to a member function get_billing_country() on null in …

        1. I’ve used get_shipping_country instead because we need to avoid people to ship in certain countries. (using billing, ad user can place an order billing in his country and ship in another country)

  6. Thank you for this great Snippet!!!

    1. You’re welcome!

  7. Hi Rodolfo, why you put for the same method id ‘isset’ and ‘unset’?
    if ( isset( $available_gateways[‘authorize’] ) && WC()->customer->get_billing_country() ‘US’ ) {
    unset( $available_gateways[‘authorize’] );

    1. So I first check if it exists

  8. i am using 4 payment gateway so how to modify this code
    i need this
    1.paypal & bitpay – worldwide
    2.stripe – us,uk,canada,
    3.cashfree – India only
    4,payumoney – India Only
    5.Bank Transfer – India,Saudi arabia

    Please Help Me

    1. Askarali, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  9. Hello,

    I want to disable payment method COD oitside india. Is the below code is correct?

    function payment_gateway_disable_country( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways['cod'] ) &amp;&amp; $woocommerce-&gt;customer-&gt;get_country() != 'IN' ) {
    unset( $available_gateways['cod'] );
    } 
    return $available_gateways;
    }
    add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
    

    Please help

    1. Looks good to me, yes ๐Ÿ™‚

  10. Hi there! Have been using this code successfully, but now i’m getting this php error:
    “get_billing_country was called incorrectly. Customer properties should not be accessed directly. “.
    I’m using your latest update. What am I missing?

    1. Hi Dani, weird. If you disable the snippet do you still get the error or not?

      1. When it is disabled we don’t get this error

        1. Hi Dani, I can’t replicate the error. I just tested this again with Storefront theme and it works perfectly. Maybe your theme (or another plugin) is messing/conflicting with my snippet?

          To troubleshoot, disable all plugins but WooCommerce and also switch temporarily to “Twentyseventeen” theme (load the snippet there in functions.php) – does it work? If yes, you have a problem with your current theme or one of the plugins.

          Hope this helps!

          R

  11. Fantastic ! Thank you so much.

    1. You’re welcome!

    2. Woocommerce version 3.5.6 no longer displays payment method ID’s in Woocommerce/Settings/Payments. Where can I find them.

      1. Blog post updated.

  12. thank you. works still great for me in woocommerce 3.5.3

    1. Great!

  13. Hello
    How can i restict for currency or many currences? For examples EUR and GBP ?

    1. Hey Michael, thanks for your comment! That will depend on the currency switcher plugin you use ๐Ÿ™‚

  14. Woocommerce->Settings->Checkout is not there anymore? Anywhere else where I can find the gateway ids?

    1. Robin, thanks for your comment! You’re right ๐Ÿ™‚

      It’s now WooCommerce->Settings->Payments

  15. Hello,

    Is it possible to restrict per zone?
    I have 10 zones in my country im sending too.
    Some of them i want to restrict payment methods.

    Is that possible?

    1. Hello Pepijn, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R

  16. Doesn’t seem compatible with the last WooCommerce version unfortunately. First statement seems to disable the payment method for all countries, second statement doesn’t seem to take effect at all.

    1. Hey Luke, works for me ๐Ÿ™‚ Try switching to a default theme and disabling all plugins but Woo, then test again. Let me know

  17. Its working!! Thank you very much Rodolfo!

    1. You’re welcome ๐Ÿ™‚

  18. Hi ๐Ÿ™‚ Great snippet, I like it and it is working smoothly.
    I have multiple countries to be avoided of a specific payment methods. I tried to use || operator on the list of countries, but it broke up. Any ideas how to implement it?
    Thanks there !

    1. Hey Dani – thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R

    2. Hi there, thanks ๐Ÿ™‚
      I finally realized how to pull it through:

      
      add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_payment_gateway_disable_country' );
       
      function bbloomer_payment_gateway_disable_country( $available_gateways ) {
      global $woocommerce;
      if ( is_admin() ) return;
      if ( isset( $available_gateways['officeguy'] ) &amp;&amp; ($woocommerce-&gt;customer-&gt;get_billing_country() == 'GR' || $woocommerce-&gt;customer-&gt;get_billing_country() == 'GR' || $woocommerce-&gt;customer-&gt;get_billing_country() == 'GR' || $woocommerce-&gt;customer-&gt;get_billing_country() == 'GR' || $woocommerce-&gt;customer-&gt;get_billing_country() == 'GR' || $woocommerce-&gt;customer-&gt;get_billing_country() == 'GR' || $woocommerce-&gt;customer-&gt;get_billing_country() == 'GR' || $woocommerce-&gt;customer-&gt;get_billing_country() == 'GR' || $woocommerce-&gt;customer-&gt;get_billing_country() == 'GR')) {
      unset( $available_gateways['officeguy'] );
      }
      return $available_gateways;
      }
      
      

      ** Change ‘GR’ to the countries you wish to avoid

      1. Nice ๐Ÿ™‚

  19. Hi There,
    This one is working from me for long time. i wanted one PG for only One specific Country. Now , I would like to add one more PG in same list for same country only . What do i need to add in snippet ?
    Thanks

    1. Hi Kumar, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  20. Looking good! Thanks a lot for the snippet and guide.

  21. I used the snippet with Woo 3.3.1 is still working but in somehow it doesnโ€™t permit the WP menu section to display

    1. You’re right Marwa ๐Ÿ™‚ Snippet has now been revised.

    2. I had the same problem, seems that

      if ( is_admin() ) return;

      does the trick.
      But I still find this error in my phpo error log:

      PHP Fatal error: Uncaught Error: Call to a member function get_billing_country() on null in /…../wordpress/wp-content/themes/vantage-child/functions.php:

      1. Hey Louis, can you try the latest version please?

  22. Using the latest code and got “Instant โ€˜woocommerce_available_payment_gatewaysโ€™ – assumed ‘โ€˜woocommerce_available_payment_gatewaysโ€™’ on line 20 Notice: Use of undefined constant โ€˜payment_gateway_disable_countryโ€™ – assumed ‘โ€˜payment_gateway_disable_countryโ€™’ on line 20

    on the line 20 is add_filter(โ€˜woocommerce_available_payment_gatewaysโ€™, โ€˜payment_gateway_disable_countryโ€™,10,1 ); or add_filter(โ€˜woocommerce_available_payment_gatewaysโ€™, โ€˜payment_gateway_disable_countryโ€™ );. We’ve tested both situation. What do we miss?

    1. Marketa , thanks for your comment! Maybe your theme (or another plugin) is messing/conflicting with my snippet?

      To troubleshoot, take a look at this tutorial to see how to troubleshoot: https://businessbloomer.com/woocommerce-troubleshooting-mistakes-to-avoid/

      Finally, can you try switching temporarily to “Twentyseventeen” or “Storefront” theme and let me know if it works?

      Hope this helps!

      R

  23. Hi, we are using this great plugin and it worked really good until we moved our site on a new hosting and upgraded wordpress, woocommerce and php to the last version…… i mean, the snippet is still working but in somehow it doesn’t permit the WP menu section to display… i mean, if i quit your snippet from the function.php the WP menu displays and works without problems… if i put the snippet… well….it doesn’t.

    1. Ciao Angelo, thanks so much for your comment! I just retested this on the latest version of WooCommerce and you’re right, it gave error. I’ve now posted the correct snippet, valid for Woo 3.0 and above ๐Ÿ™‚

    2. Grazie mille Rodolfo!! ๐Ÿ™‚ … i check the page and i think you’are having problem with the [/php] shortcode: is not detecting the code as “code” … check it out.

      PS: the snippet now works great!!

  24. Ciao Rodolfo,
    is possible to disable ALL payment methods (and so avoid order) for a specific shipping zone, or for the “rest of the world” zone?

    I want so sell only in some specific CAP in italy, and not in the ones outside that area (is a local service).

    Is that possible?

    1. Ciao Omar, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  25. Hi Rodolfo,
    I want to hide a payment gateway when a company name is entered. Unfortunately after entering a company name the payment options are not reloaded and therefore [paymentmethodXY] is still available.
    Do you know how i can trigger a reload of the payment methods so [paymentmethodXY] is gone?
    Thanks a lot.
    Best Regards,
    Toralf

    1. Hey Toralf, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  26. Hi Great Rodolfo. Do you think there is way to hide a payment gateway based on city?
    Thanks in advanced

    1. David, thanks so much for your comment! Yes, this is definitely possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  27. Hi Rodolfo,
    the code works fine on the frontend page. But I get an error message “PHP Fatal error: Call to a member function get_country() on null” and I don’t see my subscriptions anymore on the admin page.
    Any suggestions are very appreciated.
    My code:

    function bbloomer_payment_gateway_disable_country( $available_gateways ) {
    global $woocommerce;
    // 1. Get current country
    $ccountry = $woocommerce->customer->get_country();

    // 2. Check if current country is in your array of countries
    $enabledcountries = array("DE");
    if (in_array($ccountry, $enabledcountries)) {
    $itsenabled = true;
    } else {
    $itsenabled = false;
    }

    // 3. Original function
    if ( isset( $available_gateways['bacs'] ) && !$itsenabled) {
    unset( $available_gateways['bacs'] );
    }
    return $available_gateways;
    }

    add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_payment_gateway_disable_country' );

    1. Eric, thanks so much for your comment! Unfortunately this is custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~R

    2. Hi Rodolfo,
      I understand it. Meanwhile I found on github an approach, that inserts an is_admin-check before restricting the payment gateways. With that code I could see the subscriptions again.

      I just want to let you know, that I nevertheless disabled the function, because it somehow interferes with WooCommerce Subscription. Renewal payment orders aren’t handled properly. Orders are created but not further processed.

      Thank you though
      Eric

      1. Ok Eric, no problem ๐Ÿ™‚

  28. Hello, i got this code working, thank you very much.
    But i got 1 question and 1 sort of beauty mistake.

    The mistake, when my customers goes to checkout, every payment gateway is there, when they switch countries it changes.
    Exemple (standard country is The Netherlands), when they go to checkout 4 payment options are available, but when i switch to Germany and then back, the 2 (correct) payment options are left. You know how this is possible.

    The other is a question, i got multiple payment methods. But 1 i need to have more countries, is that possible with this line and how do i have to adjust this line?

    } if ( isset( $available_gateways['paypal'] ) && $woocommerce->customer->get_country() <> 'MT' ) {
    unset( $available_gateways['paypal'] );
    1. Sorry, i believe the mistake where all payment methods were available was my bad (cookies and history) haha.
      But the second one is very much needed. I am not really a php writer, haha. Thanks in advance.

      1. Hey Maikel, thanks for your comment! Just add more of these:

         && $woocommerce->customer->get_country() <> 'US' && $woocommerce->customer->get_country() <> 'UK' 
  29. Hi,
    I’m using this code, it works flawlessly but Stripe is throwing some cosmetic errors, which do not resolve until a refresh at checkout, I’m attaching screen shots below.

    If my user is changing from India to any other country, the code defaults to displaying Stripe and PayPal as the payment option, but in this case, Stripe will not load properly. Highlighting them in the images attached below.

    add_filter('woocommerce_available_payment_gateways', 'payment_gateway_disable_country');
    
    function payment_gateway_disable_country($available_gateways)
        {
        global $woocommerce;
        if (isset($available_gateways['payu_in']) && $woocommerce->customer->get_shipping_country() <> 'IN')
            {
            unset($available_gateways['payu_in']);
            }	
          else
        if (isset($available_gateways['paypal']) && $woocommerce->customer->get_shipping_country() == 'IN')
            {
            unset($available_gateways['paypal']);
            }
    	if (isset($available_gateways['stripe']) && $woocommerce->customer->get_shipping_country() == 'IN')
            {
            unset($available_gateways['stripe']);
            }
        if (isset($available_gateways['cod']) && $woocommerce->customer->get_shipping_country() <> 'IN')
            {
            unset($available_gateways['cod']);
            }
          
        return $available_gateways;
        }

    When shipping country is changed from India to any other country. This is how stripe loads and it doesn’t get fixed unless the page is refreshed. (Doesn’t auto detect Card Type or input dates properly)

    https://imgur.com/a/fk13y

    Ideal loading of Stripe (notice auto detection of card type and proper input of dates)

    https://imgur.com/a/Gepgz

    Would appreciate if you could help fix this.

    Warm Regards.

    1. Pramathesh, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here on the blog. Thanks a lot for your understanding! ~R

  30. thank you for the awesome work … once again you saved me from a lot of trouble

    1. Cheers Manos! ๐Ÿ™‚

  31. Hi,
    Excellent snippet!
    I’m looking for, to improve your snippet code
    I’d wish to disable all payments for some specifics countries (France & Belgium, by example) and add a common text in replacement of inital Purchase details OR replace “PURCHASE” text button by another text like “CONTACT RESSELLER” with a custom link.
    Here, what I did for the moment

    function payment_gateway_disable_country( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways['authorize'] ) && $woocommerce->customer->get_country() <> 'FR' && 'BE' ) {
    unset( $available_gateways['authorize'] );
    } else if ( isset( $available_gateways['paypal'] ) && $woocommerce->customer->get_country() == 'FR' && 'BE' ) {
    unset( $available_gateways['paypal'] );
    unset( $available_gateways['bacs'] );
    unset( $available_gateways['cod'] );
    echo "<table class="shop_table woocommerce-checkout-review-order-table"></table>";
    echo "<input class="button alt" name="woocommerce_checkout_place_order" id="place_order" value="Payer avec PayPal" data-value="Commander" type="submit"><input id="_wpnonce" name="_wpnonce" value="a55446108f" type="hidden">"<input name="_wp_http_referer" value="https://www.anotherwebsite.com" type="hidden">";
    }
    return $available_gateways;
    }
     
    add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
    

    Thanks alot for your helping!
    Cheers,
    Nico.

    1. Hey Nico, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here on the blog. Hopefully I will have time to create a snippet soon ๐Ÿ™‚ Thanks a lot for your understanding! ~R

    2. I think that you’ll have to break this into two steps because the ‘woocommerce_available_payment_gateways’ occurs before the template file is processed i.e. you cannot display something at this point.

      To disable all gateways you can simply return an empty array from the function.

  32. Hello Rodolfo,

    By the way We want Stripe Payment Gateway only available in Australia and not available outside Australia here is my code

    
    function payment_gateway_disable_country( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways['stripe'] ) &amp;&amp; $woocommerce-&gt;customer-&gt;get_country()  'AU' ) {
    unset( $available_gateways['stripe'] );
    } 
    return $available_gateways;
    }
     
    add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
    
    

    Regards,
    Hannah

    1. Hey Hannah thanks for your comment! Are you saying your code doesn’t work? Sorry, it’s not clear what your question is ๐Ÿ™‚

  33. Hi Rodolfo,

    can you please tell how and where to implement this function? I have now in wp/wp-includes/functions.php but I doesn’t work. In my opinion this function must be called from somewhere but where?

    Thanks for reply, Ivan

    1. Hey Ivan, thanks for your comment! No, you should never edit WordPress core files ๐Ÿ™‚ You can place this in your child theme’s functions.php file – if you need more guidance, please take a look at this video tutorial: https://businessbloomer.com/woocommerce-customization-hangout/. Thank you!

  34. Hi!
    Help me! How to hide a specific payment method in the checkout page?

    1. Erik, you should be able to do that from the WooCommerce settings ๐Ÿ™‚ Thanks for your comment and let me know if this helps!

      1. I just need to hide on the checkout page. Leave in the payment profile ๐Ÿ™‚
        Excuse me for my bad English ( I am from Italy :))

        1. Hey Erik, I’m not sure what you mean by “payment profile”. Maybe a screenshot might help? Let me know

  35. Hi, thanks for your codes, works fine but there is a small issue here. When i set the city name: New York, then check out with the same names but with different formats like new york, NEW YORK, NeWyoRk,…. it doesn’t work, the customer has to type the exact name: New York in order to work. Help please!

    1. Hello there and thanks for your comment! This snippet limits shipping by country, so it wouldn’t work with cities. Are you using another snippet?

  36. Hi.
    I need a coding if you can help me in this case.I am new for all.
    I want to enable cash on delivery (COD) option only for one state and two other cities. So in this case what would be coding.
    Please reply soon. Thanks in advance.

    1. Hey Mohammad, thanks so much for your comment! I’m afraid I cannot provide a free solution right now, but I’ll make sure to add this to my to-write list of WooCommerce resources. Thanks for your understanding ๐Ÿ™‚

  37. Hello Rodolfo Melogli,

    Thanks for providing great solution worked for me too.

    But facing issue: the code does not work if shipping and billing countries are different.

    thanks,
    Vicky

    1. Hello Rodolfo Melogli,

      I mean to say it should work for billing address only but if shipping address selected than it should work for shipping address only and not for billing

      thanks,
      Vicky

      1. Hey Vicky thanks for your message! I think this is as simple as using “get_shipping_country()” instead of “get_country()”. Try that and let me know ๐Ÿ™‚

        1. Hello,

          Thanks for positive and quick reply.

          As per your reply I guess than it will only work with Shipping Address but it should not be the case instead

          By default it should check with billing address but if different shipping address check box is checked than it should verify or check with shipping address only.

          The thing you asked to change will only work when shipping address checked.

          Hope you are getting what I am trying to say.

          Thanks
          Vicky

          1. No problem Vicky ๐Ÿ™‚ Have you tested the new snippet already? I believe “get_shipping_country()” is the same as Billing Country in case shipping is not selected – give it a go!

  38. Hi,

    followed this instructions I managed to enable Bank wire payment for one country only.
    I would need to make it for two, but I’m getting an error.

    I would like to add AT and DE.
    What I have to change in third row, where do I have ” ‘AT’ ” ?

    
    function payment_gateway_disable_country( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways['bacs'] ) && $woocommerce->customer->get_country()  'AT' ) {
    unset( $available_gateways['bacs'] );
    } 
    return $available_gateways;
    }
    add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' ); 
    
    

    Thanks for your help !

    1. Hey Tomko, thanks for your question! You can do this:

      
      .....
      if ( isset( $available_gateways['bacs'] ) && ( $woocommerce->customer->get_country() == 'AT' || $woocommerce->customer->get_country() == 'DE' ) ) {
      .....
      
      
  39. Hello, i want to disable the payment method “invoice” for all countries except for Germany. I have adapted the code from above.

    
    /** Kauf auf Rechnung fรผr das Ausland deaktivieren */
    
    function payment_gateway_disable_country( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways['invoice'] ) && $woocommerce->customer->get_country()  'DE' ) {
    unset( $available_gateways['invoice'] );
    return $available_gateways;
    }
     
    add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
    
    

    But it do not work. I get the message:

    Warning: Cannot modify header information – headers already sent by (output started at /homepages/37/d591495225/htdocs/***/themes/vendipro/functions.php:1) in /homepages/37/d591495225/htdocs/***/wp-includes/pluggable.php on line 1228

    Please, help me! Thank you a lot.

    1. Hey Jonas thanks for your comment ๐Ÿ™‚ From what I see you have a missing ‘==’ before ‘DE’:

      
      /** Kauf auf Rechnung fรผr das Ausland deaktivieren */
      
      function payment_gateway_disable_country( $available_gateways ) {
      global $woocommerce;
      if ( isset( $available_gateways['invoice'] ) && $woocommerce->customer->get_country() == 'DE' ) {
      unset( $available_gateways['invoice'] );
      return $available_gateways;
      }
       
      add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
      
      

      Let me know ๐Ÿ™‚

      1. Thank you for your help. I have simply copied the code from your answer, but it appears again an error message. Did you have any idea what it could be ?

        1. Jonas, thanks for your feedback! What error are you getting?

  40. Hi again

    I forgot to mention, I would like to make changes when customer changes the language (i have WPML) not when they choose county address.

    Br, Marko

    1. Got it, short for Slovenia in woocommerce is SI not with litle L but with big i.

      Is it possible to add like I asked before on base what kind of language is chosen?

      Br, Marko

      1. ๐Ÿ™‚ Thanks for your feedback Marko!

  41. Hi,

    nice code. I want to unset cod for ever country except Slovenia but nothing works. But it does unset cod for every language. I think something is wrong in array(“Sl”) part.

    I tried this:

    function bbloomer_payment_gateway_enable_country( $available_gateways ) {
    global $woocommerce;

    // 1. get current country
    $ccountry = $woocommerce->customer->get_country();

    // 2. check if current country is in your array of countries
    $enabledcountries = array(“Sl”);

    if (in_array($ccountry, $enabledcountries)) {
    $itsenabled = true;
    }

    // 3. original function
    if ( isset( $available_gateways[‘cod’] ) && !$itsenabled ) {
    unset( $available_gateways[‘cod’] );
    }

    return $available_gateways;
    }

    add_filter( ‘woocommerce_available_payment_gateways’, ‘bbloomer_payment_gateway_enable_country’ );

    and this

    function payment_gateway_disable_country( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways[‘cod’] ) && $woocommerce->customer->get_country() ‘Sl’ ) {
    unset( $available_gateways[‘cod’] );
    }

    return $available_gateways;
    }

    add_filter( ‘woocommerce_available_payment_gateways’, ‘payment_gateway_disable_country’ );

    with different types of language “short tags” like “Sl_sl”, “SL”, “Slovenia”……

    tnx, br

  42. This works great, thank you so much!! Is it possible to restrict gateways based on country only for certain products? I want to restrict authorize_net_cim_credit_card but only on certain non-virtual products.

    1. Thanks for your feedback Chris! Sure, you should be able to check if a certain product ID is in the cart before running my function. I suggest to check this blog from Remi Corson, it will send you in the right direction: https://www.remicorson.com/woocommerce-check-if-product-is-already-in-cart/. Thank you!

  43. Thank you Rodolfo!

    I used the version to enable!

    It worked perfectly!

  44. Hello Sir

    Thanks for this code

    Please

    what shall i put in the payment gateway ID or name?
    Mine is a plugin called KNET Payement gateway
    how to name it? i mean it is not a one word name like paypal

    I want it to be shown to KUWAIT only if it is chosed as country bcoz that only accepts local payment
    now it appears for all countries in the world

    hope u can help

    KNET Payment Gateway – thats the name in checkouts tabs

    1. btw, i click on hire me but i didnt know what to do didnt find any button to do so

      1. Thanks for asking Mai. If you would like to get a quote for WooCommerce jobs, go here. Thank you! R

    2. Hello Mai! Thanks for your feedback ๐Ÿ™‚ I added an image to the blog post to show you where to find the Gateway ID. Hope this helps!

      1. YOU ARE THE BEST!!! NOW it works : )

        THANK YOU

        I so much liked ur blog and u r very helpful

        will make business with you one day am sure

        Thank you Rodolfo

        1. Ahah thank you Mai ๐Ÿ™‚

  45. Greetings

    Is it possible to disable gateway discounts if a specific shipping method is choosen?
    Example: When someone pays me in Bank transfer(bacs) they get x amount of discount. If they reach y total cost of items, they get frees hipping, but i dont want them to get this bacs discount if they have free shipping.
    Is it possible? Do you have any idea?

    Thanks

    1. Lotrai, thanks so much for your feedback! Yes, this is possible – but unfortunately it’s pretty custom and I cannot provide this solution on the blog. If you would like to get a quote, feel free to go here. Thank you! R

  46. Hi Rodolfo Grt Post Helped me a lot. Although instead of country i wanna try this out with postal codes Make COD option available for certain pins…How to do that ?

    1. Amit, thanks for your query! You can get the postcode via $woocommerce->customer->get_shipping_postcode() – and then make the function run only if that variable equals e.g. “90210”. Hope this helps!

  47. Sorry I’m not very PHP savvy, what is code if I only want to enable COD for certain countries? From my understanding, the code in your post will disable for certain countries. I need for multiple so please put a few sample countries in the code.

    Thanks so much!

    1. Hey there thanks for your feedback! To enable COD only for certain countries you can use the following workaround (let me know if it works!):

      function bbloomer_payment_gateway_enable_country( $available_gateways ) {
      global $woocommerce;
      
      // 1. get current country
      $ccountry = $woocommerce->customer->get_country();
      
      // 2. check if current country is in your array of countries
      $enabledcountries = array("UK", "US", "IE", "AU");
      if (in_array($ccountry, $enabledcountries)) {
      $itsenabled = true;
      }
      
      // 3. original function
      if ( isset( $available_gateways['cod'] ) && !$itsenabled ) {
      unset( $available_gateways['cod'] );
      }
      return $available_gateways;
      }
      add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_payment_gateway_enable_country' );
      
      
  48. Hi Rodolfo.
    Thank you for your code. I can’t make it work with my storefront child theme, only in the storefront theme… It’s no deal breaker, but is it possible to make it work in the child theme?
    Obrigado! ๐Ÿ™‚

    1. Hi Miguel, thanks for your query ๐Ÿ™‚ This is very weird, it should work in the parent or child theme no problem. Maybe you have an error in your child theme’s function.php and therefore the function you added is not loaded?

  49. Hello Rodolfo,

    I’ve tried your code on my website but I can’t make it work.
    I have 3 countries : FR, BE & CH.
    I have 3 payment gateways : cod, cheque & bacs.
    I need the 3 gateways to be available for France and I want CH & BE to only use the cod gateway.
    Hope it’s clear and you can help me fix this ๐Ÿ™‚

    Have a nice day !

    1. Hi again,

      I finally figured out how to deal with my problem by using this code :

      function payment_gateway_disable_country( $available_gateways ) {
      global $woocommerce;
      if ( isset( $available_gateways[‘cheque’] ) && $woocommerce->customer->get_country() ‘FR’ ) {
      unset( $available_gateways[‘cheque’] );
      }
      if ( isset( $available_gateways[‘bacs’] ) && $woocommerce->customer->get_country() ‘FR’ ) {
      unset( $available_gateways[‘bacs’] );
      }
      return $available_gateways;
      }
      add_filter( ‘woocommerce_available_payment_gateways’, ‘payment_gateway_disable_country’ );

      Thanks for sharing your knowledge with this article ๐Ÿ™‚

      1. Awesome Camille, thanks for the feedback!

  50. Hi Rodolfo,

    I have been trying out your code and cannot seem to get it to work on https://www.menorcameva.com. What I want to achieve is to remove the “Cash on Delivery” payment option when a client is not in Spain.

    This is the code I have used:

    function payment_gateway_disable_country( $available_gateways ) {

    global $woocommerce;

    if ( isset( $available_gateways[‘WC_Gateway_COD’] ) && $woocommerce->customer->get_country() ‘ES’ ) {

    unset( $available_gateways[‘WC_Gateway_COD’] );

    }

    return $available_gateways;

    }

    add_filter( ‘woocommerce_available_payment_gateways’, ‘payment_gateway_disable_country’ );

    It does not seem to be doing anything. Any ideas? Could it have something to do with the version of WooCommerce that we are using?

    Hope you can point me in the right direction.

    Best regards,

    James

    1. James thanks for your feedback!

      1) please change all the WC_Gateway_cod with cod
      2) please add <> to this line: if ( isset( $available_gateways[‘WC_Gateway_COD’] ) && $woocommerce->customer->get_country() <> ‘ES’ ) {

      Hope this helps!

      1. Rodolfo,

        The “” between get_country and ‘ES’ did not seem to paste correctly from my code editor. I noticed after hitting the submit button ๐Ÿ˜‰

        After the change from WC_Gateway_cod to cod it now works like a charm.

        Thanks.

  51. Hi Rodolfo, is it possible to hide all payment methods if customer choose local pickup? So the customer can pay in store…

    Thanks a lot

    1. Good question Dario, I’ll write a blog post about this maybe. For now I suggest you to use the Cash on Delivery (COD) payment gateway – and disable all the others if local shipping is chosen.

  52. Its working perfectly fine rest of all countries as well !!
    Thank you.

    1. Awesome, thanks Muhammad!

  53. This code is working perfectly fine only if i chose country “US”, rest of all countries are not working.

    1. Thank you Muhammad! Would you be able to send me a copy of your code so that I can take a look? It should work with all countries. Thank you!

  54. Hi Rodolfo, how can i enable just 1 specific payment gateway for 1 country? I want to have customers from holland, to give them the option to pay by invoice.

    Like to hear from you.

    Greetings carlo

    1. Hello Carlo, thanks for your comment! If you want to “enable” a gateway for a specific country, that’s equivalent to disabling that gateway for every country excluded Holland. Just use this:

      
      function payment_gateway_disable_country( $available_gateways ) {
      global $woocommerce;
      if ( isset( $available_gateways['YOUR_GATEWAY_ID'] ) && $woocommerce->customer->get_country() <> 'NL' ) {
      unset( $available_gateways['YOUR_GATEWAY_ID'] );
      } 
      return $available_gateways;
      }
      add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
      
      
      1. The code works! Thanks Rodolfo. I tried another option, but i can’t get it worked:
        I have also groups with groupricing, for normal B2C users, and for B2B users. Now i want to offer this payment gateway only to people from NL and logged in with B2B account. Can you make a suggestion for me how to solve this?

        Thaqnks in advance!!!!

        1. Thank you Carlo! You might want to use something like “if ( is_user_logged_in() && current_user_can( ‘administrator’ ) ) {}”… but of course it depends on the group plugin you’re using. Hope this helps!

Questions? Feedback? Customization? Leave your comment now!
_____

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining the Business Bloomer Club to get quick WooCommerce support. Thank you!

Your email address will not be published. Required fields are marked *