Posted on

Changing user role after purchasing

Some months ago I talked about how to add a checkout field only for a specific user role with WooCommerce.

Today I’ll show you how to change the user role after purchasing a specific product.

Open your functions.php file in wp-content/themes/your-child-theme-name/ and add this code at the end of the file:

Note the code on line 6. It is a list of products to check, which means that the custom script will check if one of the products purchased by the customer is in that list. If yes, the user role will change to what you define on line 14.

Line 13 removes the customer’s old role, by default it’s Customer when they buy from you, but it could be different. If you want to remove more than one role, just duplicate the line and change the role slug.

Note: If you defined multiple role switch and the customer purchased more products that will change their role, only the first one found will switch their role.

The original code is by troydean.

39 thoughts on “Changing user role after purchasing

  1. Hi,

    Thank you for the post. I tried your code but when the user do checkout, I get a internal server error and a user with the default role “customer” is created. Any ideia what could be causing this problem?

    1. Hi ams,
      No sorry, the Internal Server Error is a generic error. If you check your error log you should have a specific error though which could help in understanding what’s going on.

      Otherwise, you can temporarily enable WP_DEBUG and get the error on the screen directly.

      Please check this document on Debugging in WordPress.

  2. I really like this code, but can you help me?¡, i have 6 products and each product must create a different role , what can i do?

    Thank you

    1. Hi Diego,
      Inside the if on line 9 you should add a switch on the product ID and change the role there.

      Something like this: https://gist.github.com/SiR-DanieL/20372ea13fe4bfa784c2

  3. Nice, but what if i wanted to remove that role after product expiration (like a subscription product) ??

    1. Hi Hugo,
      You don’t need a snippet for that. You can choose the roles used when the customer’s subscription is active/inactive in WooCommerce > Settings > Subscriptions:

      See this screenshot: http://cld.wthms.co/RZ66/48AH6qYp+

  4. Hi, I was excited to find your script but not working – am I missing something? see below

    add_action( 'woocommerce_order_status_completed', 'change_role_on_purchase' );
    function change_role_on_purchase( $order_id ) {
        $order = wc_get_order( $order_id );
        $items = $order->get_items();
    
        $products_to_check = array( '3379', '3376' );
    
    foreach ( $items as $item ) {
        if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
            $user = new WP_User( $order->user_id );
    
            // Change role
            $user->remove_role( 'customer' );
            $user->add_role( 'subscriber' );
    
            // Exit the loop
            break;
        }
    }
    
    }
    
    1. Hi Jessica,
      Can you try by using numeric IDs instead of strings?

      Remove the quotes here: array( '3379', '3376' )

  5. Hi-this added the new user role I specified but it did not remove the customer role. Instead it has both roles listed. I see that the code says to remove the customer role. Since they’re both there now, does that mean something didn’t work right with that line?

  6. I wish this worked – am I missing something? (I tried with and without quotation marks):

    add_action( ‘woocommerce_order_status_completed’, ‘change_role_on_purchase’ );
    function change_role_on_purchase( $order_id ) {
    $order = wc_get_order( $order_id );
    $items = $order->get_items();
    $products_to_check = array( ‘944 ‘);
    foreach ( $items as $item ) {
    if ( $order->user_id > 0 && in_array( $item[‘product_id’], $products_to_check ) ) {
    $user = new WP_User( $order->user_id );
    // Change role
    $user->remove_role( ‘subscriber’ );
    $user->add_role( ‘customer’ );
    // Exit the loop
    break;
    }
    }
    }

    1. It worked, I am dim.

  7. Hello ! Thank you for your helpfull code!
    Do you know what kind of hook i can use for yith woocommerce subscriptions plugins ?

    Thank you !
    Marco.

    1. Hi Marco,
      No, I’d suggest to ask them directly.

  8. Hello, Nikola!

    Very good code! And you can make it as a wordpress plugin? It would be very convenient to use, especially to users who do not know programming.

    1. Hello,
      Sorry but I don’t think that I’m gonna make a plugin for this. Feel free to do one with my code though if you want!

  9. I noticed a bug: when a first time successful payment happens, the goods do not disappear from the shopping cart. And if you make the payment again (the same product), being already in the new user role, then the product disappears from the shopping cart.

    What could it be? This is due to the change in roles when purchasing goods?

    1. Hey,
      I’m not sure if this is due to the role change. Can you try without my custom code?

      Does it happen anyway?

  10. Nicola!

    I deleted your code from the file and re-made the payment through Woocommerce. The product no longer appeared, everything went well.

    Then I added your code again and made a payment from the cart. But I have two-factor authentication from the DUO two-factor (https://duo.com) for the role that the old user role changes when making a payment.

    And when the payment system confirms a successful payment, your code assigns a new role (for me it is a “student”), and immediately for this role the DUO requires authentication. When successful authentication passes, I go to the shopping cart, and there again there is a product on which a successful payment has just been made.

    Maybe this is the problem?

  11. I just checked. I deleted the DUO from my user, and everything went as it should. After purchasing the product, the old user role was replaced by a new role. And the product disappeared from the shopping cart.

    I’m at a loss … I just need that for a new user role there was a possibility of two-factor authentication after the purchase of the product.

    I do not know what the problem is, I’m not a programmer …

    But your code works fine, it’s confirmed!

  12. This added a capability rather than a role. Any idea why?

  13. I removed my capital F in Free and it worked on test 2. Cool and thanks!

  14. Is there a way to get this to work with a variable product?

    For instance, if I have a product called SUBSCRIPTION with variations: FREE and PAID. I’d like to set people with a PAID subscription to the role Subscriber, and people with the FREE subscription to a role called Free Subscriber.

    It seems if I create these as two separate products, it sort of works, but if I make them variations (which I’d prefer to facilitate upgrading and downgrading), it won’t work.

    Thanks.

    1. Hi David,
      You should add more code to check if the purchased product has specific meta fields.

      You can use wc_get_order_item_meta() to do that.

    2. Did you ever get this to work David or Nicola? I too would love this functionality. Thanks in advance.

      1. Hi Eric,
        I never actually wrote the code to make it work with variations, but as I said before you can use wc_get-order_item_meta() to make it work by checking the item meta data.

  15. Nice snippet! Are there any thoughts on changing the role based on the purchase certain product categories rather than individual id’s?

    1. Hey Jasha,
      You have the product ID, from there you can get their categories with $terms = get_the_terms( $item['product_id'], 'product_cat' ); and then loop through them to get their IDs. Later, instead of checking against an array of product IDs you can check with the category IDs.

      1. Hi Nicola,
        thank you for the great snippet!
        Can you tell me please how i can make it work with a category? I tried now several days, but im not able to make it work. Per product works fine, but i need it for a category.

        Thank you very much,

        Marco

  16. For some reason, this isn’t working for me. This is my code. I am testing it on a free product. Does that make a difference?

    add_action( ‘woocommerce_order_status_completed’, ‘change_role_on_purchase’ );
    function change_role_on_purchase( $order_id ) {
    $order = wc_get_order( $order_id );
    $items = $order->get_items();

    $products_to_check = array( '210', '11858', '11674' );

    foreach ( $items as $item ) {
    if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
    $user = new WP_User( $order->user_id );

    // Change role
    $user->remove_role( 'employer' );
    $user->add_role( 'vendor' );

    // Exit the loop
    break;
    }
    }

    }

    1. No Mark,
      it should not make any difference. Make sure that the IDs are correct, and try with a different theme/without other plugins.

  17. thanks dude .
    it’s worked .
    good Job

    1. You’re welcome Farhad!

  18. I tried using your code and it just doesn’t do anything. I have customers that purchase a subscription product which automatically changes their role from customer to a subscriber, but I want the role to change to a newly created one (member) when they purchase one specific subscription and the other two subscription products will keep their subscriber role. Do I have to do some extra step since it is already changing the role when they purchase the product? I feel like there is something I’m missing to bring the pieces together.

    The product ID is 18973.

    add_action( ‘woocommerce_order_status_completed’, ‘change_role_on_purchase’ );
    function change_role_on_purchase( $order_id ) {
    $order = wc_get_order( $order_id );
    $items = $order->get_items();

    $products_to_check = array( '18973' );

    foreach ( $items as $item ) {
    if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
    $user = new WP_User( $order->user_id );

    // Change role
    $user->remove_role( 'customer' );
    $user->add_role( 'member' );

    // Exit the loop
    break;
    }
    }

    }

  19. I am so happy I found this, you have greatly helped me solve this issue. This works perfectly!
    Kudos ++++++++

    1. You’re welcome, Angela! And thanks for sharing the info below!

  20. I also just want to add, in my case:

    Until the payment is processed and completed the user did not update. Once the payment is received or the process is manually completed, then the role changes. In my case I have Paypal set to auto complete the order upon the user purchasing, so the role automatically updates. But I also have another payment gateway using E-Transfer. This type of payment has to be approved by the admin once the payment is received, so for this reason I didnt see the role update right away, it was until I completed the action that the above script completed the role change! It does work perfectly but you may need to consider how your payments are processed! hope that might help someone!

    thanks again!

    1. This worked for me as a work around

      add_action( ‘woocommerce_thankyou’, ‘change_role_on_purchase’ );

  21. FYI, There is a relatively new plug-in that accomplishes automatic role changing after purchase. It’s called YITH Automatic Role Changer.

Leave a Reply
You have to agree to the comment policy.