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!

The default WooCommerce settings may not be enough for you. What if you want “customers” to only pay via PayPal, while you want “subscribers” to be able to pay via bank transfers as well? Here’s the fix!

PHP Snippet 1: Disable Payment Gateway for a Specific User Role @ WooCommerce Checkout

/**
 * @snippet       Disable Payment Gateway by User Role | WooCommerce
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @testedwith    WooCommerce 7
 * @community     https://businessbloomer.com/club/
 */
 
add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_paypal_disable_manager' );
 
function bbloomer_paypal_disable_manager( $available_gateways ) {
   if ( isset( $available_gateways['paypal'] ) && wc_current_user_has_role( 'customer' ) ) {
      unset( $available_gateways['paypal'] );
   } 
   return $available_gateways;
}

PHP Snippet 2: Enable Payment Gateway Only for a Specific User Role @ WooCommerce Checkout

We will basically hide the gateway for all the other roles.

/**
 * @snippet       Enable Payment Gateway for User Role | WooCommerce
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 7
 * @community     https://businessbloomer.com/club/
 */
 
add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_paypal_enable_manager' );
 
function bbloomer_paypal_enable_manager( $available_gateways ) {
   if ( isset( $available_gateways['paypal'] ) && ! wc_current_user_has_role( 'subscriber' ) ) {
      unset( $available_gateways['paypal'] );
   } 
   return $available_gateways;
}

How to Find WooCommerce Payment Gateway ID

Here’s the screenshot. Basically, go to WooCommerce Settings > Payments, and either:

  • hover onto the “Manage” button, and read the URL parameter “section“. In this case, you will see “&section=bacs” so “bacs” is the payment gateway ID
  • or right click on the Method title, click on Inspect (Google Chrome), and find the “data-gateway_id” attribute. In this case, you will see “tr data-gateway_id=bacs” so “bacs” is the payment gateway ID

Mini-Plugin: Business Bloomer WooCommerce Toggle Payments By User Role

You don’t feel confident with coding? You need more control over your payment/user role exclusions? You don’t want to purchase yet another bloated, expensive plugin? Great!

Business Bloomer WooCommerce Toggle Payments By User Role 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 user role that should trigger that from the right. Add more rules if needed. Simple!

Advanced WooCommerce “Payment Gateways by User Role” 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 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 […]

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

