Updated to handle switched subscriptions too (upgrade or downgrade a subscription)
You can try to use use woocommerce_subscription_status_updated
related hook.In the code below, you will set for each variation ID, the related user role in the settings array (commented code):
// Custom function for your settings - Variation id per user role
function variation_id_per_user_role_settings(){
// Settings: set the variation ID as key with the related user role as value
return array(
'417' => 'subscriber-a',
'418' => 'subscriber-b',
'419' => 'subscriber-c',
);
}
// Custom function that check item and change user role based on variation ID
function check_order_item_and_change_user_role( $item, $user, $settings ){
$product = $item->get_product(); // The product object
// Only for variation subscriptions
if( $product->is_type('subscription_variation') ) {
$variation_id = $item->get_variation_id(); // the variation ID
$user_role = $settings[$variation_id]; // The right user role for the current variation ID
// If current user role doesn't match with the right role
if( ! in_array( $user_role, $user->roles) ) {
// Remove "subscriber" user role (if it is set)
if( in_array('subscriber', $user->roles) ) {
$user->remove_role( 'subscriber' );
}
// Remove other user roles (if they are set)
foreach ( $settings as $key_id => $value_role ) {
if( in_array($value_role, $user->roles) && $user_role !== $value_role ) {
$user->remove_role( $value_role );
}
}
// Set the right user role (if it is not set yet)
$user->set_role( $user_role );
}
}
}
// On first purchase (if needed)
add_action( 'woocommerce_subscription_status_updated', 'active_subscription_change_user_role', 100, 3 );
function active_subscription_change_user_role( $subscription, $new_status, $old_status ) {
// When subscrition status is updated to "active"
if ( $new_status === 'active' ) {
// Get the WC_Order Object from subscription
$order = wc_get_order( $subscription->get_parent_id() );
// Get an instance of the customer WP_User Object
$user = $order->get_user();
// Check that it's not a guest customer
if( is_a( $user, 'WP_User' ) && $user->ID > 0 ) {
// Load settings
$settings = variation_id_per_user_role_settings();
// Loop through order items
foreach ( $subscription->get_items() as $item ) {
check_order_item_and_change_user_role( $item, $user, $settings );
}
}
}
}
// On switched purchased subscription
add_action( 'woocommerce_order_status_changed', 'switched_subscription_change_user_role_on_order_status_change', 100, 4 );
function switched_subscription_change_user_role_on_order_status_change( $order_id, $old_status, $new_status, $order ) {
// When order status is updated to 'processing' or 'completed' status
if ( in_array( $new_status, array('processing','completed') ) ) {
// Get an instance of the customer WP_User Object
$user = $order->get_user();
// Check that it's not a guest customer
if( is_a( $user, 'WP_User' ) && $user->ID > 0 ) {
// Load settings
$settings = variation_id_per_user_role_settings();
// Loop through order items
foreach ( $order->get_items() as $item ) {
check_order_item_and_change_user_role( $item, $user, $settings );
}
}
}
}
Code goes in functions.php file of your active child theme (or active theme). It could works.
Or you can also try with woocommerce_subscription_status_active
hook:
// Custom function for your settings - Variation id per user role
function variation_id_per_user_role_settings(){
// Settings: set the variation ID as key with the related user role as value
return array(
'417' => 'subscriber-a',
'418' => 'subscriber-b',
'419' => 'subscriber-c',
);
}
// Custom function that check item and change user role based on variation ID
function check_order_item_and_change_user_role( $item, $user, $settings ){
$product = $item->get_product(); // The product object
// Only for variation subscriptions
if( $product->is_type('subscription_variation') ) {
$variation_id = $item->get_variation_id(); // the variation ID
$user_role = $settings[$variation_id]; // The right user role for the current variation ID
// If current user role doesn't match with the right role
if( ! in_array( $user_role, $user->roles) ) {
// Remove "subscriber" user role (if it is set)
if( in_array('subscriber', $user->roles) ) {
$user->remove_role( 'subscriber' );
}
// Remove other user roles (if they are set)
foreach ( $settings as $key_id => $value_role ) {
if( in_array($value_role, $user->roles) && $user_role !== $value_role ) {
$user->remove_role( $value_role );
}
}
// Set the right user role (if it is not set yet)
$user->set_role( $user_role );
}
}
}
// On first purchase (if needed)
add_action( 'woocommerce_subscription_status_active', 'active_subscription_change_user_role', 100 );
function active_subscription_change_user_role( $subscription ) {
// Get the WC_Order Object from subscription
$order = wc_get_order( $subscription->get_parent_id() );
// Get an instance of the customer WP_User Object
$user = $order->get_user();
// Check that it's not a guest customer
if( is_a( $user, 'WP_User' ) && $user->ID > 0 ) {
// Load settings
$settings = variation_id_per_user_role_settings();
// Loop through order items
foreach ( $subscription->get_items() as $item ) {
check_order_item_and_change_user_role( $item, $user, $settings );
}
}
}
// On switched purchased subscription
add_action( 'woocommerce_order_status_changed', 'switched_subscription_change_user_role_on_order_status_change', 100, 4 );
function switched_subscription_change_user_role_on_order_status_change( $order_id, $old_status, $new_status, $order ) {
// When order status is updated to 'processing' or 'completed' status
if ( in_array( $new_status, array('processing','completed') ) ) {
// Get an instance of the customer WP_User Object
$user = $order->get_user();
// Check that it's not a guest customer
if( is_a( $user, 'WP_User' ) && $user->ID > 0 ) {
// Load settings
$settings = variation_id_per_user_role_settings();
// Loop through order items
foreach ( $order->get_items() as $item ) {
check_order_item_and_change_user_role( $item, $user, $settings );
}
}
}
}
Code goes in functions.php file of your active child theme (or active theme). It should works.
Documentation: Subscriptions Action Hook Reference