---
title: "Display helpers — Coupons for Laravel | Roundly"
description: "Non-throwing helpers for views and APIs — remaining uses, usage percentage, can-this-customer-redeem and a safe discount preview."
url: https://roundly-consulting.com/open-source/docs/coupons-for-laravel/display-helpers
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Coupons for Laravel](https://roundly-consulting.com/open-source/docs/coupons-for-laravel.md)

# Display helpers

For views and APIs, read coupon state without manual math or try/catch. Each helper is safe to call anywhere:

```php
$coupon->remainingUsage();              // ?int   — e.g. 37; null when unlimited (max_usage <= 0)
$coupon->remainingUsageFor($user);      // ?int   — null when untracked or per-redeemer unlimited
$coupon->usagePercentage();             // ?float — e.g. 92.6 (0..100); null when unlimited
$coupon->isRedeemableBy($user, $cart);  // bool   — pass a price to also check currency + minimum spend
$coupon->previewDiscount($cart);        // Money  — zero on a currency mismatch
```

| Method | Returns |
| --- | --- |
| `remainingUsage(): ?int` | Uses left under the global cap; null when unlimited. |
| `remainingUsageFor(Model $redeemer): ?int` | Uses left for that redeemer; null when tracking is off or the per-redeemer cap is 0. |
| `usagePercentage(): ?float` | Share of the global cap used, 0..100, rounded to 2 decimals; null when unlimited. |
| `isRedeemableBy(?Model $redeemer = null, ?Money $price = null): bool` | The same checks as redemption; pass a price to also check currency and minimum spend. |
| `previewDiscount(Money $price): Money` | Like discountFor(), but zero on a currency mismatch — safe in views. |

isRedeemableBy() asks Coupons::check() — the same checks, in the same order, as redeem() and the Redeemable rule — so they never drift apart: a soft-deleted Coupon instance, for one, is NotFound for all of them, just as redeem() throws CouponNotFound. Use Coupons::check() itself when you need the reason, not just a yes or no; Coupons::code($code)->preview($cart) is the facade form of previewDiscount() when you only have a code.

## Example: a coupon preview endpoint

```php
use RoundlyConsulting\Coupons\Facades\Coupons;

$coupon = Coupons::findOrFail((string) $request->input('code'));

return [
    'code' => $coupon->code,
    'redeemable' => $coupon->isRedeemableBy($request->user(), $cartTotal),
    'you_save' => (string) $coupon->previewDiscount($cartTotal),   // e.g. "4.50 EUR"
    'uses_left' => $coupon->remainingUsage(),
    'free_shipping' => $coupon->appliesToShipping(),
];
```

One edge case: a Fixed row written around CreateCouponAction without a currency can’t be priced at all, so previewDiscount() still throws InvalidCouponDefinition for it.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/coupons-for-laravel.md)
