Award Different Points per Customer Role in Your WooCommerce Loyalty Program

Loyalty Program for WooCommerce applies a single global earning rate, the points per unit of currency, to every customer. There is no admin setting for a different rate per user role, but the earning calculation is filter driven, so you can award different points to different customer roles with a small snippet. A common use case is giving your subscribers double points while regular customers keep the standard rate.

Which filter to use

Points for an order are finalised in the wpgens_loyalty_order_points_after_discount filter. It receives the WooCommerce order object, so you can read the real customer with $order->get_user_id() and multiply the points. This is the value that is actually awarded, and because it reads the customer from the order it keeps working even when points are granted in the background, for example when an admin changes the order status, or when cron or Action Scheduler runs, where the current logged in user is not available.

To keep the “points to be earned” preview in the cart in sync with what is awarded, add the same multiplier to wpgens_loyalty_cart_points_after_discount, which runs for the logged in customer while they view the cart.

Example: double points for subscribers

Add the following to your child theme functions.php, or better, to a small custom plugin. Adjust the roles and multipliers in the $role_multipliers array to match your store.

/**
 * Double points for subscribers, custom rates per role.
 * Regular customers keep the normal rate; add rows to $role_multipliers as needed.
 */
function my_loyalty_role_multiplier_for_user( $user_id ) {
    if ( ! $user_id ) {
        return 1.0; // guest, no change
    }

    // Option A: by WordPress user role
    $role_multipliers = array(
        'subscriber' => 2.0, // double points
        'wholesale'  => 1.5,
    );
    $user = get_userdata( $user_id );
    if ( $user ) {
        foreach ( (array) $user->roles as $role ) {
            if ( isset( $role_multipliers[ $role ] ) ) {
                return (float) $role_multipliers[ $role ];
            }
        }
    }

    // Option B: active WooCommerce Subscription. Use this if "subscribers"
    // means paying subscribers, not the built in WordPress "subscriber" role.
    // if ( function_exists( 'wcs_user_has_subscription' )
    //     && wcs_user_has_subscription( $user_id, '', 'active' ) ) {
    //     return 2.0;
    // }

    return 1.0;
}

// What actually gets awarded on the order.
add_filter( 'wpgens_loyalty_order_points_after_discount', function ( $points, $order ) {
    $mult = my_loyalty_role_multiplier_for_user( $order->get_user_id() );
    return $mult !== 1.0 ? round( $points * $mult ) : $points;
}, 20, 2 );

// Keep the cart "points to be earned" preview in sync for the logged in user.
add_filter( 'wpgens_loyalty_cart_points_after_discount', function ( $points, $cart, $ratio ) {
    $mult = my_loyalty_role_multiplier_for_user( get_current_user_id() );
    return $mult !== 1.0 ? round( $points * $mult ) : $points;
}, 20, 3 );

Roles versus active subscriptions

Decide what “subscriber” means for your store. The built in WordPress subscriber role is the default low privilege role every registered user can have, and it is usually not the same as a paying subscriber. If you sell subscriptions with WooCommerce Subscriptions and want to reward customers with an active plan, use Option B in the snippet, which checks wcs_user_has_subscription() instead of the role name. You can also combine both approaches, for example a higher multiplier for wholesale roles and double points for active subscribers.

How it works with rank multipliers

If you also use the Ranks feature with a points multiplier reward, both multipliers apply. Rank multipliers are calculated per line item before the order total is finalised, so a role multiplier added on wpgens_loyalty_order_points_after_discount stacks on top. For example a Gold rank with a 2x multiplier combined with a 2x subscriber role reward results in 4x the base points. Set your multipliers with that stacking in mind.

Can I set different points per customer role without code?

No. The plugin uses one global earning rate and there is no per role rate field in the admin. Different rates per role are added with a short PHP snippet on the wpgens_loyalty_order_points_after_discount filter.

Will subscribers still get their rank multiplier as well?

Yes. Rank multipliers are applied per line item before the order total is finalised, so a role multiplier added on wpgens_loyalty_order_points_after_discount stacks on top of the rank multiplier.

Does subscriber mean the WordPress role or a WooCommerce Subscriptions customer?

It can be either. Use the WordPress role check for the built in subscriber role, or the wcs_user_has_subscription check shown in Option B to target customers with an active WooCommerce subscription.

Why not use the per item filter that ranks use?

The per item hook resolves the customer with the current logged in user, which is empty when points are awarded in the background by cron or an admin status change. Reading the customer from the order object avoids that, so the multiplier is always applied.

Browse our plugins

Lightweight WooCommerce plugins built for speed. No bloat, no frameworks -- just clean code that works.

View all plugins
Stay in the loop

Get notified when we launch new plugins. No spam, just product updates.