I am trying to create a function to add a new user role to any customer who purchases a specific item via Woocommerce.
I have the following code which achieves this with a paid product, however, the product that triggers this is a free item. I am not sure if the code "paying_customer" is stopping this function from working with a free item order.
Is there an alternative to using "paying_customer" or a better way of achieving this?
Below is the code that works for paid products, but not for free products.
Thanks
function change_role_on_purchase( $order_id ) {
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_name = $item['name'];
$product_id = $item['product_id'];
$product_variation_id = $item['variation_id'];
if ( $order->user_id > 0 && $product_id == '13874904' ) {
update_user_meta( $order->user_id, 'paying_customer', 1 );
$user = new WP_User( $order->user_id );
// Remove role
$user->remove_role( 'subscriber' );
// Add role
$user->add_role( 'special_subscriber' );
}
}
}
add_action( 'woocommerce_order_status_processing', 'change_role_on_purchase' );
Your code is obsolete, can be simplified and has some mistakes like:
Try the following:
add_action( 'woocommerce_order_status_processing', 'change_role_on_purchase', 10, 2 );
add_action( 'woocommerce_order_status_completed', 'change_role_on_purchase', 10, 2 );
function change_role_on_purchase( $order_id, $order ) {
$user = $order->get_user(); // Get the WP_User Object
// Loop through order line items
foreach ( $order->get_items() as $item ) {
$product_id = $item->get_product_id();
$variation_id = $item->get_variation_id();
if ( $user && in_array('13874904', [$product_id , $variation_id]) ) {
// Set user as paying customer if not set yet
wc_paying_customer( $order_id );
// Check for "subscriber" user role and replace it
if ( wc_user_has_role( $user, 'subscriber' ) ) {
$user->set_role( 'special_subscriber' );
}
break; // Stop the loop
}
}
}
It should better work.
Related: