composer require mustafa-azmi/laravel-checkin
Every check-in
is a signed
little document.
A Laravel package that turns any Eloquent model into something people can be issued a pass for — and checked into, once, safely, without you writing the hashing, locking, or expiry logic yourself.
Laravel Meetup
Riyadh · General Admission
TOKEN
a1f9…c204e7b8
EXPIRES IN
9:47
What you get
Every feature the package ships with.
HMAC-hashed tokens
The raw token is shown to you once and never stored. Only its HMAC hash lives in the database — a full DB leak can't be used to forge or replay a check-in.
Race-condition safe
The Redemption runs inside a locked database transaction. Two people scanning the same single-use code at the same instant — only one ever succeeds.
Configurable expiry
Every token carries its own expiry. Set a global default in config, or override it per-token when you generate one.
Single-use or reusable
Same package, two patterns: a one-time event ticket, or a reusable gym-door pass that works every visit until it expires. Configurable per token.
Attaches to any model
One polymorphic table, one trait — use HasCheckins —
and any Eloquent model becomes
checkinable. Event, ClassSession, GymVisit, whatever you have.
Three specific exceptions
TokenNotFoundException,
TokenExpiredException, TokenAlreadyUsedException — handle each outcome differently instead
of parsing a message string.
Preview without consuming
validate()
runs every check redemption does, but doesn't mark the token used — good for a confirmation screen
before staff commit.
Arbitrary metadata
Attach any array to a token when generating it — attendee name, gate number, device ID — and read it back at redemption time.
QR-renderer agnostic
The package hands you a signed payload string. Render it with any QR library, a barcode, or don't — send it as a link. Your choice, not a bundled dependency.
Two calls
Issue a pass. Redeem a pass.
That's the entire mental model. Everything else — the hashing, the locking, the expiry math — happens inside those two calls so you don't have to think about it.
// Issue
$pass = $event->generateCheckinToken(
user: $attendee
);
// Redeem, at the door
$token = Checkin::redeem($scanned);
See every state, not just the docs.
Create an event, issue a real pass, and redeem it at the desk — including the expired, duplicate, and invalid states.
Create your first event