Automatically Add a Role When a Customer Buys a Specific Product
In this step-by-step guide, I will show how to automatically add a WordPress user role when a customer purchases a specific product.
Below, you will find two approaches:
- Using a plugin from WordPress.org.
- Using a code snippet.
Both ways are pretty good; you can choose whatever suits you best. If you’re not comfortable with the code, you can use the plugin and vice versa.
Now, let’s jump into it.
Use a Plugin to Add a Role to a Customer When a Specific Product is Purchased.
First things first, here is the link to the plugin. You can also install and activate it directly from your WordPress admin dashboard.
Then, visit the WooCommerce > Settings > Products > Assign roles on product purchase page, where you can set your custom conditions.
Here is an example in the screenshot below:

Programmatically
The programmatic process of assigning a user role after a product purchase in WooCommerce consists of two steps:
- We have to decide on a WooCommerce hook we’re going to use, because there are plenty of them, and each one can be triggered under different conditions
- Then we check the order items whether there is a specific product (or products) in the order and do the thing.
Let me treat you with a ready-to-use code snippet, and then I will explain everything to you.
add_action( 'woocommerce_payment_complete', 'rudr_set_role_on_specific_product_purchase' );
function rudr_set_role_on_specific_product_purchase( $order_id ) {
// get an order object
$order = wc_get_order( $order_id );
// if this purchase has been made without creating an account, do nothing
if( ! $order->user_id ) {
return;
}
$items = $order->get_items();
// one or multiple product IDs to check
$product_ids = array( 5, 10, 32 );
foreach( $items as $item ) {
if( in_array( $item[ 'product_id' ], $product_ids ) ) {
$user = new WP_User( $order->user_id );
// do we need to remove a previous user role? (optional)
$user->remove_role( 'customer' );
// add role
$user->add_role( 'editor' );
break; // exit the loop
}
}
}In case you still don’t know where to insert the code, please read this.
Now let’s deconstruct this code a little bit:
- I decided to use
woocommerce_payment_completehook to make sure that the payment has actually been made; in some tutorials, they use thewoocommerce_order_status_{$status}hook, not sure whether it is the correct way, but you can read more about it here. - I am also using
$order->get_items()method to get all the products in the order, more about it in a separate tutorial. - On lines
8-10, we need to check whether this purchase is made by an actual user or by someone without creating an account. If you don’t want anyone without an account to make purchases on your website, you can turn it off in WooCommerce settings, specifically, in the “Accounts & Privacy” tab.
- On line
15specify one or multiple product IDs which should be in the order in order to make the role change. - If you would like to remove a previous customer role, specify it on the line
23, the new role (or multiple roles) – on line25. If you don’t know what the previous customer role was, you can modify the code a little bit:
foreach( $user->roles as $prev_role ) {
$user->remove_role( $prev_role );
}That’s pretty much it. If you have any questions or maybe suggestions on how I could improve the plugin, feel free to ask in the comments below.
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
Hi Misha,
Is it possible to automatically change the customer role when an order is received rather than payment completed, to allow for order that don’t require immediate payment (on-hold) to still run the change of role?
Also, can it activated when the customer orders any product from an array of product categories, rather than specific product ids?
I’ve tried altering your code for my requirements, but can’t get it to work.
Any suggestions would be very much appreciated!
Thank you!
Hi Jon-Paul,
I think you can use the
woocommerce_pre_payment_completehook then.