PHP code example of binafy / laravel-discount

1. Go to this page and download the library: Download binafy/laravel-discount library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

binafy / laravel-discount example snippets


use Binafy\LaravelDiscount\Enums\DiscountType;

Schema::table('discounts', function (Blueprint $table) {
    $table->enum('type', DiscountType::values())->default(DiscountType::Percentage->value)->change();
    $table->decimal('value', 10, 2)->default(0)->change();
});

use Binafy\LaravelDiscount\Enums\DiscountType;
use Binafy\LaravelDiscount\Models\Discount;

$discount = Discount::query()->create([
    'name' => 'Summer Sale',
    'type' => DiscountType::Percentage,
    'value' => 20, // 20%
]);

$discount = Discount::query()->create([
    'name' => 'Ten dollars off',
    'type' => DiscountType::Fixed,
    'value' => 10, // deducts 10 from the total
]);

$discount = Discount::query()->create([
    'code' => 'SAVE20',
    'type' => DiscountType::Percentage,
    'value' => 20,
    'max_discount_amount' => 100,
]);

LaravelDiscount::apply($discount, 300)->discountAmount;  // 60.0  (20% of 300)
LaravelDiscount::apply($discount, 1000)->discountAmount; // 100.0 (capped)

$discount = Discount::query()->create([
    'code' => 'EURO10',
    'type' => DiscountType::Fixed,
    'value' => 10,
    'currency' => 'EUR', // ISO 4217, stored upper case
]);

LaravelDiscount::applyCode('EURO10', 50, $user, payload: ['currency' => 'EUR']); // OK
LaravelDiscount::applyCode('EURO10', 50, $user, payload: ['currency' => 'USD']);
// throws DiscountCurrencyMismatchException: "This discount is only available for orders in EUR."

// config/laravel-discount.php
'currency' => env('DISCOUNT_CURRENCY'), // e.g. DISCOUNT_CURRENCY=EUR

Discount::query()->valid()->forCurrency('EUR')->get();

$discount = Discount::query()->create([
    'name' => 'Buy 2 get 1 free',
    'code' => 'BUY2GET1',
    'type' => DiscountType::BuyXGetY,
    'conditions' => ['buy' => 2, 'get' => 1],
]);

// 3 items at 100 each: the third one is free.
LaravelDiscount::apply($discount, 300, quantity: 3)->discountAmount; // 100.0

// 6 items at 50 each: two full sets, so two items are free.
LaravelDiscount::apply($discount, 300, quantity: 6)->discountAmount; // 100.0

// Below a full set, nothing applies.
LaravelDiscount::apply($discount, 200, quantity: 2)->discountAmount; // 0.0

// Buy 2, get the third at 50% off, at most 2 discounted items per order.
'conditions' => ['buy' => 2, 'get' => 1, 'get_discount_percentage' => 50, 'max_free_items' => 2],

$discount = Discount::query()->create([
    'name' => 'Spend more, save more',
    'type' => DiscountType::Tiered,
    'conditions' => ['tiers' => [
        ['min' => 1_000_000, 'value' => 5],  // over 1,000,000 → 5%
        ['min' => 5_000_000, 'value' => 10], // over 5,000,000 → 10%
    ]],
]);

LaravelDiscount::apply($discount, 900_000)->discountAmount;   // 0.0      (below every tier)
LaravelDiscount::apply($discount, 2_000_000)->discountAmount; // 100_000.0 (5%)
LaravelDiscount::apply($discount, 6_000_000)->discountAmount; // 600_000.0 (10%)

'conditions' => ['tiers' => [
    ['min' => 1_000_000, 'value' => 50_000, 'type' => 'fixed'],
    ['min' => 5_000_000, 'value' => 400_000, 'type' => 'fixed'],
]],

LaravelDiscount::matchingTier($discount, 6_000_000); // ['min' => 5000000, 'value' => 10]

$discount = Discount::query()->create([
    'name' => 'Free shipping',
    'code' => 'FREESHIP',
    'type' => DiscountType::FreeShipping,
]);

$result = LaravelDiscount::applyCode('FREESHIP', 500);

$result->discountAmount;        // 0.0
$result->payableAmount();       // 500.0
$result->hasFreeShipping();     // true
$result->payableShipping(35);   // 0.0   (35 when shipping is not free)
$result->payableTotal(35);      // 500.0 (535 when shipping is not free)

$result = LaravelDiscount::applyMany([$freeShipping, $twentyPercent], 500);

$result->discountAmount;    // 100.0 (the 20%)
$result->hasFreeShipping(); // true

Discount::query()->create([
    'code' => 'SHIP-OVER-1000',
    'type' => DiscountType::FreeShipping,
    'min_order_value' => 1000,
]);

