Artisan commands
# Immediately expire coupons (admin kill-switch) — Coupons::expireAll(). --code limits it to
# one coupon. Each one is revoked like Coupons::revoke(): CouponRevoked fires per coupon.
php artisan coupons:expire
php artisan coupons:expire --code=SAVE20
# Prune coupons expired more than N days ago — Coupons::prune(). Soft deletes (the code is free
# to issue again, the history stays); --force deletes permanently, including coupons an earlier
# prune soft-deleted. A --days that is negative or not a whole number (thirty, 1.5) is refused.
php artisan coupons:prune --days=30
php artisan coupons:prune --days=30 --force| Signature | What it does |
|---|---|
coupons:expire {--code=} | Admin kill-switch, runs Coupons::expireAll(): revokes every live coupon (or only --code) — expires_at = now and one CouponRevoked per coupon. Prints the count. |
coupons:prune {--days=30} {--force} | Runs Coupons::prune(): soft-deletes coupons whose expires_at is at least --days days old — the code is free to issue again, the history stays; --force deletes them permanently, including ones an earlier prune trashed. A --days that is negative or not a whole number (thirty, 1.5) fails the command. |
Each command is one manager call, so the same work runs from code — and under Coupons::fake() it’s recorded instead of performed:
use RoundlyConsulting\Coupons\Facades\Coupons;
Coupons::expireAll(); // what coupons:expire runs; returns the count
Coupons::expireAll(code: 'SAVE20'); // coupons:expire --code=SAVE20
Coupons::prune(days: 30); // coupons:prune --days=30
Coupons::prune(days: 30, force: true); // coupons:prune --days=30 --forceBoth work in chunks of 100 and query the model configured in coupons.model, so a subclass’s model events and overrides run for every coupon they touch.
Scheduling
Run the prune command on Laravel’s scheduler:
// routes/console.php
use Illuminate\Support\Facades\Schedule;
Schedule::command('coupons:prune --days=90')->weekly();Pruned coupons are soft-deleted and keep their redemption history, and their codes are free to issue again. With --force the rows are deleted permanently, and the foreign key cascades the delete to their coupon_redemptions rows.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.