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
Requires
- php: ^8.2
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0
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\DiscountAssignedPhpAjaxExperts\UserDiscounts\Events\DiscountRevokedPhpAjaxExperts\UserDiscounts\Events\DiscountApplied
Testing
composer test
License
The MIT License (MIT). Please see License File for more information.