use Binafy\LaravelDiscount\Facades\LaravelDiscount;

$result = LaravelDiscount::apply($discount, 200);

$result->originalAmount;    // 200.0
$result->discountAmount;    // 40.0
$result->payableAmount();   // 160.0
$result->discounts;         // Collection of the applied discounts
$result->hasFreeShipping(); // false — see Free Shipping

LaravelDiscount::isValid($discount, orderAmount: 200, user: $user); // true|false

$discount = Discount::query()->create([
    'code' => 'WELCOME10',
    'type' => DiscountType::Percentage,
    'value' => 10,
]);

LaravelDiscount::generateCode();              // "8FJ2K9QW"
LaravelDiscount::generateCode('SUMMER');      // "SUMMER-8FJ2K9QW"
LaravelDiscount::generateCodes(100, 'VIP');   // Collection of 100 unique codes

$result = LaravelDiscount::applyCode('WELCOME10', 200, $user);

$discount = LaravelDiscount::findByCode('WELCOME10');

$discount = Discount::query()->create([
    'code' => 'BLACK-FRIDAY',
    'type' => DiscountType::Percentage,
    'value' => 30,
    'starts_at' => now()->startOfDay(),
    'expires_at' => now()->addDays(3),
]);

Discount::query()->valid()->get();

$discount = Discount::query()->create([
    'code' => 'FIRST-100',
    'type' => DiscountType::Fixed,
    'value' => 15,
    'usage_limit' => 100,        // first 100 redemptions only
    'usage_limit_per_user' => 1, // once per user
]);

LaravelDiscount::redeem($discount, $user, $result->discountAmount);

$result = LaravelDiscount::applyCode('GUEST10', $total, sessionId: session()->getId());

LaravelDiscount::redeem($discount, amount: $result->discountAmount, sessionId: session()->getId());

$discount = Discount::query()->create([
    'code' => 'BIG-SPENDER',
    'type' => DiscountType::Percentage,
    'value' => 15,
    'min_order_value' => 500,
]);

LaravelDiscount::applyCode('BIG-SPENDER', 300); // throws MinimumOrderValueException
LaravelDiscount::applyCode('BIG-SPENDER', 800); // OK

use Binafy\LaravelDiscount\Traits\HasDiscounts;

class Product extends Model
{
    use HasDiscounts;
}

// Attach and query
$product->discounts()->attach($discount);
$product->validDiscounts();       // only the currently applicable ones
$product->hasDiscount('TECH10');  // by code or by model instance

// Apply all attached valid discounts to a price (stacking rules 

$discount = Discount::query()->create([
    'code' => 'WELCOME10',
    'type' => DiscountType::Percentage,
    'value' => 10,
    'conditions' => ['rules' => [
        ['type' => 'first_purchase'],
        ['type' => 'minimum_item_count', 'count' => 2],
    ]],
]);

LaravelDiscount::apply($discount, 500, $user, quantity: 1);
// throws DiscountConditionFailedException: "This discount 

$result = LaravelDiscount::apply(
    $discount,
    $order->total,
    $user,
    quantity: $order->items->sum('quantity'),
    payload: ['items' => $order->items->pluck('product')],
);

use Binafy\LaravelDiscount\Exceptions\DiscountConditionFailedException;

try {
    $result = LaravelDiscount::applyCode($code, $total, $user, quantity: $count, payload: ['items' => $items]);
} catch (DiscountConditionFailedException $e) {
    return back()->withErrors($e->getMessage()); // e.g. "This discount is only available on your first purchase."
}

LaravelDiscount::conditions($discount); // Collection<DiscountCondition>

'conditions' => ['rules' => [
    ['type' => 'category', 'categories' => [7, 9]],              // any item in 7 or 9
    ['type' => 'category', 'categories' => [7], 'match' => 'all'], // every item in 7
]],

// config/laravel-discount.php
'conditions' => [
    'first_purchase' => [
        'model' => \App\Models\Order::class,
        'column' => 'user_id',
    ],
],

'conditions' => ['rules' => [
    ['type' => 'first_purchase'],
    // or override the model for this rule only:
    ['type' => 'first_purchase', 'model' => \App\Models\Subscription::class, 'column' => 'user_id'],
]],

// in a service provider
use Binafy\LaravelDiscount\Conditions\FirstPurchaseCondition;
use Binafy\LaravelDiscount\Support\DiscountContext;

FirstPurchaseCondition::countUsing(fn (DiscountContext $context) => Order::query()
    ->where('user_id', $context->userId())
    ->where('status', OrderStatus::Paid)
    ->count());

class CountPaidOrders
{
    public function __invoke(DiscountContext $context): int
    {
        return Order::query()->where('user_id', $context->userId())->paid()->count();
    }
}

