NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Coupons for Laravel

Uplatnenie kupónu

Každé uplatnenie ide cez CouponManager, ktorý spúšťa RedeemCouponAction — či už voláte Coupons::code()->redeem(), priame Coupons::redeem(), alebo skratky $coupon->redeemBy() a $user->redeemCoupon(). Akcia overí oprávnenosť, atomicky navýši počet použití, pri zapnutom sledovaní zapíše riadok zákazníka a spustí CouponRedeemed. S kupónom SAVE20 (zľava 20 %) na košík v hodnote 50.00 EUR:

use RoundlyConsulting\Coupons\Facades\Coupons;
use RoundlyConsulting\Money\Money;

$result = Coupons::code('SAVE20')->redeem(Money::ofMinor(5000, 'EUR'), $user);

$result->coupon;        // the refreshed Coupon, usage already incremented
$result->discount;      // Money 10.00 EUR — never more than the price
$result->total;         // Money 40.00 EUR — the new total after the discount
$result->redeemer;      // the redeemer you passed, or null
$result->freeShipping;  // true for a free-shipping coupon — zero your own shipping line

// The flat form of the same call:
$result = Coupons::redeem('SAVE20', Money::ofMinor(5000, 'EUR'), redeemer: $user);

// Model shorthand — sugar over the same manager (redeemer may be null for guest checkout):
$result = $coupon->redeemBy($user, Money::ofMinor(5000, 'EUR'));

Čo sa pri uplatnení deje

  • Nájde kupón podľa modelu alebo kódu bez ohľadu na veľkosť písmen. Neznámy alebo prázdny kód spustí CouponRedemptionFailed a vyhodí CouponNotFound.
  • Otvorí transakciu na vlastnom spojení modelu kupónu a riadok kupónu znovu načíta cez lockForUpdate(), takže súbežné uplatnenia nikdy neprekročia max_usage — ani keď coupons.model používa iné ako predvolené spojenie. Soft-deleted Coupon sa tu nenájde a vyhodí CouponNotFound.
  • Spustí kontroly oprávnenosti v pevnom poradí a pri prvom zlyhaní vyhodí výnimku.
  • Vypočíta zľavu cez discountFor() a celkovú sumu ako cenu mínus zľavu.
  • Navýši usage relatívnym zápisom a obnoví model.
  • Zapíše riadok coupon_redemptions — len ak je zadaný zákazník a coupons.redeemer.track je zapnuté. Uplatnenia bez zákazníka sa rátajú len do celkového limitu.
  • Spustí CouponRedeemed a navyše CouponExhausted presne raz — pri uplatnení, ktoré dotiahne usage na kladný max_usage —, obe až po potvrdení vonkajšej transakcie.

Poradie kontrol

Kontroly bežia vždy v rovnakom poradí, takže zákazník dostane vždy rovnakú odpoveď:

#RedemptionFailureReasonVýnimkaVýznam
1NotFoundCouponNotFoundNeznámy alebo prázdny kód, prípadne soft-deleted inštancia Coupon.
2CurrencyMismatchCurrencyMismatchKupón je uzamknutý na inú menu, než je mena ceny.
3MinimumSpendNotMetMinimumSpendNotMetCena je pod minimálnou hodnotou nákupu kupónu.
4ExpiredCouponExpiredEšte nie je aktívny alebo mu uplynula platnosť.
5AtMaxUsageCouponAtMaxUsageCelkový limit použití je vyčerpaný.
6AlreadyRedeemedCouponAlreadyRedeemedLimit na zákazníka je vyčerpaný — kontroluje sa len pri zadanom zákazníkovi.

redeem() pri zlyhaní vždy vyhodí výnimku — uplatnenie bez výnimky neexistuje. Ak sa chcete najprv opýtať, Coupons::check() vráti prvý neúspešný RedemptionFailureReason alebo null bez výnimky, zamykania či zápisu; isRedeemableBy() a pravidlo Redeemable spúšťajú rovnaké kontroly.

Spracovanie zlyhaní

Každé zlyhanie je presná výnimka, ktorú môžete zachytiť. Všetky okrem CouponNotFound dedia z CouponNotRedeemable; obe dedia z CouponException:

use RoundlyConsulting\Coupons\Exceptions\{CouponNotFound, CouponExpired, CouponAtMaxUsage,
    CouponAlreadyRedeemed, MinimumSpendNotMet, CurrencyMismatch};

try {
    $result = Coupons::redeem($code, $price, redeemer: $user);
} catch (CouponNotFound) {          // unknown code
} catch (CouponExpired) {           // not active / past expiry
} catch (CouponAtMaxUsage) {        // global cap reached
} catch (CouponAlreadyRedeemed) {   // per-redeemer cap reached
} catch (MinimumSpendNotMet) {      // price below the coupon's minimum
} catch (CurrencyMismatch) {        // coupon locked to another currency
}

Alebo zachyťte naraz oba základné typy:

use RoundlyConsulting\Coupons\Exceptions\CouponNotFound;
use RoundlyConsulting\Coupons\Exceptions\CouponNotRedeemable;

try {
    $result = Coupons::redeem((string) $request->input('code'), $cartTotal, $request->user());
} catch (CouponNotFound|CouponNotRedeemable $e) {
    return back()->withErrors(['code' => $e->getMessage()]);
}

Doprava zadarmo

Balík nespravuje košík ani riadok dopravy, takže kupón na dopravu zadarmo z ceny tovaru nič neodpočíta — discount je nula a total sa rovná cene. Vlastnú dopravu vynulujte, keď je $result->freeShipping (alebo $coupon->appliesToShipping()) true:

use RoundlyConsulting\Money\Money;

$result = Coupons::redeem('SHIPFREE', $cartTotal, redeemer: $user);

$result->discount;   // zero — the goods price is untouched
$result->total;      // equals $cartTotal

if ($result->freeShipping) {
    $shipping = Money::zero($shipping->currency());   // zero your own shipping line
}

Priame volanie akcie

To isté uplatnenie bez fasády aj manažéra — pozrite si DI a akcie:

use RoundlyConsulting\Coupons\Actions\RedeemCouponAction;
use RoundlyConsulting\Coupons\DataTransferObjects\RedeemCouponData;

$result = app(RedeemCouponAction::class)->execute(
    new RedeemCouponData(coupon: 'SAVE20', price: $cartTotal, redeemer: $user),
);

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.