PHPackages                             nagsamayam/laravel-promocodes - 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. nagsamayam/laravel-promocodes

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

nagsamayam/laravel-promocodes
=============================

Coupons and promotional codes generator

462PHP

Since Apr 27Pushed 4y ago1 watchersCompare

[ Source](https://github.com/nagsamayam/laravel-promocodes)[ Packagist](https://packagist.org/packages/nagsamayam/laravel-promocodes)[ RSS](/packages/nagsamayam-laravel-promocodes/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

laravel-promocodes
==================

[](#laravel-promocodes)

Coupons and promotional codes generator for [Laravel](https://laravel.com). This package requires [Laravel 9.x](https://laravel.com/docs/9.x) and [PHP 8.1](https://www.php.net/releases/8.1/en.php).

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require nagsamayam/laravel-promocodes
```

Configuration
-------------

[](#configuration)

You can publish the config file with:

```
php artisan vendor:publish --tag="laravel-promocodes-config"
```

This is the contents of the published config file:

```
return [
    'models' => [
        'promocodes' => [
            'model' => \NagSamayam\Promocodes\Models\Promocode::class,
            'table_name' => 'promocodes',
            'foreign_id' => 'promocode_id',
        ],

        'users' => [
            'model' => \App\Models\User::class,
            'table_name' => 'users',
            'foreign_id' => 'user_id',
        ],

        'pivot' => [
            'model' => \NagSamayam\Promocodes\Models\PromocodeUser::class,
            'table_name' => 'promocode_user',
        ],
    ],
    'code_mask' => '**-****-****',
    'allowed_symbols' => 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789',
];
```

After you configure this file, publish and run the migrations with:

```
php artisan vendor:publish --tag="laravel-promocodes-migrations"
php artisan migrate
```

Now you will need to use AppliesPromocode on your user model.

```
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use NagSamayam\Promocodes\Traits\AppliesPromocode;

class User extends Authenticatable
{
    use AppliesPromocode;

    //
}
```

Usage
-----

[](#usage)

It's very easy to use. Methods are combined, so that you can configure promocodes easily.

- [Reference](#reference)
- [Creating Promocodes](#creating-promocodes)
- [Generating Promocodes](#generating-promocodes)
- [Applying Promocode](#applying-promocode)
- [Expiring Promocode](#expiring-promocode)
- [Applicable Discount](#get-applicable-discount)
- [Note](#note)

Reference
---------

[](#reference)

NameExplanationMaskAstrisks will be replaced with random symbolCharactersAllowed symbols to use in mask replacementTypePromocode type. flat or percentMulti useDefine if single code can be used multiple times, by the same userUnlimitedGenerated code will have unlimited usagesBound to userDefine if promocode can be used only one user, if user is not assigned initially, first user will be bound to promocodeUserDefine user who will be initially bound to promocodeCountAmount of unique promocodes should be generatedUsagesDefine how many times can promocode be usedExpirationDateTime when promocode should be expired. Null means that promocode will never expireDetailsArray of details which will be retrieved upon apply. `discount` key for `flat` type. `percent_off` key for `percent` typeMin order valueDefine order minimum valueMax discountDefine maximum discount to be applied for an order.StatusPromocode status. active or inactive. default `inactive`Creating Promocodes
-------------------

[](#creating-promocodes)

### Using class

[](#using-class)

Combine methods as you need. You can skip any method that you don't need, most of them already have default values. For custom code generation, `create` method should have argument. Or you can use `createWithCustomCode` with argument. Both the options works.

```
use NagSamayam\Promocodes\Facades\Promocodes;
use NagSamayam\Promocodes\Enums\PromocodeType;
use NagSamayam\Promocodes\Enums\PromocodeStatus;

Promocodes::mask('AA-***-BB') // default: config('promocodes.code_mask')
    ->characters('ABCDE12345') // default: config('promocodes.allowed_symbols')
    ->multiUse() // default: false
    ->unlimited() // default: false
    ->boundToUser() // default: false
    ->user(User::find(1)) // default: null
    ->count(5) // default: 1
    ->expiration(now()->addYear()) // default: null
    ->details(['percent_off' => 50]) // default: []
    ->minOrderValue(500) // default: null
    ->maxDiscount(5) // default: null
    ->createdByAdmin(User::find(1)) // default: null
    ->type(PromocodeType::PERCENT->value) // default: PromocodeType::FLAT->value
    ->status(PromocodeStatus::ACTIVE->value); // default: 'inactive'
    ->create(); // default: null

Promocodes::multiUse() // default: false
    ->boundToUser() // default: false
    ->user(User::find(1)) // default: null
    ->usages(5) // default: 1
    ->expiration(now()->addYear()) // default: null
    ->details(['discount' => 50]) // default: []
    ->minOrderValue(500) // default: null
    ->maxDiscount(5) // default: null
    ->createdByAdmin(User::find(1)) // default: null
    ->type(PromocodeType::FLAT->value) // default: PromocodeType::FLAT->value
    ->status(PromocodeStatus::ACTIVE->value); // default: 'inactive'
    ->create('AA-A4C-B1'); // default: null // Custom promo code can be passed // Equivalent to createWithCustomCode('MO-OT2P-897P') method

Promocodes::multiUse() // default: false
    ->boundToUser() // default: false
    ->user(User::find(1)) // default: null
    ->usages(5) // default: 1
    ->expiration(now()->addYear()) // default: null
    ->details([
        'percent_off' => 50,
        'message' => 'This one is for you. I hope you like it',
    ]) // default: []
    ->minOrderValue(500) // default: null
    ->maxDiscount(5) // default: null
    ->createdByAdmin(User::find(1)) // default: null
    ->type(PromocodeType::PERCENT->value) // default: PromocodeType::FLAT->value
    ->status(); // default: 'inactive'
    ->createWithCustomCode('MO-OT2P-897P');
```

### Using helper

[](#using-helper)

There is a global helper function which will do the same as promocodes class. You can use named arguments magic from php 8.1.

```
use NagSamayam\Promocodes\Enums\PromocodeType;
use NagSamayam\Promocodes\Enums\PromocodeStatus;

create_promocodes(
    type: PromocodeType::PERCENT->value, // default: PromocodeType::FLAT->value
    mask: 'AA-***-BB', // default: config('promocodes.code_mask')
    characters: 'ABCDE12345', // default: config('promocodes.allowed_symbols')
    multiUse: true, // default: false
    unlimited: true, // default: false
    boundToUser: true, // default: false
    user: User::find(1), // default: null
    count: 5, // default: 1
    expiration: now()->addYear(), // default: null
    details: ['percent_off' => 50], // default: [],
    createdByAdmin: User::find(98), // default: null
  	maxDiscount: 101, // default: null
  	minOrderValue: 1000, // default: null
    status: PromocodeStatus::ACTIVE->value // default: PromocodeStatus::INACTIVE->value
);

create_custom_promocode(
    code: '66-OMPY-ULZU',
    type: PromocodeType::FLAT->value, // default: PromocodeType::FLAT->value
    multiUse: true, // default: false
    boundToUser: true, // default: false
    user: User::find(1), // default: null
    usages: 5, // default: 1
    expiration: now()->addYear(), // default: null
    details: ['discount' => 50], // default: [],
    createdByAdmin: User::find(98), // default: null
  	maxDiscount: 101, // default: null
  	minOrderValue: 1000 // default: null
    status: PromocodeStatus::ACTIVE->value // default: PromocodeStatus::INACTIVE->value
);
```

### Generating Promocodes

[](#generating-promocodes)

If you want to output promocodes and not save them to database, you can call generate method instead of create.

```
use NagSamayam\Promocodes\Facades\Promocodes;
use NagSamayam\Promocodes\Enums\PromocodeType;
use NagSamayam\Promocodes\Enums\PromocodeStatus;

Promocodes::mask('AA-***-BB') // default: config('promocodes.code_mask')
    ->characters('ABCDE12345') // default: config('promocodes.allowed_symbols')
    ->multiUse() // default: false
    ->unlimited() // default: false
    ->boundToUser() // default: false
    ->user(User::find(1)) // default: null
    ->count(5) // default: 1
    ->expiration(now()->addYear()) // default: null
    ->details(['percent_off' => 50]) // default: []
    ->minOrderValue(500)
    ->maxDiscount(5)
    ->createdByAdmin(User::find(1))
    ->status(PromocodeStatus::ACTIVE->value) // default: PromocodeStatus::INACTIVE->value
    ->type(PromocodeType::PERCENT->value) // default: PromocodeType::FLAT->value
    ->generate();
```

### Applying Promocode

[](#applying-promocode)

### Using class

[](#using-class-1)

Combine methods as you need. You can skip any method that you don't need.

```
use NagSamayam\Promocodes\Facades\Promocodes;

Promocodes::code('ABC-DEF')
    ->user(User::find(1)) // default: null
    ->apply(['order_id' => '405-6828433-4214765']); // default: null // Good to send unique order ID // Preferbly string format
```

### Using helper

[](#using-helper-1)

There is a global helper function which will do the same as promocodes class.

```
apply_promocode(
    'ABC-DEF',
    User::find(1), // default: null,
    ['order_id' => '405-6828433-4214765'] // default: null // Good to send unique order ID // Preferbly string format
);
```

#### Exceptions

[](#exceptions)

While trying to apply promocode, you should be aware of exceptions. Most part of the code throws exceptions, when there is a problem:

```
// NagSamayam\Promocodes\Exceptions\*

PromocodeAlreadyUsedByUserException - "The given code `ABC-DEF` is already used by user with id 1."
PromocodeBoundToOtherUserException - "The given code `ABC-DEF` is bound to other user, not user with id 1."
PromocodeDoesNotExistException - "The given code `ABC-DEF` doesn't exist." | "The code was not event provided."
PromocodeExpiredException - "The given code `ABC-DEF` already expired."
PromocodeNoUsagesLeftException - "The given code `ABC-DEF` has no usages left."
UserHasNoAppliesPromocodeTrait - "The given user model doesn't have AppliesPromocode trait."
UserRequiredToAcceptPromocode - "The given code `ABC-DEF` requires to be used by user, not by guest."
PromocodeAlreadyExistedException - "The given promocode `10s%discount` is already existed. Please try with a new one."
PromocodeAlreadyUsedForOrderException - "The given code `ABC-DEF` is already applied for the order with id 405-6828433-4214765."
PromocodeNotAcitveException - "The given promocode `ABC-DEF` is not active. Please try with a new one."
```

#### Events

[](#events)

There are two events which are fired upon applying.

```
// NagSamayam\Promocodes\Events\*

GuestAppliedPromocode // Fired when guest applies promocode
    // It has public variable: promocode

UserAppliedPromocode // Fired when user applies promocode
    // It has public variable: promocode
    // It has public variable: user
```

### Expiring Promocode

[](#expiring-promocode)

### Using helper

[](#using-helper-2)

There is a global helper function which will expire promocode.

```
expire_promocode('ABC-DEF');
```

### Update Promocode status

[](#update-promocode-status)

### Using class

[](#using-class-2)

```
use NagSamayam\Promocodes\Facades\Promocodes;
use NagSamayam\Promocodes\Enums\PromocodeStatus;

Promocodes::code('ABC-DEF')
    ->updatedByAdmin(User::find(6))
    ->updateStatus(PromocodeStatus::ACTIVE->value);
```

### Using helper

[](#using-helper-3)

```
update_promocode_status('ABC-DEF',
    PromocodeStatus::ACTIVE->value,
    User::find(6)
);
```

Trait Methods
-------------

[](#trait-methods)

If you added AppliesPromocode trait to your user model, you will have some additional methods on user.

```
$user = User::find(1);

$user->appliedPromocodes; // Returns promocodes applied by user
$user->boundPromocodes; // Returns promocodes bound to user
$user->applyPromocode('ABC-DEF', ['order_id' => '405-6828433-4214765']); // Applies promocode to user
```

#### Get applicable discount

[](#get-applicable-discount)

There is a way to get the discount to be applied on total order value.

```
use NagSamayam\Promocodes\Facades\Promocodes;

Promocodes::code('ABC-DEF')
    ->orderTotal(1000) // default: 0
    ->getApplicableDiscount($forceCheck = true); // default: false // If false, it will not check for usagesLeft, status and expiry
```

Testing
-------

[](#testing)

Will be added very soon

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](https://github.com/nagsamayam/laravel-promocodes/blob/master/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Nageswara Rao](https://github.com/nagsamayam)
- [All Contributors](../../contributors)

This package is heavily based on the Laravel Promocodes package from [Zura Gabievi](https://github.com/zgabievi). You can find the code on [GitHub](https://github.com/zgabievi/laravel-promocodes).

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

Note
----

[](#note)

I have developed this package for my personal use. I made this public. Hope it helps you. Please do not expect the immediate bug fixes. Hope you understand.

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity10

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity26

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.

### Community

Maintainers

![](https://www.gravatar.com/avatar/fde76322a3eebc8a2cb1c1caf1a282bd226ed41efe332eff9cce82b6b2e9efcf?d=identicon)[nagsamayam](/maintainers/nagsamayam)

---

Top Contributors

[![nagsamayam](https://avatars.githubusercontent.com/u/3983455?v=4)](https://github.com/nagsamayam "nagsamayam (1 commits)")

---

Tags

couponslaravelpromocodesvouchers

### Embed Badge

![Health badge](/badges/nagsamayam-laravel-promocodes/health.svg)

```
[![Health](https://phpackages.com/badges/nagsamayam-laravel-promocodes/health.svg)](https://phpackages.com/packages/nagsamayam-laravel-promocodes)
```

###  Alternatives

[yahnis-elsts/admin-notices

A utility library for WordPress plugins that makes it easier to create admin notices. Supports persistently dismissible notices.

311.1k](/packages/yahnis-elsts-admin-notices)[jahvi/magento2-copy-theme-override

Magento 2 command to automatically copy files into active theme

124.5k](/packages/jahvi-magento2-copy-theme-override)

PHPackages © 2026

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