phpajaxexperts/user-discounts

A reusable Laravel package for user-level discounts.

Installs: 1

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/phpajaxexperts/user-discounts

v1.0.0 2025-12-11 12:57 UTC

This package is auto-updated.

Last update: 2025-12-11 14:27:37 UTC


README

A robust, reusable Laravel package for managing user-level discounts with deterministic stacking, usage caps, and audit logging.

Features

  • Flexible Discount Types: Percentage and fixed amount discounts.
  • Deterministic Stacking: Control the order in which discounts are applied (e.g., highest value first).
  • Usage Limits: Global and per-user usage caps.
  • Time-bound: Start and expiration dates.
  • Audit Logging: Tracks assignment, revocation, and application of discounts.
  • Concurrency Safe: Atomic operations to prevent race conditions.
  • Events: Dispatches events for easy integration with other systems.

Installation

You can install the package via composer:

composer require phpajaxexperts/user-discounts

Configuration

Publish the configuration file to customize stacking order, rounding, and caps:

php artisan vendor:publish --tag=user-discounts-config

Config Options:

  • stacking_order: 'highest_value', 'lowest_value', 'created_asc', 'created_desc'
  • max_percentage_cap: Maximum total percentage discount allowed (0-100)
  • rounding: Decimal places for rounding calculations

Database Migrations

Run the migrations to create the necessary tables:

php artisan migrate

Usage

Injecting the Service

use PhpAjaxExperts\UserDiscounts\DiscountService;

public function checkout(DiscountService $discountService)
{
    // ...
}

Creating a Discount

use PhpAjaxExperts\UserDiscounts\Models\Discount;

$discount = Discount::create([
    'name' => 'Welcome Offer',
    'code' => 'WELCOME10',
    'type' => 'percentage', // or 'fixed'
    'value' => 10,
    'active' => true,
    'starts_at' => now(),
    'expires_at' => now()->addDays(30),
    'usage_limit' => 1000, // Global limit
    'usage_limit_per_user' => 1, // Per user limit
]);

Assigning a Discount

$discountService->assign($user, $discount);

Checking Eligibility

if ($discountService->eligibleFor($user, $discount)) {
    // User can use this discount
}

Applying Discounts

This method calculates the final amount after applying all eligible discounts assigned to the user, respecting the stacking order and limits.

$result = $discountService->apply($user, $originalAmount);

// $result structure:
// [
//     'original_amount' => 100.00,
//     'final_amount' => 90.00,
//     'applied_discounts' => [
//         ['discount' => $discountModel, 'amount' => 10.00],
//         ...
//     ]
// ]

Revoking a Discount

$discountService->revoke($user, $discount);

Events

The package dispatches the following events:

  • PhpAjaxExperts\UserDiscounts\Events\DiscountAssigned
  • PhpAjaxExperts\UserDiscounts\Events\DiscountRevoked
  • PhpAjaxExperts\UserDiscounts\Events\DiscountApplied

Testing

composer test

License

The MIT License (MIT). Please see License File for more information.