Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Otp Laravel Package

ichtrojan/laravel-otp

A lightweight Laravel package for generating, storing, and verifying one-time passwords (OTPs). It provides configurable code length and expiry, simple validation helpers, and database-backed storage, making it easy to add OTP-based verification to Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require the package at ^2.0, then publish its config and migrations (php artisan vendor:publish), and run php artisan migrate — OTP packages typically need a table to track issued tokens and expiry.
  • Look first at config/otp.php (or similarly named). In v2.0.0 this is where you choose numeric vs. alphanumeric tokens; confirm the default before writing any tests, since the shape of a generated token changed for anyone opting into alphanumeric.
  • Read the service class, not a facade. v2.0.0 abolishes facades entirely, so your first integration point is the underlying service resolved from the container. Do not port Otp::generate() snippets from v1 tutorials.
  • First use case: issue a token, deliver it out-of-band (mail/SMS), then validate the user's input.
use App\Services\OtpGate; // your thin wrapper, or inject the package service directly

public function send(OtpGate $otp)
{
    $token = $otp->generate($user->phone);   // numeric by default, alphanumeric if configured
    // send via notification / SMS driver
}
  • Run php artisan otp:clean once manually before wiring it into the scheduler — v2.0.0 improved its output, so you can see exactly what it pruned and confirm your expiry config is sane.

Implementation Patterns

Constructor injection over facades. Since facades are gone, inject the service into controllers, form requests, jobs, and notification classes. This is the single biggest day-to-day change from v1: every call site needs a dependency, not a static alias resolved from config/app.php.

Validate inside a Form Request. The refactored validate() is the natural home for verification logic. Call it from rules() or withValidator() so failed OTPs surface as normal validation errors rather than exceptions bubbling out of a controller.

public function rules(OtpService $otp): array
{
    return [
        'code' => [
            'required',
            function ($attribute, $value, $fail) use ($otp) {
                if (! $otp->validate($this->input('phone'), $value)) {
                    $fail('That code is invalid or has expired.');
                }
            },
        ],
    ];
}

Wrap it in your own abstraction. Because the public API just changed across a major version (validate() refactor + facade removal), put a small OtpGate interface in app/ and bind the package to it. Future majors then touch one file instead of every controller.

Alphanumeric tokens need a normalisation step. If you enable alphanumeric generation, decide on case handling at the boundary — uppercase on generate, uppercase the user input before validating — otherwise support tickets about "the code doesn't work" will be caused by autocapitalise on mobile keyboards.

Schedule cleanup. Register otp:clean in routes/console.php or the scheduler (e.g. hourly). With v2.0.0's improved reporting, pipe the output to your log channel in staging for a week to confirm the retention window matches your token TTL.

Delivery stays your responsibility. The package generates and validates; sending is yours. Fire the token through a queued notification so a slow SMS gateway doesn't hold the HTTP request, and never persist the plaintext token in your own tables.

Gotchas and Tips

  • The facade removal is the breaking change. Any Otp:: call, any alias in config/app.php, and any test using Otp::shouldReceive(...) will fail. Grep your codebase for the facade alias before upgrading; static analysis will not catch string-based container lookups.
  • validate() changed shape. Don't assume the v1 return contract. Check whether the refactored method returns a bool, throws, or consumes the token as a side effect — and write one test asserting a second call with the same code behaves the way you expect (single-use vs. reusable).
  • Alphanumeric is opt-in via config, not per-call in most implementations. If you need mixed token types in one app, verify whether the generator accepts an argument; if not, isolate the two flows behind separate config or service instances.
  • Config caching bites after publish. php artisan config:clear after editing token length/expiry, or your otp:clean retention window and generation format will silently stay on old values in local dev.
  • otp:clean is destructive. Confirm the retention window covers your longest TTL plus any grace period, and avoid running it against production without first running it in a lower environment to read the new v2.0.0 output.
  • Debugging invalid-token reports: log the generation timestamp and the token hash/ID, never the code itself. Most "expired code" reports are clock skew, a user requesting a second code (invalidating the first), or a case-sensitivity mismatch on alphanumeric tokens.
  • Testing: bind a fake implementation of your OtpGate interface in the container during tests rather than hitting the real service; facades are gone, so Facade::fake() patterns from v1 examples are dead ends.
  • Extension point: if the package exposes a driver/repository contract for token storage, prefer swapping in a cache-backed store for high-volume flows over the default database table — but validate that otp:clean still reconciles whatever store you choose.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource