PHPackages                             furic/filament-redeem-codes - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. furic/filament-redeem-codes

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

furic/filament-redeem-codes
===========================

Filament v5 plugin for batch-issued, multi-reward redeem codes — for games, event rewards and player compensation.

v0.1.0(2mo ago)121MITPHPPHP ^8.2

Since May 6Pushed 1mo agoCompare

[ Source](https://github.com/furic/filament-redeem-codes)[ Packagist](https://packagist.org/packages/furic/filament-redeem-codes)[ Docs](https://github.com/furic/filament-redeem-codes)[ RSS](/packages/furic-filament-redeem-codes/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (1)Dependencies (6)Versions (2)Used By (0)

Filament Redeem Codes
=====================

[](#filament-redeem-codes)

[![Filament Plugin](https://camo.githubusercontent.com/329d3b6dfe5b91dbf0b500aa1d5815c72e738579a0cb6859e6702c7478fcba95/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f46696c616d656e742d506c7567696e2d4644414534423f7374796c653d666c6174266c6f676f3d6c61726176656c266c6f676f436f6c6f723d7768697465)](https://filamentphp.com/plugins/richard-fu-redeem-codes)[![Latest Version on Packagist](https://camo.githubusercontent.com/a3c98a6aca0e6bc221640816d48e83e900b8f6bebcf7a55c2b5a2574160f3a28/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f66757269632f66696c616d656e742d72656465656d2d636f6465732e7376673f7374796c653d666c6174)](https://packagist.org/packages/furic/filament-redeem-codes)[![Total Downloads](https://camo.githubusercontent.com/0bd420c1ee32864df5445922bea27b9e1351ea562d56552209017326ec7cc99b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f66757269632f66696c616d656e742d72656465656d2d636f6465732e7376673f7374796c653d666c6174)](https://packagist.org/packages/furic/filament-redeem-codes)[![PHP Version](https://camo.githubusercontent.com/c71a5d3fa57f76132e59018ce43ded91a843d81ce8fc0d8b7dfbde85ec401625/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f66757269632f66696c616d656e742d72656465656d2d636f6465732e7376673f7374796c653d666c6174)](https://packagist.org/packages/furic/filament-redeem-codes)[![License](https://camo.githubusercontent.com/9c0a469f4fb3dd91a2294ef23ea37c368d4a9d68d541bf2c8181ecfb0809b319/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f66757269632f66696c616d656e742d72656465656d2d636f6465732e7376673f7374796c653d666c6174)](LICENSE)

A Filament v5 plugin for **batch-issued, multi-reward redeem codes** — built for game player compensation, event rewards, and marketing campaigns where one batch needs to issue many codes that all share the same reward set.

📦 Available on the [Filament plugin directory](https://filamentphp.com/plugins/richard-fu-redeem-codes).

This is a ground-up rewrite of [`furic/redeem-codes`](https://github.com/furic/laravel-redeem-codes), a 2018 package retired in favour of a Filament-native approach.

Screenshots
-----------

[](#screenshots)

Campaign listEdit campaign + rewardsGenerate codes[![Campaign list](docs/images/campaign-list.png)](docs/images/campaign-list.png)[![Edit campaign](docs/images/edit-form-typed.png)](docs/images/edit-form-typed.png)[![Generate codes modal](docs/images/generate-codes-modal.png)](docs/images/generate-codes-modal.png)Reward types (admin-managed)Add a new reward type[![Reward types list](docs/images/reward-types-list.png)](docs/images/reward-types-list.png)[![Create reward type](docs/images/reward-type-create.png)](docs/images/reward-type-create.png)Why this plugin
---------------

[](#why-this-plugin)

Existing Filament coupon/voucher plugins target e-commerce: one code, one discount value. None of them model the "campaign → N codes → M shared rewards" topology that games need (e.g. an Easter event hands out 5,000 codes that all grant 500 coins + 1 character + 5 energy).

NeedExisting Filament pluginsThis pluginGenerate N codes at once❌✅Multi-reward per code❌ (1 discount only)✅ (any number of typed rewards)Campaign / batch grouping❌✅Game-style rewards (items, currency)❌ (monetary only)✅ (enum or admin-managed)Print/OCR-friendly code alphabet—✅ (no `0/1/O/I` ambiguity)Public redemption API + rate limit—✅Requirements
------------

[](#requirements)

- PHP `^8.2`
- Laravel `^11.0 || ^12.0 || ^13.0`
- Filament `^5.0`

Install
-------

[](#install)

```
composer require furic/filament-redeem-codes
php artisan vendor:publish --tag="filament-redeem-codes-migrations"
php artisan vendor:publish --tag="filament-redeem-codes-config"
php artisan migrate
```

Register the plugin in your panel provider:

```
use Furic\FilamentRedeemCodes\FilamentRedeemCodesPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->id('admin')
        ->plugins([
            FilamentRedeemCodesPlugin::make(),
        ]);
}
```

Reward types — pick a binding strategy
--------------------------------------

[](#reward-types--pick-a-binding-strategy)

Reward types are stored as strings on each reward row. The `filament-redeem-codes.reward_type` config decides how those strings are constrained and presented in the panel. Two flavours are supported:

### Option A: Backed enum (recommended for single-game, code-controlled types)

[](#option-a-backed-enum-recommended-for-single-game-code-controlled-types)

Define a backed enum implementing the marker interface and bind it:

```
// app/Enums/RewardType.php
namespace App\Enums;

use Furic\FilamentRedeemCodes\Contracts\RewardType as RewardTypeContract;

enum RewardType: string implements RewardTypeContract
{
    case Coins = 'coins';
    case Gems = 'gems';
    case Energy = 'energy';
    case Character = 'character';
    case RemoveAds = 'remove_ads';
}
```

```
// config/filament-redeem-codes.php
'reward_type' => App\Enums\RewardType::class,
```

The campaign form switches from a free-text input to a typed `Select`, and `RedeemCodeReward::$type` hydrates as your enum so you get exhaustive `match` checks in host code.

**Use when:** the reward set is closed and tied to compiled client logic. Adding a new type requires deploying client code anyway, so source-controlling the list makes sense.

### Option B: Eloquent model (admin-managed, runtime-editable)

[](#option-b-eloquent-model-admin-managed-runtime-editable)

Bind the bundled model — a `Reward Types` page appears in the panel where ops/marketing can add, rename, and reorder types without a deploy:

```
// config/filament-redeem-codes.php
'reward_type' => Furic\FilamentRedeemCodes\Models\RedeemRewardType::class,
```

Each row carries `key` (machine identifier sent to clients), `label` (human name), `icon`, `description`, and `sort_order`. The campaign form populates the Type dropdown from these rows. The redemption API includes the resolved label alongside the raw type string:

```
{"type": "coins", "label": "Coins", "amount": 500}
```

**Use when:** multi-game/white-label panels, marketing-driven cosmetic rewards (avatar frames, sticker packs), or i18n labels — anywhere the *type list itself* benefits from non-developer curation. **Tradeoff:** you lose compile-time safety in host code.

### Option C: Free-text (default, no binding)

[](#option-c-free-text-default-no-binding)

Leave `reward_type` as `null`. Campaign form uses a plain text input, types are stored verbatim. Fine for prototypes and low-stakes uses.

Generating codes
----------------

[](#generating-codes)

In the panel, open a campaign's edit page and click **Generate codes** in the header. Provide a count, optional prefix, and optional `reusable` flag.

Programmatically:

```
use Furic\FilamentRedeemCodes\Actions\GenerateCodes;
use Furic\FilamentRedeemCodes\Models\RedeemCampaign;

$campaign = RedeemCampaign::create(['name' => 'Easter 2026']);
$campaign->rewards()->createMany([
    ['type' => 'coins', 'amount' => 500],
    ['type' => 'energy', 'amount' => 5],
]);

$codes = (new GenerateCodes)->execute(
    campaign: $campaign,
    count: 5_000,
    prefix: 'EASTER',
    reusable: false,
);
```

Public redemption API
---------------------

[](#public-redemption-api)

```
GET /api/redeem/{code}

```

**Success (200):**

```
{
  "data": {
    "code": "EASTERAB23GH",
    "reusable": false,
    "redeemed_at": "2026-05-06T12:34:56+00:00",
    "rewards": [
      {"type": "coins", "label": "Coins", "amount": 500},
      {"type": "energy", "label": "Energy", "amount": 5}
    ]
  }
}
```

The `label` field is included only when a reward type binding is configured (enum case name, or model `label` column). With no binding, only `type` is returned.

**Failure responses:**

Status`error`Meaning404`code_not_found`Unknown code409`code_already_redeemed`Single-use code already consumed422`campaign_not_started`Campaign `start_at` is in the future410`campaign_expired`Campaign `end_at` is in the past429(Laravel default)Rate limit hitThe endpoint is rate-limited to **10 attempts per minute per IP** by default. Configure via `filament-redeem-codes.api.rate_limit` (`","`).

To disable the API entirely (panel-only usage):

```
'api' => ['enabled' => false],
```

Events
------

[](#events)

`Furic\FilamentRedeemCodes\Events\RedeemCodeRedeemed` fires after a successful redemption. Hook it to grant rewards in your host app:

```
use Furic\FilamentRedeemCodes\Events\RedeemCodeRedeemed;

Event::listen(RedeemCodeRedeemed::class, function (RedeemCodeRedeemed $event) {
    foreach ($event->code->rewards as $reward) {
        // grant $reward->type / $reward->amount to auth()->user()
    }
});
```

Per-user redemption tracking
----------------------------

[](#per-user-redemption-tracking)

By design, this package does **not** know who redeemed what. **Single-use** codes self-track via `redeemed_at`; **reusable** codes never become unredeemable. If you need per-user "this user has already used this reusable code" enforcement, listen for `RedeemCodeRedeemed` and store that linkage in your host app.

Migrating from `furic/redeem-codes`
-----------------------------------

[](#migrating-from-furicredeem-codes)

The schema is intentionally different — this is a v2, not a drop-in upgrade. Notable changes:

- `events` → `redeem_campaigns` (also fixes the `start_at`/`started_at` inconsistency in v1)
- `redeemed` boolean → `redeemed_at` nullable timestamp
- `redeem_code_rewards.type` was numeric → now string (host binds an enum)
- Hardcoded reward types removed; bind your own enum
- Web console replaced by Filament Resource
- Built-in rate limiting and structured error codes
- Real test suite

Existing v1 installations should write a one-time data migration; the schemas don't line up.

Testing
-------

[](#testing)

```
composer install
composer test
```

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance88

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

80d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/44884321?v=4)[Richard Fu](/maintainers/furic)[@furic](https://github.com/furic)

---

Top Contributors

[![furic](https://avatars.githubusercontent.com/u/44884321?v=4)](https://github.com/furic "furic (7 commits)")

---

Tags

couponfilamentfilament-pluginfilamentphpgamedevlaravelphppromo-coderedeem-coderewardsvoucherlaravelgamevoucherfilamentfilamentphprewardpromo coderedeem code

###  Code Quality

TestsPest

### Embed Badge

![Health badge](/badges/furic-filament-redeem-codes/health.svg)

```
[![Health](https://phpackages.com/badges/furic-filament-redeem-codes/health.svg)](https://phpackages.com/packages/furic-filament-redeem-codes)
```

###  Alternatives

[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.8k](/packages/rawilk-profile-filament-plugin)[stephenjude/filament-jetstream

A Laravel starter kit built with Filament inspired by Jetstream.

17760.2k3](/packages/stephenjude-filament-jetstream)[codewithdennis/filament-select-tree

The multi-level select field enables you to make single selections from a predefined list of options that are organized into multiple levels or depths.

330530.5k30](/packages/codewithdennis-filament-select-tree)[dotswan/filament-map-picker

Easily pick and retrieve geo-coordinates using a map-based interface in your Filament applications.

128192.3k3](/packages/dotswan-filament-map-picker)[stephenjude/filament-debugger

About

104162.2k2](/packages/stephenjude-filament-debugger)[finity-labs/fin-mail

A powerful email template manager and composer for Filament with dynamic token replacement, template versioning, and inline email sending.

284.8k2](/packages/finity-labs-fin-mail)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