138 thoughts on “WooCommerce: Disable Payment Gateway for Specific User Role

  1. Hello! I’m trying to enable COD for multiple users. It works great with your snippet above, targeting 1 user category (vip_customer) to enable the COD for them. But when I add a second user, it does not work for the second user (still works for the first user). Is the snippet out dated perhaps?

    !current_user_can('vip_customer') || current_user_can('exceptional_client')
    1. Nope, your PHP has a mistake 🙂

  2. This is brilliant and works like a charm thank you! I created a custom role then applied this to hide the default payment method. My challenge is to hide the custom payment method for shoppers who are not logged in.

    Would something with ‘is_user_logged_in()’ work in this case? Since users that aren’t logged in have no ‘roles’ (that I know of) how would this be approached?

    1. Hi Vince! Like this maybe?

      add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_paypal_disable_logged_out' );
       
      function bbloomer_paypal_disable_logged_out( $available_gateways ) {
         if ( isset( $available_gateways['paypal'] ) && ! is_user_logged_in() ) {
            unset( $available_gateways['paypal'] );
         } 
         return $available_gateways;
      }
      
      1. HI I am trying to do this with afterpay,
        However it doesnt appear to make a difference , AFterpay is still showing on products before. user is loggged in,
        ANy ideas appreciated.
        Cheers Dylan

        1. This only works at checkout in the default WooCommerce payments section. AfterPay and other “express checkout” plugins would require additional work.

  3. Hello,
    Is it possible to disable a payment gateway option instead of completely removing it?

    1. Hi Ritesh, what do you mean exactly?

  4. Hi Rodolfo,

    I really love your snippets! I’m a beginner with PHP but you make it so easy to use php code instead of plugins for so many functions. Many thanks. I wanted to add the code with this additional function: for orders over e.g. 200 USD. Is it possible to add this as well?

  5. Just wanted to thank you this save me a lot coding. It worked great once I figure out that the $available_gateway was “cheque” and not check.

      1. Hi Rodolfo,
        you’re doing an amazing job with woocommerce and you helped me a lot. I would like to ask if it is possible to disable a payment method based on the billing email for guests that don’t have an account in the website.

        Here is the code I have but it works for registered users and I want it for guests

        function disable_cod( $available_payment_gateways ) { 
        //Check whether the available payment gateways have the Cash on delivery option and if the user is not logged in or has the role customer 
            $user = wp_get_current_user();
             $allowed_roles = array('customer');
             if ( isset($available_payment_gateways['cod']) &&  $user->user_email == 'test@test.com' ) { 
                //Remove the cash on delivery payment gateway 
                unset($available_payment_gateways['cod']); 
            } 
            return $available_payment_gateways; 
        } 
        add_filter('woocommerce_available_payment_gateways', 'disable_cod', 90, 1);
        

        Thanks in advance

        1. Hi George, maybe you could just “unset” the gateway if user is logged out?

  6. Hi Rodolfo,

    When I use the ‘disable code’, it disable the payment method for all the users and not just the one I mentioned in the code. Example:

    add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_quickpay_disable_shop_manager' );
      
    function bbloomer_quickpay_disable_shop_manager( $available_gateways ) {
       if ( isset( $available_gateways['quickpay'] ) && current_user_can( 'manage_woocommerce' ) ) {
          unset( $available_gateways['quickpay'] );
       } 
       return $available_gateways;
    }
    

    Do you know why and what I can do?

    1. Hey Cecilie, that will disable all users who “manage_woocommerce”, e.g. admins and shop managers. You’ll need to change that capability to something else: https://docs.woocommerce.com/document/roles-capabilities/

  7. Hello Rudolfo,
    i want to enable the invoice payment for a specific user role, but I can’t find the gateway ID for “Invoice”. Can you help me with that?
    Thank you very much.
    Best regards
    Hendrik

    1. Hi Hendrik, Must be a custom gateway as that’s not default WooCommerce. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  8. Hi! I want to create a private section to sell especial products to registred users.
    I want these users to only see the option to pay “cash on delivery”
    instead I want unregistered customers to see the other payment options (Stripe and Paypal) except cash on delivery option.
    So I will need 2 codes?
    I don’t quite understand how this works… I will realy apreciate if you can help me!
    Can you tell me which codes i need to use?
    Thank you so much!!!

    1. Hi Claudia, 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. Radolfo, thank you very much for this.

    Could you help out in specific situation. I have multiple wholesale customer roles that need to have only BACS active, but shop manager is adding them with plugin, so it’s not good to need to add every new one in functions code.

    It would be easier to enable this roles (guest, shop manager, administrator and customer) to have all payment options enabled, and all other have only BACS.

    Could you help out?

    Thank in advance

    1. Pierre, 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!

  10. Great snippet. Just used it on wordpress 5.4.1 and woocommerce 4.1 to only show invoice payment gateway to wholesale customers only. Thank you Rodolfo.

    1. Nice!

  11. Hello.I am interested in disabling cash on delivery for a specific vendor’s products.Could you advise.

    1. Hi Jose, 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!

  12. Fantastic code snippet so thank you Rodolfo 😉 My question is how to apply this code to include mulitple payment methods please? Thank you.

    1. Hello Paul, 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!

  13. Hi Rodolfo
    Thank you for all your suggestions. Trying to get your code to work in functions.php and I must be missing a step as it’s not working in my Upstore Child theme. I pasted in your code:

    add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_paypal_disable_manager' );
    function bbloomer_paypal_disable_manager( $available_gateways ) {
       if ( isset( $available_gateways['paypal'] ) && current_user_can( 'manage_woocommerce' ) ) {
          unset( $available_gateways['paypal'] );
       } 
       return $available_gateways;
    }
    
    add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_paypal_enable_manager' );
    function bbloomer_paypal_enable_manager( $available_gateways ) {
       if ( isset( $available_gateways['paypal'] ) && ! current_user_can( 'manage_woocommerce' ) ) {
          unset( $available_gateways['paypal'] );
       } 
       return $available_gateways;
    }
    

    In WooCommerce – Settings – Payments, the screen hasn’t changed. I’ve emptied the cache several times in Firefox, no luck.
    I’m looking for code that will enable me to disable PayPal for wholesale customers.
    I successfully got your shipping low to high cost order php snippet to work, thank you so much.
    Thank you in advanced.

    1. This is for the checkout page only – not the admin. Sorry

  14. Hi Redolfo, the codex says;

    “Passing role names to current_user_can() is discouraged as this is not guaranteed to work correctly (see #22624).”
    https://codex.wordpress.org/Function_Reference/current_user_can#Notes

    Suggest it’s better to test a user’s capabilities instead. In this instance “manage_woocommerce” may be more appropriate as it is a core capability of a Shop Manager.

    Will

    1. Perfect – thank you!

  15. dear Rodolfo,

    i inserted the code successfully in the child theme, but…nothing has changed in my Woo plugin setting page, or anywhere else.
    i’d be happy to use your code instead of another plugin.
    you can reply in italian if you wish. thanks

    Alessandro

    1. English only – sorry 🙂 What code did you use exactly?

  16. Everytime I get your snippet to work the products just disappear from the category pages for some odd reason. Any idea why and has this happened for anyone else?

    I am using the Avada theme for my eCommerce site.

    1. Not sure. 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

  17. Is it just me or is the two snippets identical?

    So how is it possible to Enable a certain payment gateway method for a specific user role? Only Disable is available?

    1. Good point Erik, you’re almost right… The only difference between the 2 snippets is a single “!” exclamation mark, which includes/exclude the “shop_manager” role. That gives the enable/disable functionality 🙂

  18. Could this script be changed to hide the PayPal checkout on certain user groups?
    example: I have a wholesaler website and I ship freight. So, the wholesaler picks there products and picks freight for shipping method, but I want to be able to hide the PayPal checkout from the checkout page. Because I edit the order and update the shipping cost for bulk products.

    12 pots = 1210.22 I process the order with 210. shipping and send an invoice to the wholesaler and he then gets a link to process out via PayPal.

    1. Hello Scot, thanks so much for your comment! Yes, this is possible – 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

  19. Hello,

    Here are two questions:

    1# In latest of the woocommerce version, there is no Payment method displaying, please check the screenshot: https://prntscr.com/mq582i, how should I get payment ID now please?

    2# how should I change the code if I want to disable a specific method for more that one roles please? should I just add role name with comma like this way?
    if ( isset( $available_gateways[‘paypal’] ) && current_user_can(‘shop_manager’, ‘subscriber’) ) {

    or should I duplicate all of that code line please?

    Thanks

    1. Hey Alex! Try to use “inspect” in Chrome to see if you can find a CSS ID with the name of the payment method. For #2, sorry, that’s custom code and cannot help here 🙂

  20. Great blog! I’ve referenced a few of your articles. I want to implement this exact functionality but against a specific “GROUP” if using the popular Groups plugin.

    The official WooCommerce plugin can cross-reference Groups – https://docs.woocommerce.com/document/paymentshipping-roles/ so was hoping yours could be modified to do the same.

    1. Hey Blake, thanks so much for your comment! Yes, this is possible – 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

  21. Hello sir, I want to hide the payumoney button for specific users’ role, is this code need any changes? Thanks in advance!!!

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

  22. Worked for me, thanks!

    1. Great!

  23. Thanks for this example. Code worked exactly as required and tweaked to our requirements.

    1. Excellent!

  24. Hi
    Why this code is not working ?

    add_filter( ‘woocommerce_available_payment_gateways’, ‘bbloomer_paypal_enable_manager’ );

    function bbloomer_paypal_enable_manager( $available_gateways ) {
    global $woocommerce;

    if ( $_GET[‘action’] == ‘reserved’ ) {
    unset( $available_gateways[‘paypal’] );
    }
    return $available_gateways;
    }

    My checkout url is : https://xyz.co.uk/checkout/?action=reserved

    1. Hello Ahir, thanks so much for your comment! 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

  25. Works perfectly. I used the User Role Editor to create a new role for Woocommerce, duplicated the existimg role and removed the gateway. In the last version the role slug is not visible anymore, only with the ‘Manage’ button link.

    1. Awesome 🙂

    2. Thanks so much for this. However, when the payment gateway is disabled a message says: “There are no available payment methods for your state”. Is there a way to change that message?

      1. Hi Mark, 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. I have a problem using this code because it seems that the slug that you use as a parameter for the current_user_can() function doesn’t seem to work the way I thought. It only works with the slugs from this link https://codex.wordpress.org/Roles_and_Capabilities#Special_Cases under Summary of Roles. But according to a plugin I used to find the slugs for all my roles on my site I have the following:
    Role: Slug:
    Administratör adminsitrator
    Redaktör redaktor
    . .
    . .
    . .
    Test test

    The following code works as expected:

     /**
     * @snippet       Enable Payment Gateway for a Specific User Role | WooCommerce
     * @how-to        Get CustomizeWoo.com FREE
     * @sourcecode    https://businessbloomer.com/?p=273
     * @author        Rodolfo Melogli
     * @compatible    WooCommerce 2.4.10
     */
     
    function credit_payment_enable_manager( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways['cod'] ) && !current_user_can('administrator')  ) {
    unset( $available_gateways['cod'] );
    } 
    return $available_gateways;
    }
     
    add_filter( 'woocommerce_available_payment_gateways', 'credit_payment_enable_manager' ); 

    but not:

     /**
     * @snippet       Enable Payment Gateway for a Specific User Role | WooCommerce
     * @how-to        Get CustomizeWoo.com FREE
     * @sourcecode    https://businessbloomer.com/?p=273
     * @author        Rodolfo Melogli
     * @compatible    WooCommerce 2.4.10
     */
     
    function credit_payment_enable_manager( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways['cod'] ) && !current_user_can('test')  ) {
    unset( $available_gateways['cod'] );
    } 
    return $available_gateways;
    }
     
    add_filter( 'woocommerce_available_payment_gateways', 'credit_payment_enable_manager' ); 

    What am I not getting?

    1. Hey Niklas, thanks for your comment! What’s the name of the custom user role you’re targeting?

    2. It’s a role I have created myself via a plugin called Capability Manager Enhanced. I have named the user role “kreditkund”.

    3. Can’t figure how!

      Hide checkout field if certain payment gateway/method is selected.

      Thank you

  27. Hi, I’m wondering where I can find the id for the different users roles so that I can use this code but with another role than ‘shop_manager’? You provide instructions on how to find the Gateway ID for the payment methods but I can’t manage to find the different ID’s for the user roles.

    Thanks in advance

  28. Unfortunately for me this does not work and messed something up so my page went offline – managed to fix from ftp by renaming code snippets plugin folder – so deactivating all snippets.

    Fatal error: Cannot redeclare bbloomer_paypal_disable_manager() (previously declared in //wp-content/plugins/code-snippets/php/snippet-ops.php(352) : eval()’d code:9) in /wp-content/plugins/code-snippets/php/snippet-ops.php(352) : eval()’d code on line 15

    Tried to disable my main payment gateway for admin (shop_manager) role and only allow invoice payment.

    I have used the disable code snippet for disabling

    I dont understand the error code so how do I fix this so I can use my snippets plugin again? Just reinstall the snippets plugin?

    1. Hey Ken, thank you so much for your comment! That’s one of the reasons it’s much better to work on a child theme functions.php. From what I see you’ve used the same function name twice (line 9 and 15) – in PHP function names must be unique. You will need to access the database, find the content, edit it and only then reactivate the plugin. Hope this helps 🙂

  29. Hello,
    I have a Marketplace made with Woocommerce, within the Marketplace each seller and his store are identified by the user ID, I wish to disable shipping methods for some stores.
    Is there a snippet to disable shipping methods depending on the user ID?

    1. Noé, 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

  30. Worked perfectly, Thank you!

  31. Worked great for me! I disabled credit card payments for my wholesale customers and enabled check payments for them. Thank you so much for this! Now I just need to find a way to add a fee to only wholesale customers…

  32. Hi, I tried the code and it works perfectly. Nevertheless a strange thing happens: each time I disable a gateway, regardless of the gateway and regardless of the user role, the “Payment Method” menu item from the user account (my-account) page disappears. It’s like I deleted the endpoint. As soon as I enable the previously disabled gateway the “Payment Methdos” menu item comes back.

    This is rather nasty, as our subscription site relies heavily on the possibility of the subscribers to change/add/delete their registered payment method. I know you don’t offer support through this section, but maybe a hint to what might be needed to do?

    Thnx.

    1. Hey Emil, thanks so much for your comment! Sorry but I can’t help free subscribers here on the blog. If you wish to get a quote, you can use the relevant form on the Contact page. Thank you 🙂

  33. Hi there, this looks like exactly what I am after to turn on Cash On Delivery for administrators only. I pasted the code in to functions.php however it does not show – are you able to confirm if this still works?

    Thanks, Ben

    1. Ben, thanks for your comment! Positive, just re-tested on Woo 3.2.4 and it works perfectly. Make sure to use the right “capabilities” and payment gateway ID 🙂

  34. Hi Rodolfo, first at all thanks for this great snippet. Now, i try to use it for disable the “cod” payment ONLY to NOT LOG IN and NOT specific role user, like “administrator” but doesnt work…Have you idea why? Thanks

    1. This it the code i use:

      add_filter('woocommerce_available_payment_gateways','filter_gateways',1);
      
      function filter_gateways($gateways){
          global $woocommerce, $current_user;
      
          if ( is_user_logged_in() ) {        
              $userRole = implode(',',$current_user->roles);
              if($userRole ==! 'administrator'){
                  unset($gateways['cod']);        
              }   
          }else{
              unset($gateways['cod']);
          }           
       return $gateways;
      }
      
      
      1. Gaston, 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

  35. Hello, How can i disable more than just one payment option? Now i can only disable 1, if i try to disable 2 i get fatal error.

    1. Marcus, thanks so much for your comment! Feel free to copy/paste your snippet here and I’ll take a look 🙂

  36. Excellent!!!

  37. Hi, I tried turning off the usual payment type for “wholesale_customer” and enable “bacs” only for this type of customer. Added the code via the “Snippets” plugin but it has no effect. One snippet for disabling the default payment and 2nd separate snippet to enable “bacs” payment type. Also enabled “bacs” in woocommerce payment gateways. Still when logging in as a “wholesale_customer” then I get the default payment type. What have I missed?

    DISABLE code

    /**
     * @snippet       Disable Payment Gateway for a Specific User Role | WooCommerce
     * @how-to        Get CustomizeWoo.com FREE
     * @sourcecode    https://businessbloomer.com/?p=273
     * @author        Rodolfo Melogli
     * @compatible    WooCommerce 2.4.10
     */
     
    function bbloomer_makecommerce_sc_disable_manager( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways['makecommerce_sc'] ) && current_user_can('wholesale_customer') ) {
    unset( $available_gateways['makecommerce_sc'] );
    } 
    return $available_gateways;
    }
     
    add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_makecommerce_sc_disable_manager' );
    

    AND ENABLE CODE

    /**
     * @snippet       Enable Payment Gateway for a Specific User Role | WooCommerce
     * @how-to        Get CustomizeWoo.com FREE
     * @sourcecode    https://businessbloomer.com/?p=273
     * @author        Rodolfo Melogli
     * @compatible    WooCommerce 2.4.10
     */
     
    function bbloomer_bacs_enable_manager( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways['bacs'] ) && !current_user_can('wholesale_customer') ) {
    unset( $available_gateways['bacs'] );
    } 
    return $available_gateways;
    }
     
    add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_bacs_enable_manager' );
    

    Thanks so much for your help!

    1. Hey Ken, 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 Ken! Without having tested or knowing for sure, I would say that the ” &&” in your code does not belong there…

  38. Hi Rodolfo
    Thanks for this very helpful.
    Is it possible to apply this snippet only on the Woocommerce check out page?
    I am trying to disable PayPal for products checkouts but enable for adding account funds.
    Thanks

    1. Hey Zafer, thanks for your comment! Yes, of course, but it will strictly depend on the Account Funds plugin 🙂

  39. You are genius! Thank you very much for all your tips 🙂

  40. I can’t get your code to work. For a role called ‘company_clubs’ I basically don’t want those users to have to pay at all; so tried this with the ‘bacs’ and ‘cheque’ gateways. Everything looks ok; but the gateway doesn’t show up for these users.

    Any ideas?

    function bbloomer_paypal_enable_manager( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways[‘cheque’] ) && !current_user_can(‘company_clubs’) ) {
    unset( $available_gateways[‘cheque’] );
    }
    return $available_gateways;
    }

    add_filter( ‘woocommerce_available_payment_gateways’, ‘bbloomer_paypal_enable_manager’ );

    1. Hey Mike, sorry but I can’t offer custom troubleshooting here via the blog – thanks a lot for your understanding 🙂

  41. Hi Sir,

    I have disabled the payment option for the particular role ” Wholesale customer”. I need to send to the invoice to the customer ” Payment is not required now! An invoice will be sent when the order is processed. ” At the same time the order of the product will be stored in the admin products history and send to the mail to the admin. After disable the payment option it shows the message invalid payment method. What i do disable the error statement and process the invoice. Please help me.

    1. Hey Sumathi, you should enable a payment method such as “COD” and rename it to “Get a Quote”. In this way they can complete the checkout and you can send them back an invoice 🙂

  42. Hi Rodolfo and very thanks for your snippet !
    I use your snippet to disable payment gateway for user roles.
    But if a user is not already logged all the payment gateway are displaying!

    So how to disable some payment gateway for a not logged user?
    Thanks !

    1. Good question Johanna! You should add an IF statement for https://developer.wordpress.org/reference/functions/is_user_logged_in/. Let me know 🙂

    2. Thanks Rodolfo

      But i’m really not a coder… I don’t know where to add the IF
      Think i have to add this but where? :

      if ( is_user_logged_in() )

      Please see my (your) code:

      function bbloomer_x_disable_manager( $available_gateways ) {
      global $woocommerce;
      if ( isset( $available_gateways['other_payment'] ) && current_user_can('customer') ) {
      unset( $available_gateways['other_payment'] );
      } 
      return $available_gateways;
      }
      add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_x_disable_manager' );
      
      1. Hey Johanna, you should ad the IF just after the global declaration. Then, open the IF’s “{” and remember to close that before the end of the function “}”

  43. Rodolfo, you’re a genius. You’ve saved my day with the second method (enabling for some roles).

    Your web is FULL of great advices. Keep on the hard work!

    1. Brilliant, no one ever called me genius! Thanks again Litbea 🙂

  44. Hi, used the role and it worked for register user. but can I do it also for none registered one? tried it and it didn’t worked.
    What I mean that I need to disable some of the payment methods for none registered users and keep only the paypal for them.

    1. Hey Efrat, thanks for your comment! Yes, you can target non logged in customers with:

      if ( !is_user_logged_in() ) {
      // do something
      }
      

      An example is here: https://businessbloomer.com/woocommerce-hide-price-add-cart-logged-users/

      Hope this helps!

  45. i have a Purchase order payment gateway. 2 questions: how do i found out what the gateway id is, and two, what if i just want to turn that gateway on for a specific role?

    1. Hey Mike, thanks for your comment!

      1) I just added a screenshot to the blog to help you find IDs: https://businessbloomer.com/disable-payment-gateway-specific-user-role-woocommerce/#how-to-find-woocommerce-payment-gateway-id

      2) Just take a look at the second snippet, that should enable a gateway for a specific user role: https://businessbloomer.com/disable-payment-gateway-specific-user-role-woocommerce/#enable-payment-gateway-for-a-specific-user-role

      Hope this helps!

  46. Hi Rodolfo, thanks for all your tutorials, I have found answers to several of my woocommerce questions here 🙂

    I want to hide bacs when there is a virtual product in the cart. I already, in my functions.php, have this to check if there is a virtual product (it’s related to something else):

     /**
     * Check if cart has virtual product
     *
     * @return bool
     */
    function woo_cart_has_virtual_product() {
    
    	global $woocommerce;
    
    	// By default, no virtual product
    	$has_virtual_products = false;
    
    	// Default virtual products number
    	$virtual_products = 0;
    
    	// Get all products in cart
    	$products = $woocommerce->cart->get_cart();
    
    	// Loop through cart products
    	foreach( $products as $product ) {
    
    		// Get product ID and '_virtual' post meta
    		$product_id = $product['product_id'];
    		$is_virtual = get_post_meta( $product_id, '_virtual', true );
    
    		// Update $has_virtual_product if product is virtual
    		if( $is_virtual == 'yes' )
    			$virtual_products += 1;
    	}
    
    	if( count($products) == $virtual_products )
    		$has_virtual_products = true;
    
    	return $has_virtual_products;
    }
     

    Then I figured ( I really don’t know php) I could just do this, using your function:

     function bbloomer_paypal_enable_manager( $available_gateways ) {
    global $woocommerce;
     if( woo_cart_has_virtual_product() == true ) {
    unset( $available_gateways['bacs'] );
    } 
    return $available_gateways;
    }
     

    Would you be willing to help me with this?

    1. Hey Kristin, thanks so much for your comment! Unfortunately, I’m not able to give free advice for custom snippets (in case, feel free to contact me in pvt). Other than that, it seems to me your snippet should work – have you tried it yet?

  47. How to hide the payment gateway “bacs” on my account page ? ( do not disable it in the settings) Thank you!

    1. Hey Wilsa, thank you for your comment! I’m afraid I’m not sure I fully understand this – could you provide a screenshot maybe?

  48. Hi Rodolfo!
    I just found your website and it’s great: live all the info you have here. I’m learning a lot!

    One of the reasons I’m learning so much is because I know so little ehehe. Can I ask you something? Is there a way to allow one particular payment method (COD) to only one user role?

    Thanks!

    1. Thanks for your comment! 🙂 Of course, you can slightly modify the function and achieve what you’re looking for. I added an extra snippet on this blog page. You could simply say “!current_user_can()” and basically unset the gateway for ALL users but the one you want. Hope this helps!

  49. Dear Rodolfo, thank you very much for this extremely useful piece of code. Now let’s say that not only do I want to disable Paypal gateway for the shop manager but I also want to enable a specific gateway for him and him only. How would I do that?

    Thanks for your help

    1. Cheers Axel 🙂 Your request is very simple to fix. First, you add a payment gateway via WooCommerce settings. Second, you use an additional IF statement in the PHP that excludes the gateway to all non-shop managers:

      
      function bbloomer_paypal_disable_manager( $available_gateways ) {
      global $woocommerce;
      if ( isset( $available_gateways['paypal'] ) && current_user_can('shop_manager') ) {
      unset( $available_gateways['paypal'] );
      } 
      
      // NEW CODE. Please note the "!" in front of current_user_can to exclude non managers
      if ( isset( $available_gateways['your_shopmanager_gateway'] ) && !current_user_can('shop_manager') ) {
      unset( $available_gateways['your_shopmanager_gateway'] );
      }
       
      return $available_gateways;
      }
      
      add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_paypal_disable_manager' );
      
      
      1. Thank you Rodolfo for your help. I tried your code and it worked. However I realized I was not being very logical with my request 😉 You see I still need that shop manager payment gateway used in some cases by non-shop managers. As you mentioned this codes excludes the payment gateway to all non-shop managers altogether.

        This is a total newbie question: you use this php “unset” in your code… is there such a thing as “set”?

        Sorry for my poor English and merry Christmas!

        1. No problem 🙂 “Set” is way too complicated – so maybe you could explain the “used in some cases” a little bit better. Based on that, unset might still be the best and cost-effective option!

          1. Dear Rodolfo,

            Happy new year! Actually I realized I was not being logical and that your piece of code above is just what I need. Thank you again for your precious help. Your blog is a treasure trove for anyone using woocommerce!

            1. Awesome!!! And Happy New Year to you too 🙂

  50. Hi Rodolfo. This code snippet was exactly what I was looking for! I tried to change it according to my situation. My gateway ID is jetpack_custom_gateway where people have the option to pay 14 days later, but will get the goods shipped already. I want this only to apply to wholesalers so that, when standard users (‘customer’ in my case) do not see this payment option.

    However I’ve modified it to the below without succes. Do you know what I have done wrong? And how can I add a variable that when user is not logged in, it will also hide the ‘pay later’ option.

    function pay_later_manager( $available_gateways ) {
    global $woocommerce;
    if ( isset( $available_gateways[‘jetpack_custom_gateway’] ) && current_user_can(‘customer’) ) {
    unset( $available_gateways[‘jetpack_custom_gateway’] );
    }
    return $available_gateways;
    }
    add_filter( ‘woocommerce_available_payment_gateways’, ‘pay_later_manager’ );

    1. Hello Glenn, thanks for your message 🙂 The problem is that you’re trying to hide a payment gateway only to thew people who are logged in to your website and belong to the customer user_role.

      Basically, you want to hide your gateway UNLESS users are logged in as wholesalers. Here’s what you should do instead:

      function pay_later_manager( $available_gateways ) {
      global $woocommerce;
      if ( isset( $available_gateways['jetpack_custom_gateway'] ) && !current_user_can('wholesalers') ) {
      unset( $available_gateways['jetpack_custom_gateway'] );
      }
      return $available_gateways;
      }
      add_filter( 'woocommerce_available_payment_gateways', 'pay_later_manager' );
      

      Let me know 🙂

  51. Hi Rodolfo, I’d like to setup ONLY Paypal payment method for Singapore for local delivery. For international users, they should be only able to see “International Order” (I am using COD payment gateway for this) as I want them to place an order and I will calculate and add the shipping cost and send them customer invoice via Woocommerce.

    I used your code snippet above and modified to below:

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

    It works perfect in the frontend in terms of SG customer only can select Paypal and non-SG customer can only select “International Order” (i.e. COD) to place order.

    However, for non-SG customer order, after I set pending payment, add the shipping charge and send customer invoice, customer who received the invoice cannot pay via Paypal as it shows the error:

    “Sorry, it seems that there are no available payment methods for your location. Please contact us if you require assistance or wish to make alternate arrangements.” I believe this is due to the above code unset the paypal for SG.

    May I know how to enable Paypal back for the International order on sending the customer invoice?

    Appreciate your advice! Thanks!

    1. Lee, yes of course 🙂 the snippet disables PayPal so that’s why it’s not working. This is why you need to define a customer user_role e.g. “invoice_sent”, and then:

      function bbloomer_disable_payment_userrole ( $available_gateways ) {
      global $woocommerce;
      if ( isset( $available_gateways['paypal'] ) && $woocommerce->customer->get_country() <> 'SG' && !current_user_can('invoice_sent') ) {
      unset( $available_gateways['paypal'] );
      } else if ( isset( $available_gateways['cod'] ) && $woocommerce->customer->get_country() == 'SG' ) {
      unset( $available_gateways['cod'] );
      }
      return $available_gateways;
      }
      add_filter( 'woocommerce_available_payment_gateways', 'bbloomer_disable_payment_userrole ' );
      
  52. Hi there,
    i have a question about the payment gateway, i change the COD gateway to purchase order gateway so customer can submit the PO before they pay, but my problem is how do i disable this “COD” gateway when i email customer new invoice after i make some change to the PO order ?? please help ?

    1. Hey Albert, thanks for your question 🙂 Not really sure what you mean here. From what I understand, you have a new gateway called “PO” and are trying to disable COD?

      1. HI,
        im sorry not to explain you better, what i mean is i change the COD gateway to PO.. (basically COD=PO). so when customer place an dropship order they can used this payment method to submit a PO then we can quote them the shipping cost for it and resend them the invoice so they can pay for it, but when i resend them the invoice the PO gateway option still there i want it to disable them.. i only want customer see the paypal and CC option only..
        is there a way to do it ?? (am i explain it better now sorry)

        Thanks

        1. Yes, it’s clear now 🙂 The customer you send the invoice back – do they need to login in order to pay via PayPal/CC?

          1. Yes. and i have two user role on my website which is customer and dropshipper (if thats help too) i want this feature only for dropshipper.

            Thank you

            1. Ok. Are you saying after they send you the PO request, you change the user role from “customer” to “dropshipper” manually? And after that you want to show only PPal/CC? If it is this simple, then all you have to do is using the snippet with user role = dropshipper. When you send back the invoice make sure to change their user role manually.

              Problem is – if the same dropshipper goes to checkout again in the future (order #2) – do they need to see PO again?

          2. Sorry, you know what i think they dont need to login if thats make easier for you. they just need to pay the invoice. 🙂

            Thanks

          3. No, i already assign them when they register to the website for user role. so only dropshipper user role can submit a PO .. after that i make a change on their order such as price and shipping cost, then i email them back the updated invoice so they can pay with paypal/CC…
            but my problem now when i email them the updated invoice they still can see the submit PO payment, so some of them is confused by it?? i want to disable this payment so they can just pay for it with paypal/CC only.
            (hope this explain better)

            1. Gotcha 🙂 Maybe you could create another role e.g. “dropshipper-invoiced”. In that way you can change the user role when you send them the invoice, and disable PO for that new role. This is the only free solution there is. Of course it can be made via code, but unfortunately this is custom work and I cannot provide this solution on the blog right now. If you would like to get a quote, feel free to go here. Thank you! R

  53. How I can hide a payment-gateway plugin for specific customer on WooCommerce , for example in the checkout if the customer’s first name is : Peter , the plugin will not show for him.
    Please answer it’s urgent .

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

  54. Just noticed that it might have worked for customer but what if the customer is not logged in?

    1. Hey Jon, thanks for your 2 comments! Are you asking to disable the rule if the customer is not logged in? You could use something like “if ( is_user_logged_in() && current_user_can( ‘administrator’ ) ) {“… Does this help?

  55. I tried using this code and it doesn’t seem to be working. I changed the user to customer instead of shop manager.

    function paypal_disable_manager( $available_gateways ) {

    global $woocommerce;

    if ( isset( $available_gateways[‘paypal’] ) && current_user_can(‘shop_manager’) ) {

    unset( $available_gateways[‘paypal’] );

    }

    return $available_gateways;

    }

    add_filter( ‘woocommerce_available_payment_gateways’, ‘paypal_disable_manager’ );

    ?>

  56. Hi, is it possible to add more than 1 role to each payment method? I tried adding the code more than once but it brought up a fatal error, also what would be the code for cheque payments? just change paypal to cheque? Thanks

    1. Paul, thanks for your comment! Of course you can disable for multiple roles, just use “current_user_can(‘shop_manager’) || current_user_can(‘other_role’)”. To find the code for cheque, just go to Woocommerce / Settings / Checkout and you’ll see the codes under “Gateway ID”

      1. Hi Rodolfo, thanks for this great info, worked fine for me.
        I didn’t manage to get it working for several user roles, what would the code be exactly when using it to enable payment for the administrator and shopmanager ?
        I tried this :

        if ( isset( $available_gateways['bacs'] ) &amp;&amp; !current_user_can('administrator') or current_user_can('shop_manager') ) {
        unset( $available_gateways['bacs'] );
        } 
        return $available_gateways;
        }
        

        Thanks, Bjorn

        1. Hey Bjorn thanks for your comment! I cannot provide custom support here via the blog I’m afraid. However, I can give you a little hint – in the if statement you’re basically not using precedence: https://php.net/manual/en/language.operators.precedence.php 🙂

          1. I want to deactivate the cash on delivery (COD) if the amount of the basket is greater than 2000 $

            1. Royce, 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!

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 *