PHPackages                             asgarihope/pretty-otp - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. asgarihope/pretty-otp

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

asgarihope/pretty-otp
=====================

V1.0.0(1y ago)34MITPHPPHP &gt;=7.2

Since Dec 21Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/asgarihope/pretty-otp)[ Packagist](https://packagist.org/packages/asgarihope/pretty-otp)[ RSS](/packages/asgarihope-pretty-otp/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (4)Versions (2)Used By (0)

PrettyOtp Laravel Package
=========================

[](#prettyotp-laravel-package)

PrettyOtp is a Laravel package designed to simplify the implementation of OTP (One-Time Password) mechanisms for authentication and other secure actions.

Requirements
------------

[](#requirements)

- **PHP** &gt;= 8.2
- **Laravel** 6.x – 13.x

The package is tested against Laravel 6 through 13. Laravel 11+ requires PHP 8.2+, which is the minimum PHP version for this package.

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require asgarihope/pretty-otp
```

The service provider (`PrettyOtp\Laravel\Providers\PrettyOtpServiceProvider`) is auto-discovered by Laravel. If you have disabled package discovery, register it manually in `config/app.php` (Laravel 10 and below) under `providers`.

Configuration
-------------

[](#configuration)

Publish the package configuration file:

```
php artisan vendor:publish --tag=otp-config
```

This will create a configuration file at `config/otp.php`:

```
return [
    'otp_expiry'     => 5,  // OTP validity time in minutes
    'otp_attempts'   => 5,  // Maximum allowed validation attempts per OTP
    'otp_length'     => 6,  // Number of digits in the generated OTP
    'otp_retry_time' => 2,  // Cooldown (in minutes) before a new OTP can be requested
];
```

KeyDescription`otp_expiry`How long (in minutes) a generated OTP stays valid.`otp_attempts`Maximum number of failed validation attempts before the user is locked out and must request a new OTP.`otp_length`The number of digits used when generating the OTP.`otp_retry_time`Minimum wait time (in minutes) between two OTP requests for the same segment/mobile.Middleware
----------

[](#middleware)

The package provides an `otp` middleware alias backed by `OtpMiddleware` to secure routes.

### Example Usage

[](#example-usage)

In your `routes/web.php` or `routes/api.php`, apply the middleware:

```
use Illuminate\Support\Facades\Route;

Route::middleware(['otp:mobile,login'])->group(function () {
    Route::post('/secure-action', [SecureController::class, 'handle']);
});
```

### Middleware Parameters

[](#middleware-parameters)

The middleware accepts up to three comma-separated parameters: `otp:key,segment,lifetimeInHours`

- `key` *(required)*: The request input name that holds the identifier (e.g. `mobile`).
- `segment` *(required)*: A string identifying the OTP usage context (e.g. `login`, `reset-password`).
- `lifetimeInHours` *(optional)*: How many hours access is granted after a successful validation. When omitted (or `null`), access is granted indefinitely until explicitly revoked.

```
// Access granted for 3 hours after a valid OTP
Route::middleware(['otp:mobile,login,3'])->post('/secure-action', ...);
```

### Response Metadata

[](#response-metadata)

When the middleware short-circuits (OTP required, invalid, locked, etc.), it returns a JSON response that includes two helpful fields alongside the message/error:

```
{
    "message": "OTP sent to 0912xxxxxxx. Please verify.",
    "time_remain": 120,
    "remain_attempt": 5
}
```

- `time_remain`: seconds left before a new OTP can be requested.
- `remain_attempt`: remaining validation attempts for the current OTP.

Events and Listeners
--------------------

[](#events-and-listeners)

The package dispatches an `OtpRequested` event whenever an OTP is requested. Listen to this event to define your custom delivery logic (SMS, email, etc.).

### OtpRequested Event

[](#otprequested-event)

#### Event Properties

[](#event-properties)

- `$mobile`: The identifier (e.g. mobile number) for which the OTP is requested.
- `$key`: The request parameter key used for the identifier.
- `$segment`: The OTP usage context.

### Implementing a Listener

[](#implementing-a-listener)

The package ships an abstract `SendOtpListener` that already generates the OTP (via `OtpService`) and builds the message. You only need to implement the `sendNotification` method:

```
namespace App\Listeners;

use PrettyOtp\Laravel\Listeners\SendOtpListener;

class MyOtpListener extends SendOtpListener
{
    public function sendNotification(string $key, string $inputValue, string $message): void
    {
        // Send $message to $inputValue via your SMS/email provider.
        SmsGateway::send($inputValue, $message);
    }
}
```

> **Note:** `SendOtpListener::handle()` calls `OtpService::generateOtp()`, which both stores the OTP in cache and records its sent-at timestamp. You should not generate or store the OTP yourself.

If you want to use your own listener instead, register it for `PrettyOtp\Laravel\Events\OtpRequested` in your `EventServiceProvider` and call `$otpService->generateOtp($event->mobile, $event->segment)` inside it.

Service Provider
----------------

[](#service-provider)

The `PrettyOtpServiceProvider` automatically:

- Registers the `otp` middleware alias.
- Registers the `OtpRequested` → `SendOtpListener` binding.
- Merges the default `otp` config.
- Publishes the configuration and translation files.

Translation
-----------

[](#translation)

Package translations are registered under the `pretty-otp` namespace and work **out of the box** without publishing. The middleware uses keys like `trans('pretty-otp::otp.invalid_otp')`.

To customize the messages, publish the translations:

```
php artisan vendor:publish --tag=otp-translations
```

Published files land in `lang/vendor/pretty-otp//otp.php` (or `resources/lang/vendor/pretty-otp/...` on older Laravel versions) and override the package defaults.

Available locales: `en`, `fa`.

Example Flow
------------

[](#example-flow)

1. **Request OTP** — A request to a protected route without a valid `otp` input triggers the `OtpRequested` event. The configured listener generates and delivers the OTP.
2. **Validate OTP** — The client sends the same request again, now including the `otp` input. The middleware validates it and grants access on success.
3. **Access Grant** — On success, access is granted for the configured `lifetimeInHours` (or indefinitely when omitted). Subsequent requests within the lifetime skip OTP validation.

### Cache Storage

[](#cache-storage)

The package uses Laravel's cache to store OTPs, attempt counters, sent-at timestamps, and access grants. Configure your preferred cache driver in `config/cache.php`.

Contribution
------------

[](#contribution)

Contributions are welcome! Feel free to submit a pull request or report issues in the repository.

License
-------

[](#license)

This package is open-sourced software licensed under the [MIT license](LICENSE).

###  Health Score

29

—

LowBetter than 57% of packages

Maintenance65

Regular maintenance activity

Popularity7

Limited adoption so far

Community4

Small or concentrated contributor base

Maturity34

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

604d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/148297745?v=4)[Omid Asgari](/maintainers/asgarihope)[@asgarihope](https://github.com/asgarihope)

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/asgarihope-pretty-otp/health.svg)

```
[![Health](https://phpackages.com/badges/asgarihope-pretty-otp/health.svg)](https://phpackages.com/packages/asgarihope-pretty-otp)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.4M354](/packages/psalm-plugin-laravel)[illuminate/view

The Illuminate View package.

13047.7M2.5k](/packages/illuminate-view)[api-platform/laravel

API Platform support for Laravel

58190.1k21](/packages/api-platform-laravel)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45844.8k1](/packages/pressbooks-pressbooks)[rapidez/core

Rapidez Core

1824.4k80](/packages/rapidez-core)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

265.2k](/packages/aedart-athenaeum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
