1

I am using the code below. I want to add an extra user role instead of the default 'customer' role right after an order is placed by a customer.

Unfortunately, the user role is not added by this code after an order is placed. Where did I miss?

add_action( 'woocommerce_order_status_completed', 'change_role_on_purchase' );
    
    function change_role_on_purchase( $order_id ) {
    
        $order = new WC_Order( $order_id );
        $items = $order->get_items();
    
        $product_id = 73; // that's my product ID
    
        foreach ( $items as $item ) {
    
                if( $product_id == $item['product_id'] && $order->user_id ) {
                    $user = new WP_User( $order->user_id );
    
                    // Remove role
                    $user->remove_role( 'customer' ); 
    
                    // Add role
                    $user->add_role( 'premium' );
                }
        }
    
    }
  
7uc1f3r
  • 28,449
  • 17
  • 32
  • 50

1 Answers1

2

With your current code, or rather using the woocommerce_order_status_completed hook the user role will only be modified when an order contains the status 'complete'. However, this is rarely the case immediately right after an order is placed by a customer, the order status will be much more likely to be 'pending' or 'on-hold'

If you want to add a user role for existing users, immediately after an order is placed, you can do this via the woocommerce_thankyou hook

So you get:

function action_woocommerce_thankyou( $order_id ) {     
    // Get $order object
    $order = wc_get_order( $order_id );
    
    // Is a WC_Order
    if ( is_a( $order, 'WC_Order' ) ) {
        // Get user
        $user = $order->get_user();

        if ( is_a( $user, 'WP_User' ) ) {
            // Add role
            $user->add_role( 'premium' );
        }
    }
}
add_action( 'woocommerce_thankyou', 'action_woocommerce_thankyou', 10, 1 );

OR

function action_woocommerce_thankyou( $order_id ) {     
    // Get $order object
    $order = wc_get_order( $order_id );
    
    // Is a WC_Order
    if ( is_a( $order, 'WC_Order' ) ) {
        // Get the WP_User Object
        $user = $order->get_user();
        
        // Check for "customer" user roles only
        if ( is_a( $user, 'WP_User' ) && in_array( 'customer', (array) $user->roles ) ) {   
            // Remove WooCommerce "customer" role (Optional)
            $user->remove_role( 'customer' ); 
        
            // Add role
            $user->add_role( 'premium' );
        }
    }
}
add_action( 'woocommerce_thankyou', 'action_woocommerce_thankyou', 10, 1 );

Where you don't apply the code for every user, but only for a user with a certain user role

7uc1f3r
  • 28,449
  • 17
  • 32
  • 50
  • Thank you for your quick response. Unfortunately, the user role was not added. I tested your both snipped. ** I added code on functions.php and the theme is storefront. – B.M. Rafiul Alam Sep 22 '21 at 10:57
  • @B.M.RafiulAlam Code has been tested in WordPress 5.8.1 and WooCommerce 5.7.0. If this doesn't work for you, it has nothing to do with the theme you are using. Test this thoroughly and possibly even [debug](https://stackoverflow.com/questions/61740111/how-to-debug-in-woocommerce-3) versus claiming that it doesn't work without more information – 7uc1f3r Sep 22 '21 at 11:04