December 29, 2023

Automatically Upgrade User Roles Based on Spending in WooCommerce

In this article, we’ll walk through how to automatically upgrade a WooCommerce customer’s user role based on their total spending. This is a common feature in membership or loyalty systems—once a customer spends a certain amount (e.g., $1000), their account is upgraded to a VIP role, which can then be used to provide exclusive benefits like discounts.

By leveraging the woocommerce_order_status_changed action hook, developers can easily implement this upgrade logic without relying on third-party plugins. We’ll explore how to detect user spending, upgrade their role, and even handle cases where a refund should reverse the upgrade.


Use Case: Auto-Upgrade to VIP After Reaching Spending Threshold

In WooCommerce, we can use WordPress roles to define membership levels. For example, regular customers may have the customer role, while VIP customers could be assigned a custom vip-customer role. To automatically upgrade a customer once their total spending exceeds $999.99, we can use WooCommerce’s built-in wc_get_customer_total_spent() function.

Here’s the function that performs the upgrade:

function wprs_customer_maybe_upgrade_to_vip( $user_id ) {
	if ( wc_get_customer_total_spent( $user_id ) > 999.99 ) {
		$user = new WP_User( $user_id );
		$user->add_role( 'vip-customer' );
		$user->remove_role( 'customer' );
	}
}

When to Trigger the Role Upgrade

The best time to run this logic is when an order’s status changes. Specifically, after a successful payment is recorded (e.g., when the order status becomes processing or completed), we can check whether the customer qualifies for an upgrade.

To avoid redundant role changes or accidental double upgrades, we add a meta flag _wprs_role_switched to mark the order as already processed for role switching.

Here’s how we put it all together:

add_action( 'woocommerce_order_status_changed', function ( $order_id ) {
	$order               = wc_get_order( $order_id );
	$user_id             = $order->get_user_id();
	$order_status        = $order->get_status();
	$switch_already_done = $order->get_meta( '_wprs_role_switched' );

	if ( ! $switch_already_done 
		&& $order->has_status( wc_get_is_paid_statuses() ) 
		&& wc_user_has_role( $user_id, 'customer' ) ) {
		
		wprs_customer_maybe_upgrade_to_vip( $user_id );

		$order->update_meta_data( '_wprs_role_switched', 'true' );
		$order->save();
	}
} );

Bonus: Revoke VIP Role on Refund

In scenarios where a customer receives a refund that reduces their total spending below the VIP threshold, you may want to revoke their VIP status. This can be done by hooking into the woocommerce_order_refunded action and performing a similar check in reverse.

While the refund logic isn’t included in this post, it would closely mirror the upgrade function—except you’d remove the vip-customer role and reassign the customer role if applicable.


Final Thoughts

Rewarding loyal customers by upgrading their membership based on spending is a great way to boost engagement. With just a few lines of code, you can build a robust VIP system within WooCommerce, without relying on external plugins. This approach also gives you full flexibility to integrate discounts, badges, or exclusive content tied to user roles.

If you’d like to go a step further, consider:

  • Automating email notifications when users are upgraded
  • Displaying VIP status on user dashboards
  • Applying special pricing using role-based discounts

Happy coding!