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.

Access Pass Valid

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.

Verified with automated tests across PHP 8.2–8.4 and Laravel 10–13
// 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