Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Vouchers Laravel Package

frittenkeez/laravel-vouchers

Laravel Vouchers offers an Eloquent-backed way to create, issue, and redeem voucher codes. Track usage, associate vouchers with models, and manage redemption state through a simple API for discounts, invites, credits, or other redeemable rewards.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Promotions, coupons, and voucher campaigns: This package provides the persistence layer for generating, issuing, redeeming, and revoking voucher codes—supporting discount campaigns, gift cards, referral codes, and one-time access codes without building code-issuance and redemption logic from scratch.
  • Bulk campaign planning and launch: The 0.9.0 counter-based codes (Vouchers::withCounter(), withCounterPadding(), withCodeFormatter()) remove the previous hard limit where a static withCode() could only safely produce a single voucher. This directly unlocks "batch-generate 10,000 codes for a seasonal campaign" as a scoped feature rather than a custom build.
  • Build vs. buy: This is a credible "buy" (adopt OSS) for the generic 80%: code uniqueness, redemption state, expiry, ownership, redeemers, and metadata. Build only the differentiated pieces—promotion rules, eligibility logic, pricing/stacking rules, and customer-facing redemption UX—on top of it.
  • Performance-sensitive campaigns: 0.9.0's batch optimization (100 vouchers from ~100 lookups to 1 query, chunked at 500) means large code-generation jobs are feasible within request/queue time budgets. This lowers the infra cost and risk previously attached to high-volume campaigns.
  • Roadmap signal: The API is still pre-1.0 (0.9.0) and has now dropped Laravel 11 support and shipped breaking changes. Plan adoption with a maintenance owner, a pinned version, and a periodic upgrade window; avoid treating it as a set-and-forget dependency in a long-lived product.

When to Consider This Package

Consider adoption when:

  • You are on Laravel 12.4+ (hard requirement in 0.9.0) and are comfortable tracking a pre-1.0 dependency.
  • Your need is fundamentally code lifecycle: generate, issue, look up, redeem, unredeem, expire, and associate vouchers with owners/redeemers. The package models these explicitly, including Voucher/Redeemer/VoucherEntity relations.
  • You expect to generate codes in volume (bulk campaigns, seeded batches, exports) and want built-in uniqueness checks and batching rather than hand-rolled collision handling.
  • You need metadata attached to vouchers and redeemers that can be mutated in place—0.9.0 changes metadata to an ArrayObject cast, which is a better ergonomic fit for accumulating redemption context than reassigning arrays wholesale.
  • You want custom code shapes (prefixes, separators, padding) via withCodeFormatter() and the new CodeFormat value object rather than string concatenation scattered through your domain.

Look elsewhere or build your own when:

  • You are pinned to Laravel 11 or earlier—0.9.0 drops it, and the scope-attribute migration in 0.9.0 depends on 12.4.
  • You need a 1.0-stable API contract or vendor support/SLAs. This release renamed a scope (Voucher::code() → Voucher::withCode()), made scope methods protected, renamed a widely used parameter, and changed the runtime type of $metadata. That is a fast-moving surface.
  • Your requirements are promotion-engine problems (stacking, eligibility, tiered discounts, tax interplay). This package stores and redeems codes; it does not price carts.
  • You require guaranteed uniqueness semantics across distributed writers beyond what a database uniqueness constraint plus batch pre-check gives you; validate this against your concurrency model before committing.
  • You cannot absorb the 0.9.0 upgrade work: metadata ArrayObject conversions, named-argument callers of redeem()/unredeem()/redeemable()/unredeemable(), subclasses overriding scopes, and any code relying on withCode() + amount > 1 throwing instead of appending a counter.

How to Pitch It (Stakeholders)

To executives: This is a mature-enough open-source Laravel package that gives us voucher and coupon code issuance and redemption as a solved primitive, so we invest engineering time in campaign rules and customer experience instead of re-implementing code generation and redemption bookkeeping. The 0.9.0 release materially improves our bulk-campaign economics: generating a hundred codes now costs one database lookup instead of a hundred, and static-code collisions are handled with configurable counters and custom formatting instead of failing. The trade-off is that it is pre-1.0 and 0.9.0 is a breaking release requiring Laravel 12.4+; we should adopt it pinned, with a named owner and a scheduled upgrade cadence, and budget a small amount of maintenance per upgrade cycle.

To engineering: 0.9.0 is a breaking release; read UPGRADING.md before merging. Concretely: minimum Laravel is now 12.4 (for the #[Scope] attribute), all model scopes moved from scopeXxx() to #[Scope] and are now protected—affects anyone extending the models or overriding scopes. Voucher::code() is now Voucher::withCode() because a scope named code shadowed the column and broke $voucher->code when the attribute wasn't loaded. Voucher::$metadata and Redeemer::$metadata return ArrayObject, so any code passing them into array functions needs ->toArray(). The first parameter of redeem()/unredeem()/redeemable()/unredeemable() is renamed $code → $voucher, which breaks named-argument callers; those methods now also accept a Voucher instance directly, skipping a lookup query—worth adopting in hot paths. withCode() with an amount greater than one now appends a counter instead of throwing InfiniteLoopException; withMask() with a static mask still throws. New AsNullableArrayObject cast preserves null instead of storing the JSON string 'null'—useful if we have nullable JSON columns. Published migrations changed metadata from text to json and modernized to $table->id() / foreignId()->constrained()->cascadeOnDelete(); schema is unchanged and existing installs are unaffected, so no action needed. Also fixed: Voucher::withOwner() and VoucherEntity::withEntity() now use the instance's own getMorphClass(), which matters if we override morph types without a morph map. Deprecations: Laravel 11 and PEST 3 support dropped.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support