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.

49 replies
  1. ams
    ams says:

    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?

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      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.

      Reply
  2. diego sanchez
    diego sanchez says:

    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

    Reply
      • Emmanuel - EFFEX network S.r.l.
        Emmanuel - EFFEX network S.r.l. says:

        Ciao Nicola, sto cercando di usare il tuo codice inserendolo nel file functions.php del tema in uso ma continuo a ricevere errore 500 internal server quando lo metto in produzione.

        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( '9466', '9467', '9468', '9469', '9470' );

        foreach ( $items as $item ) {
        if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
        $role = 'new-role';
        switch ( $item['product_id' ] ) {
        case 9466: $role = 'golfista-trial'; break;
        case 9467: $role = 'golfista-premium-1; break;
        case 9468: $role = 'golfista-premium-2; break;
        case 9469: $role = 'golfista-premium-3; break;
        case 9470: $role = 'golfista-premium-4; break;
        }

        $user = new WP_User( $order->user_id );

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

        // Exit the loop
        break;
        }
        }

        }

        Vedi qualcosa di sbagliato qua?

        Reply
  3. Jessica
    Jessica says:

    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;
        }
    }
    
    }
    
    Reply
  4. Valerie Robinson
    Valerie Robinson says:

    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?

    Reply
  5. Graham
    Graham says:

    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;
    }
    }
    }

    Reply
  6. Alexandr
    Alexandr says:

    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.

    Reply
  7. Alexandr
    Alexandr says:

    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?

    Reply
  8. Alexandr
    Alexandr says:

    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?

    Reply
  9. Alexandr
    Alexandr says:

    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!

    Reply
  10. david
    david says:

    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.

    Reply
  11. Jasha
    Jasha says:

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

    Reply
    • Nicola Mustone
      Nicola Mustone says:

      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.

      Reply
      • Marco
        Marco says:

        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

        Reply
  12. Mark
    Mark says:

    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;
    }
    }

    }

    Reply
  13. Trisha
    Trisha says:

    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;
    }
    }

    }

    Reply
  14. angela
    angela says:

    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!

    Reply
  15. Zambu
    Zambu says:

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

    Reply
  16. BEN
    BEN says:

    Hello, thanks for this code! How would I alter it to include any purchase? Basically I’m selling wholesale and want to lower minimum purchases after the first initial order from $300 (newcustomer) to $100 (repeat customer). Once they complete the 1st time purchase set to minimum $300 for user role newcustomer, it will change them to ‘repeat customer’ who has a minimum order level set at $100.

    Reply
  17. AMIT
    AMIT says:

    So if I understand that this hook will be executed only when the Order transitions to “Completed”?
    Second question, should there be quotes around the product id numbers? Does it make a difference?

    Reply

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

You have to agree to the comment policy.

This site uses Akismet to reduce spam. Learn how your comment data is processed.