PHPackages                             litepie/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. litepie/otp

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

litepie/otp
===========

A comprehensive Laravel package for generating, signing and managing OTP codes with multiple channels support

v1.0.0(8mo ago)091MITPHPPHP ^8.2

Since Aug 30Pushed 8mo agoCompare

[ Source](https://github.com/Litepie/Otp)[ Packagist](https://packagist.org/packages/litepie/otp)[ Docs](https://github.com/litepie/otp)[ RSS](/packages/litepie-otp/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (11)Versions (2)Used By (1)

Laravel OTP Package
===================

[](#laravel-otp-package)

[![Tests](https://github.com/litepie/otp/workflows/Tests/badge.svg)](https://github.com/litepie/otp/actions)[![Code Style](https://github.com/litepie/otp/workflows/Code%20Style/badge.svg)](https://github.com/litepie/otp/actions)[![Static Analysis](https://github.com/litepie/otp/workflows/Static%20Analysis/badge.svg)](https://github.com/litepie/otp/actions)[![Total Downloads](https://camo.githubusercontent.com/1f8a6f38227a1b86036eef21dac019341487b0c0e5d85975923bf8630b4ed4bc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6c6974657069652f6f74702e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/litepie/otp)[![Latest Stable Version](https://camo.githubusercontent.com/7dcec69133c1f479ec7886b8c3e4f0579a6cd544f0dade4d168f59cd0ef6d8ec/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c6974657069652f6f74702e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/litepie/otp)[![License](https://camo.githubusercontent.com/48dea0ff2bd7e3376f628b1c1a8fd1f60f4e40a000daa7e80dc5459e07e582d3/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6c6974657069652f6f74702e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/litepie/otp)

A comprehensive Laravel package for generating, signing and managing OTP (One-Time Password) codes with multiple channels support.

📋 Requirements
--------------

[](#-requirements)

- PHP 8.2 or higher
- Laravel 10.0, 11.0, or 12.0

🚀 Features
----------

[](#-features)

- ✅ **Secure OTP Generation** - Generate cryptographically secure OTP codes
- ✅ **Digital Signing** - Sign OTP codes for enhanced security and verification
- ✅ **Multiple Delivery Channels** - Email, SMS, Database, and custom channels
- ✅ **Flexible Configuration** - Customizable length, format, and expiration
- ✅ **Rate Limiting** - Built-in protection against abuse
- ✅ **Multiple OTP Types** - Login, email verification, password reset, 2FA, etc.
- ✅ **Event System** - Complete lifecycle events for monitoring and logging
- ✅ **Queue Support** - Background processing for sending OTPs
- ✅ **Auto-cleanup** - Automatic removal of expired OTPs
- ✅ **Laravel 12 Ready** - Full compatibility with the latest Laravel versions
- ✅ **Production Ready** - Thoroughly tested and optimized for production use

📦 Installation
--------------

[](#-installation)

You can install the package via Composer:

```
composer require litepie/otp
```

### Publish Configuration

[](#publish-configuration)

Publish the configuration file:

```
php artisan vendor:publish --provider="Litepie\Otp\OtpServiceProvider" --tag="config"
```

### Run Migrations

[](#run-migrations)

Run the migrations to create the OTPs table:

```
php artisan migrate
```

### Set Up Automatic Cleanup (Optional)

[](#set-up-automatic-cleanup-optional)

Add the following to your `app/Console/Kernel.php` file to automatically clean up expired OTPs:

```
protected function schedule(Schedule $schedule)
{
    $schedule->command('otp:cleanup')->daily();
}
```

🔧 Configuration
---------------

[](#-configuration)

The configuration file `config/otp.php` allows you to customize:

- **Default OTP Settings** - Length, format, expiration, channels
- **OTP Types** - Specific settings for different use cases
- **Rate Limiting** - Prevent abuse with configurable limits
- **Digital Signing** - Secure OTP verification
- **Channel Configuration** - Email, SMS, and custom channel settings
- **Automatic Cleanup** - Keep your database clean

### Environment Variables

[](#environment-variables)

Add these to your `.env` file:

```
# OTP Signing Secret (defaults to APP_KEY)
OTP_SIGNING_SECRET=your-secret-key

# SMS Provider Configuration
OTP_SMS_PROVIDER=log  # Options: log, nexmo, twilio

# Nexmo/Vonage
NEXMO_KEY=your-nexmo-key
NEXMO_SECRET=your-nexmo-secret
NEXMO_FROM=YourApp

# Twilio
TWILIO_SID=your-twilio-sid
TWILIO_TOKEN=your-twilio-token
TWILIO_FROM=your-twilio-number
```

📖 Usage
-------

[](#-usage)

### Quick Start

[](#quick-start)

```
use Litepie\Otp\Facades\Otp;

// Generate and send OTP
$otp = Otp::generate()
    ->for('user@example.com')
    ->type('login')
    ->send();

// Verify OTP
$isValid = Otp::verify('123456', 'user@example.com', 'login');

if ($isValid) {
    // OTP is valid, proceed with authentication
    return response()->json(['message' => 'Login successful']);
}
```

### Advanced Usage

[](#advanced-usage)

```
// Custom OTP with specific settings
$otp = Otp::generate()
    ->for('user@example.com')
    ->type('password_reset')
    ->length(8)                    // 8 digits
    ->format('alphanumeric')       // Letters and numbers
    ->expiresIn(900)              // 15 minutes
    ->via(['email', 'sms'])       // Multiple channels
    ->with(['user_id' => 123])    // Additional data
    ->send();

// Check if OTP exists before generating new one
if (!Otp::exists('user@example.com', 'login')) {
    $otp = Otp::generate()
        ->for('user@example.com')
        ->type('login')
        ->send();
}

// Invalidate existing OTP
Otp::invalidate('user@example.com', 'login');
```

### Exception Handling

[](#exception-handling)

```
use Litepie\Otp\Exceptions\TooManyAttemptsException;
use Litepie\Otp\Exceptions\RateLimitExceededException;

try {
    $isValid = Otp::verify($code, $email, 'login');
} catch (TooManyAttemptsException $e) {
    return response()->json(['error' => 'Too many failed attempts'], 429);
} catch (RateLimitExceededException $e) {
    return response()->json(['error' => 'Rate limit exceeded'], 429);
}
```

🎯 OTP Types
-----------

[](#-otp-types)

The package supports multiple OTP types with individual configurations:

### Built-in Types

[](#built-in-types)

TypeUse CaseDefault LengthDefault Expiry`login`User authentication6 digits5 minutes`email_verification`Email verification6 digits10 minutes`password_reset`Password reset8 characters15 minutes`two_factor`2FA authentication6 digits3 minutes`phone_verification`Phone verification6 digits5 minutes### Custom Types

[](#custom-types)

Define custom OTP types in your configuration:

```
// config/otp.php
'types' => [
    'transaction_verify' => [
        'length' => 8,
        'format' => 'alphanumeric',
        'expires_in' => 600, // 10 minutes
        'max_attempts' => 3,
        'channels' => ['email', 'sms'],
        'rate_limit' => [
            'max_attempts' => 2,
            'decay_minutes' => 30,
        ],
    ],
],
```

📡 Delivery Channels
-------------------

[](#-delivery-channels)

### Email Channel

[](#email-channel)

Sends OTP via email using Laravel's notification system or traditional mail.

```
Otp::generate()
    ->for('user@example.com')
    ->via('email')
    ->send();
```

### SMS Channel

[](#sms-channel)

Send OTPs via SMS using various providers:

```
Otp::generate()
    ->for('+1234567890')
    ->via('sms')
    ->send();
```

**Supported SMS Providers:**

- **Log** (for testing)
- **Nexmo/Vonage**
- **Twilio**
- **Custom providers** (extensible)

### Database Channel

[](#database-channel)

Store OTP in database for manual retrieval:

```
Otp::generate()
    ->for('user@example.com')
    ->via('database')
    ->send();

// Retrieve from database
$otpRecord = \Litepie\Otp\Otp::where('identifier', 'user@example.com')
    ->where('type', 'login')
    ->valid()
    ->first();
```

### Multiple Channels

[](#multiple-channels)

Send via multiple channels simultaneously:

```
Otp::generate()
    ->for('user@example.com')
    ->via(['email', 'sms', 'database'])
    ->send();
```

### Custom Channels

[](#custom-channels)

Create custom delivery channels:

```
use Litepie\Otp\Contracts\OtpChannelInterface;

class SlackChannel implements OtpChannelInterface
{
    public function send(string $identifier, string $code, array $data = []): bool
    {
        // Implementation for Slack delivery
        return true;
    }

    public function canHandle(string $identifier): bool
    {
        return str_starts_with($identifier, '@slack:');
    }
}

// Register the custom channel
Otp::extend('slack', function () {
    return new SlackChannel();
});
```

📊 Events
--------

[](#-events)

The package fires comprehensive events for monitoring and logging:

### Available Events

[](#available-events)

- **`OtpGenerated`** - When an OTP is generated
- **`OtpSent`** - When an OTP is sent via a channel
- **`OtpVerified`** - When an OTP is successfully verified
- **`OtpFailed`** - When OTP verification fails

### Event Listeners

[](#event-listeners)

```
// In EventServiceProvider
protected $listen = [
    \Litepie\Otp\Events\OtpGenerated::class => [
        \App\Listeners\LogOtpGenerated::class,
    ],
    \Litepie\Otp\Events\OtpVerified::class => [
        \App\Listeners\LogOtpVerified::class,
        \App\Listeners\SendWelcomeEmail::class,
    ],
    \Litepie\Otp\Events\OtpFailed::class => [
        \App\Listeners\LogFailedOtpAttempt::class,
    ],
];
```

### Example Listener

[](#example-listener)

```
class LogOtpGenerated
{
    public function handle(\Litepie\Otp\Events\OtpGenerated $event)
    {
        Log::info('OTP generated', [
            'identifier' => $event->otp->identifier,
            'type' => $event->otp->type,
            'expires_at' => $event->otp->expires_at,
        ]);
    }
}
```

🛠️ Artisan Commands
-------------------

[](#️-artisan-commands)

### Cleanup Expired OTPs

[](#cleanup-expired-otps)

```
# Clean up expired OTPs (default: 7 days)
php artisan otp:cleanup

# Clean up OTPs older than specific days
php artisan otp:cleanup --days=3

# Force cleanup without confirmation
php artisan otp:cleanup --force
```

🔒 Security Features
-------------------

[](#-security-features)

- **Digital Signing** - All OTPs are digitally signed using HMAC-SHA256
- **Rate Limiting** - Configurable rate limiting per identifier and type
- **Secure Generation** - Cryptographically secure random code generation
- **Attempt Tracking** - Track and limit verification attempts
- **Automatic Cleanup** - Remove expired OTPs automatically
- **Timing Attack Protection** - Use `hash_equals()` for secure comparisons

🧪 Testing
---------

[](#-testing)

### Running Tests

[](#running-tests)

```
# Run all tests
composer test

# Run tests with coverage
composer test-coverage

# Run specific test
vendor/bin/phpunit tests/Unit/OtpTest.php
```

### Test Example

[](#test-example)

```
use Litepie\Otp\Facades\Otp;
use Illuminate\Support\Facades\Mail;

public function test_otp_generation_and_verification()
{
    Mail::fake();

    // Generate OTP
    $otp = Otp::generate()
        ->for('test@example.com')
        ->type('login')
        ->send();

    // Verify OTP
    $this->assertTrue(
        Otp::verify($otp->code, 'test@example.com', 'login')
    );

    // Assert mail was sent
    Mail::assertSent(\Litepie\Otp\Notifications\OtpNotification::class);
}
```

📚 Documentation
---------------

[](#-documentation)

- **[Examples](EXAMPLES.md)** - Comprehensive usage examples
- **[Contributing](CONTRIBUTING.md)** - How to contribute
- **[Security](SECURITY.md)** - Security policy
- **[Changelog](CHANGELOG.md)** - Version history

🤝 Contributing
--------------

[](#-contributing)

We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

### Development Setup

[](#development-setup)

```
git clone https://github.com/litepie/otp.git
cd otp
composer install
composer test
```

🔐 Security
----------

[](#-security)

If you discover a security vulnerability, please send an email to . All security vulnerabilities will be promptly addressed.

📄 License
---------

[](#-license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

💖 Support
---------

[](#-support)

- **⭐ Star this repo** if you find it helpful
- **🐛 Report issues** on [GitHub Issues](https://github.com/litepie/otp/issues)
- **💡 Request features** via [GitHub Discussions](https://github.com/litepie/otp/discussions)
- **📧 Contact us** at

---

Made with ❤️ by [Litepie](https://github.com/litepie)

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance60

Regular maintenance activity

Popularity5

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

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

257d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1788735?v=4)[Renfos Technologies](/maintainers/Renfos)[@Renfos](https://github.com/Renfos)

---

Top Contributors

[![georgemjohn](https://avatars.githubusercontent.com/u/7950080?v=4)](https://github.com/georgemjohn "georgemjohn (1 commits)")

---

Tags

laravellaravel 12otpsecurityAuthenticationemail2fasmstwo-factorverification

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[laragear/two-factor

On-premises 2FA Authentication for out-of-the-box.

339785.3k8](/packages/laragear-two-factor)[salehhashemi/laravel-otp-manager

Laravel OTP manager

18713.2k](/packages/salehhashemi-laravel-otp-manager)[rinvex/laravel-authy

Rinvex Authy is a simple wrapper for Authy TOTP, the best rated Two-Factor Authentication service for consumers, simplest 2fa Rest API for developers and a strong authentication platform for the enterprise.

3376.7k1](/packages/rinvex-laravel-authy)[remotemerge/totp-php

Lightweight, fast, and secure TOTP (2FA) authentication library for PHP — battle tested, dependency free, and ready for enterprise integration.

2010.2k](/packages/remotemerge-totp-php)[sicaboy/laravel-mfa

A Laravel package of Multi-factor Authentication (MFA/2FA) with a middleware.

101.2k](/packages/sicaboy-laravel-mfa)[wnikk/laravel-access-rules

Simple system of ACR (access control rules) for Laravel, with roles, groups, unlimited inheritance and possibility of multiplayer use.

103.6k1](/packages/wnikk-laravel-access-rules)

PHPackages © 2026

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