WooCommerce: Hide a Shipping Method Based On User Role

Sometimes, it’s necessary to hide a shipping method in WooCommerce.

A client of mine offers local pickup only to a select group of customers. His business doesn’t have a showroom. The majority of his sales are on-line; however, he does sell to a few local businesses who prefer to pick up their orders in person. He’d been using a free-shipping coupon for those customers who picked up their orders at his shop, which works, but is more trouble for the customer than a custom user-role capability.

The example below shows how to hide the shipping method “Local Pickup” from all but users granted a specific user role capability using Vladimir Garagulya’s plugin User Role Editor to set and manage the custom user role capability.

I’m a major proponent of limiting the number of plugins on a site. WooCommerce probably has an extension to do exactly what I’m describing in this post, but if I can accomplish what I need to do with a code snippet in my functions.php rather than installing another plugin, that’s the route I’ll take. The site involved already uses Vladimir’s User Role Editor for tax-exempt customers in WooCommerce, so the approach below was the most efficient in this case.

Add the Local Pickup User Role Capability

After you’ve installed the User Role Editor plugin, go Users -> User Role Editor, and Select “Customer” from the drop-down.

Click “Add Capability” and add a capability called “local_pickup_allowed” to the Customer user role.

Add the Shipping Method to WooCommerce

If you haven’t already added the “Local Pickup” method to the appropriate shipping zone in WooCommerce, go WooCommerce -> Settings -> Shipping, and in Shipping Zones, click the edit link for the shipping zone where you want to allow local pickup.

In the Shipping Methods section, click “Add Shipping Method,” and choose “local pickup,” then save your changes.

Add the Code

Add the following code to your child theme’s functions.php:

/* ** Handle Local Pickup by User Role ** */
add_filter('woocommerce_package_rates', 'hide_local_pickup_based_on_user_role', 30, 2);
function hide_local_pickup_based_on_user_role($rates, $package) {
  foreach($rates as $rate_key => $rate){
    if($rate->method_id === 'local_pickup'){
      if(!current_user_can('local_pickup_allowed') || !is_user_logged_in()){
        unset($rates[$rate_key]);
        break;
      }
    }
  }
  return $rates;
}
/* ** End Local Pickup ** */

Add the Capability For the User

Next, you need to add the local pickup user role capability for the customer(s) who are allowed to see it.

Go Users -> All Users, then click the “Capabilities” link for the user who will be allowed to see local pickup as a shipping option. In the list of capabilities, scroll down to “local_pickup_allowed” and check it. Click the “Update” button to save your changes, and “yes” to confirm the operation.

Note: If a user is already logged in to your site, they’ll have to log out and back in before they have the new capability, as the capabilities are set and saved at login.

Other Shipping Methods

You could use the steps above for hiding other shipping methods by substituting the correct method_id for the shipping method in the code, and altering the user role capability in the code and the User Role Editor.