Blog Detail


A Polymorphic Coupon Functionality for Your Laravel Apps cover image

arrow_back A Polymorphic Coupon Functionality for Your Laravel Apps

Laravel Couponables is an amazing package introduced by Michael Rubel that provides polymorphic coupon functionality for your Laravel application. This package requires PHP ^8.x and Laravel ^8.71 or ^9.0.


You can install the package using composer by running this command in terminal:

composer require michael-rubel/laravel-couponables

Publish the migrations:

php artisan vendor:publish --tag="couponables-migrations"

Publish the config file:

php artisan vendor:publish --tag="couponables-config"


After publishing migrations you can use this trait in any of your models:

use HasCoupons;

Seed your database with coupon codes using the
Coupon model, then apply the code using:


redeemCoupon method throws an exception if something’s wrong:

CouponExpiredException      // Coupon is expired (`expires_at` column).
InvalidCouponException      // Coupon is not found in the database.
NotAllowedToRedeemException // Coupon is assigned to the specific model (`redeemer` morphs).
OverLimitException          // Coupon is over the limit for the specific model (`limit` column).
OverQuantityException       // Coupon is exhausted (`quantity` column).

Check if this coupon is already redeemed by the model (at least one record exists in the couponables table):


Available coupon model API:

public function isExpired(): bool;
public function isNotExpired(): bool;
public function isOverQuantity(): bool;
public function isRedeemedBy(Model $redeemer): bool;
public function isOverLimitFor(Model $redeemer): bool;

This method references the model assigned to redeem the coupon:

public function redeemer(): ?Model;

Overriding the package functionality

Traits DefinesColumns and DefinesPivotColumns contain the methods that define column names to use by the package. You can use a method binding to override the package’s method behavior.

Example method binding in your ServiceProvider:

bind(CouponContract::class)->method('getCodeColumn', fn () => 'coupon')
// This method returns the `coupon` column name instead of `code` from now.

Alternatively, you can extend/override the entire class using config values or container bindings. All the classes in the package have their own contract (interface), so you’re free to modify it as you wish.

For more details, you can visit its complete documentation and source code on Github

Published at : 09-03-2022

Author : Rizwan Aslam
Rizwan Aslam

I am a highly results-driven professional with 12+ years of collective experience in the grounds of web application development especially in laravel, native android application development in java, and desktop application development in the dot net framework. Now managing a team of expert developers at Codebrisk.

Launch your project

Launch project