Customers redeem more points when they understand the rules. A clear panel on the checkout page that shows their balance, the maximum they can use on this order, and how much more they would need to spend to unlock a higher cap turns redemption from a guess into a goal. With one short snippet, you can render that panel directly on the WooCommerce checkout.
What the Panel Shows
- Available balance. The customer’s current points total.
- Redeemable on this order. The lower of their balance and the active cap for the current cart size.
- Next tier hint. How much more they need to spend to reach the next redemption tier, and what the new cap will be.
The Snippet
The example below uses the same tiered cap shape as the redemption-limit guide (NT$1,500 / NT$3,000 brackets). Keep both snippets in sync: if you change the thresholds in one place, change them in the other so the customer sees the same numbers the filter enforces.
<?php
/**
* Show points redemption guidance on the checkout page.
* Drop into wp-content/mu-plugins/ or your child theme functions.php.
*/
add_action('woocommerce_review_order_before_payment', 'wpgl_show_redemption_guidance');
function wpgl_show_redemption_guidance()
{
if (!is_user_logged_in() || !class_exists('WPGL_Points_Core')) {
return;
}
$user_id = get_current_user_id();
$balance = (int) get_user_meta($user_id, '_wpgens_loyalty_points', true);
$settings = WPGL_Points_Core::get_settings();
$rate = $settings['conversionRate'] ?? null;
if (!$rate || empty(WC()->cart) || WC()->cart->is_empty()) {
return;
}
// Hard ceiling configured in plugin settings
$global_max = (int) ($rate['maxPoints'] ?? 0);
// Tiered cap mirroring the redemption-limit example. Sync with that snippet if you use both.
$tiers = [
1500 => 100,
3000 => 250,
PHP_INT_MAX => 500,
];
$cart_subtotal = (float) WC()->cart->get_subtotal();
$tier_max = 0;
$next_threshold = 0;
$next_tier_max = 0;
foreach ($tiers as $threshold => $limit) {
if ($cart_subtotal <= $threshold && $tier_max === 0) {
$tier_max = (int) $limit;
} elseif ($tier_max > 0 && $next_threshold === 0) {
$next_threshold = (int) $threshold;
$next_tier_max = (int) $limit;
}
}
$effective_max = $global_max > 0 ? min($global_max, $tier_max) : $tier_max;
$usable_now = min($balance, $effective_max);
echo '<div class="wpgl-redeem-guidance" style="margin: 1em 0; padding: 1em; background: #f7f7f7; border-radius: 6px;">';
echo '<strong>' . esc_html__('Your points', 'wpgens-loyalty-program') . '</strong><br>';
echo esc_html(sprintf(
/* translators: 1: balance, 2: max usable now */
__('Balance: %1$d. Redeemable on this order: %2$d.', 'wpgens-loyalty-program'),
$balance,
$usable_now
));
if ($next_threshold > 0 && $next_threshold !== PHP_INT_MAX) {
$needed = max(0, $next_threshold - $cart_subtotal);
echo '<br>' . esc_html(sprintf(
/* translators: 1: amount to spend, 2: new max */
__('Spend %1$s more to unlock a higher redemption cap of %2$d points.', 'wpgens-loyalty-program'),
wp_strip_all_tags(wc_price($needed)),
$next_tier_max
));
}
echo '</div>';
}
The guidance is rendered through woocommerce_review_order_before_payment, which fires inside the order review block and refreshes every time WooCommerce recalculates totals. This means the numbers stay live as the customer adds items, applies coupons, or changes shipping.
Styling
The snippet ships with minimal inline styles so it works out of the box. Move them into your theme stylesheet under the .wpgl-redeem-guidance class for anything more polished. The panel is plain HTML, so it is easy to extend with icons, accent colors, or a call-to-action button that scrolls to the redemption block.
Where to Put This Snippet
Drop the snippet into a small site-specific plugin under wp-content/mu-plugins/ so it survives theme changes, or paste it into your child theme’s functions.php.