Setting Up Role-Based Shipping Methods in WooCommerce

In this guide, I will show you how you can enable or disable specific shipping methods depending on a user role in your WordPress site (I mean, WooCommerce store).

But don’t all the customers in WooCommerce have a dedicated role – “Customer”? Well, while it is true, it is not a requirement; customers still can have other WordPress roles, even multiple roles, along with the “Customer” role.

A simple example: let’s say you have a custom role in your store, “Premium customer” or something like that, and your goal is to grant free shipping to all your premium customers.

We will take a look at two approaches – using a plugin and a programmatic approach.

Sounds good? Now, let’s dive into it.

Configuring Role-Based Shipping Using a Plugin

We will use Simple Conditional Shipping and Payments in this part of the tutorial.

I’d recommend considering the plugin approach:

  • It is super-simple and feels like the default WooCommerce functionality,
  • You can do much more than role-based shipping; for example, you can do it for payment methods as well, or configure product-based shipping, and much more.
  • At the moment, when you have a lot of code snippets in your WordPress website, it could become messy and cause issues, but the plugin is tested and supported.

Now, straight to the configuration.

In WooCommerce settings, open the “Conditions” tab, then the “Shipping conditions” section. Then, you can add as many conditions as you want with the “Add shipping condition” button.

For example, to achieve what I mentioned before (free shipping for the “Premium customers” role), we need the following configuration:

WooCommerce role-based shipping methods configuration
All free shipping methods will not be available if a customer don’t a “Premium customer” role, unless there are some other conditions added.

As simple as that πŸ™‚

What is also important to remember here is that WooCommerce allows you to set up free shipping methods individually for each shipping zone. The plugin has it covered as well.

Free shipping methods by a shipping zone in WooCommerce
When selecting free shipping methods to enable, you can do it only for specific shipping zones.

Setting Up Role-Based Shipping Programmatically

The programmatic approach is also possible, if you know what you’re doing, of course. Let me guide you through it step by step.

Creating a “Premium customer” user role

Probably, the whole role-management process is already configured in your WooCommerce store, and you do not need these clarifications; however, you can create a custom role in WordPress/WooCommerce easily with the piece of code below:

add_role( 
	'premium_customer', 
	'Premium customer', 
	array(
		'read',
	)
);

The only thing you need to keep in mind is that you do not need to put this code into the functions.php file by all means; you just need to run it once.

Assigning our custom user role to a customer

This part actually gives us a lot of room for different scenarios.

For example:

In other words, this part of the process is fully up to you πŸ™ƒ

Enable shipping methods based on a role

Technically, we need to do the opposite. I mean, let’s say the free shipping methods are enabled by default for everyone, and what we need to do in the code is leave it that way only if a customer is logged in and has a specific role.

The hook we will be using isΒ woocommerce_package_rates (it will work great for both the block and classic WooCommerce checkout).

add_filter( 'woocommerce_package_rates', 'rudr_role_based_shipping', 25, 2 );
     
function rudr_role_based_shipping( $rates, $package ) {
	
	// we do nothing if user role is "Premium customer"
	// free shipping methods remain active
	if( wc_current_user_has_role( 'premium_customer' ) ) {
		return $rates;
	}
	
	foreach( $rates as $rate_id => $rate ) {
		if( str_starts_with( $rate_id, 'free_shipping' ) ) {
			unset( $rates[ $rate_id ] );
		}
	}

   return $rates;    
}

If you don’t know where to use this code snippet, you can feel free to check this guide.

The condition str_starts_with( $rate_id, 'free_shipping' ) covers all free shipping methods from all shipping zones at the same time.

However, it is also possible to check some specific shipping methods by their IDs, for example, this way:

if( 'free_shipping:5' === $rate_id ) {

If you have any more questions, feel free to ask in the comments below.

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 15 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on X