// config/laravel-discount.php
'conditions' => ['first_purchase' => ['count_using' => \App\Discounts\CountPaidOrders::class]],

'conditions' => ['rules' => [
    ['type' => 'first_purchase', 'count_using' => \App\Discounts\CountPaidOrders::class],
]],

'conditions' => ['rules' => [['type' => 'minimum_item_count', 'count' => 3]]],

'conditions' => [
    'rules_match' => 'any',
    'rules' => [
        ['type' => 'category', 'categories' => [7]],
        ['type' => 'minimum_item_count', 'count' => 5],
    ],
],

'conditions' => [
    'tiers' => [['min' => 1_000_000, 'value' => 5]],
    'rules' => [['type' => 'first_purchase']],
],

use Binafy\LaravelDiscount\Contracts\DiscountCondition;
use Binafy\LaravelDiscount\Support\DiscountContext;

class WeekendOnlyCondition implements DiscountCondition
{
    public function __construct(protected array $days = ['Saturday', 'Sunday']) {}

    public static function fromArray(array $config): static
    {
        return new static($config['days'] ?? ['Saturday', 'Sunday']);
    }

    public function passes(DiscountContext $context): bool
    {
        return in_array(now()->englishDayOfWeek, $this->days);
    }

    public function message(): string
    {
        return 'This discount only runs at the weekend.';
    }
}

// config/laravel-discount.php
'conditions' => [
    'aliases' => [
        'weekend_only' => \App\Discounts\WeekendOnlyCondition::class,
    ],
],

// or at runtime, e.g. in a service provider
use Binafy\LaravelDiscount\Support\ConditionFactory;

ConditionFactory::register('weekend_only', WeekendOnlyCondition::class);

'conditions' => ['rules' => [['type' => 'weekend_only', 'days' => ['Friday']]]],

$context->discount;    // the Discount being validated
$context->amount;      // the order amount
$context->user;        // the user model or id, may be null
$context->userId();    // the id, or null for a guest
$context->sessionId;   // the guest session, may be null
$context->quantity;    // how many items the amount covers
$context->items();     // Collection of the payload's items
$context->get('key');  // any other payload value, dot notation supported

$result = LaravelDiscount::applyMany([$tenPercent, $tenFixed, $bigSolo], 100);

$result->discounts;       // the discounts that were actually applied
$result->discountAmount;  // the winning total

use Binafy\LaravelDiscount\Rules\ValidDiscountCode;

public function rules(): array
{
    return [
        'code' => ['

'code' => ['

'code' => ['ount: $this->cartTotal(),
    user: $this->user(),
    quantity: $this->cart()->items->sum('quantity'),
    payload: ['items' => $this->cart()->items->pluck('product')],
)],

use Binafy\LaravelDiscount\Exceptions\DiscountException;
use Binafy\LaravelDiscount\Exceptions\DiscountExpiredException;

try {
    $result = LaravelDiscount::applyCode($code, $total, $user);
} catch (DiscountExpiredException $e) {
    return back()->withErrors("Code {$e->getDiscount()->code} has expired.");
} catch (DiscountException $e) {
    return back()->withErrors($e->getMessage());
}

use Binafy\LaravelDiscount\Events\DiscountRedeemed;

Event::listen(DiscountRedeemed::class, function (DiscountRedeemed $event) {
    // $event->discount, $event->usage
});

use Binafy\LaravelDiscount\Integrations\LaravelCart\CartDiscount;

$cartDiscount = app(CartDiscount::class);

// Apply a code (or discount models) to the whole cart total
$result = $cartDiscount->applyToCart($cart, 'SUMMER-8FJ2K9QW');
$result->payableAmount();

// Apply a discount to a specific cart item (price × quantity)
$result = $cartDiscount->applyToItem($cartItem, $discount);

// Automatically apply the discounts attached to each item's model
// (via the HasDiscounts trait) across the whole cart
$result = $cartDiscount->applyItemDiscounts($cart);

$result = $cartDiscount->applyItemDiscounts($cart);

$result->hasFreeShipping();  // true when any item's discount grants it
$result->payableTotal(35);   // the cart total plus the shipping still due

Schedule::command('discount:prune --days=30')->daily();
bash
php artisan migrate
bash
php artisan vendor:publish --tag="laravel-discount-config"
bash
php artisan vendor:publish --tag="laravel-discount-migrations"
bash
php artisan discount:generate                    # one code
php artisan discount:generate 100 --prefix=VIP  # 100 codes like VIP-8FJ2K9QW
bash
php artisan discount:prune            # everything already expired
php artisan discount:prune --days=30  # only discounts expired 30+ days ago