How to add a user role right after an order is placed in WooCommerce?

Viewed 189

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' );
                }
        }
    
    }
  
1 Answers

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

Related