DEV Community

Cover image for Send SMS, OTP & DLT Messages in Laravel with Fast2SMS (Open Source Package)
Shakil Alam
Shakil Alam

Posted on • Edited on

Send SMS, OTP & DLT Messages in Laravel with Fast2SMS (Open Source Package)

In 2026, SMS remains one of the most reliable ways to reach users — especially in India, where mobile penetration is massive. Whether it's OTPs, transaction alerts, delivery updates, or marketing campaigns, SMS still gets through when other channels don't.

But integrating SMS as a Laravel developer is rarely clean. Most providers hand you a raw REST API, leaving you to wire up queues, handle retries, manage DLT compliance, and keep everything testable yourself.

Laravel Fast2SMS handles all of that for you.


Requirements

  • PHP 8.3 or higher
  • Laravel 12 or higher

What's Included

  • Three SMS routes: Quick SMS, DLT SMS, and OTP SMS
  • Fluent, chainable API (Fast2sms::to()->message()->send())
  • Native Laravel Notifications channel support
  • Built-in queue integration with connection, queue name, and delay control
  • Database logging of all sent messages (optional)
  • Log driver for zero-cost local development — no real SMS sent
  • Validation helper for Indian phone numbers
  • Balance monitoring via Artisan command and events
  • Automatic retries built in
  • Laravel auto-discovery — no manual provider registration needed

Installation

composer require itxshakil/laravel-fast2sms
Enter fullscreen mode Exit fullscreen mode

Publish the config file:

php artisan vendor:publish --tag=fast2sms-config
Enter fullscreen mode Exit fullscreen mode

Optionally, enable database logging:

php artisan vendor:publish --tag="fast2sms-migrations"
php artisan migrate
Enter fullscreen mode Exit fullscreen mode

Configuration

Add the following to your .env:

FAST2SMS_API_KEY="YOUR_API_KEY"
FAST2SMS_DEFAULT_SENDER_ID="FSTSMS"
FAST2SMS_DEFAULT_ROUTE="dlt"
FAST2SMS_DRIVER="api"           # Use 'log' for local development
FAST2SMS_DATABASE_LOGGING=true  # Optional: log all sent SMS to database
Enter fullscreen mode Exit fullscreen mode

The log driver is especially useful during development — it writes SMS to your Laravel log instead of making real API calls, so you can test your full integration for free.


Sending SMS

Quick SMS

For simple, non-DLT messages. Supports Unicode for regional languages:

use Shakil\Fast2sms\Facades\Fast2sms;
use Shakil\Fast2sms\Enums\SmsLanguage;

Fast2sms::quick('9999999999', 'Hello, this is a Quick SMS!');

// Unicode for Hindi or other regional languages
Fast2sms::quick('9999999999', 'नमस्ते! यह एक क्विक एसएमएस है।', SmsLanguage::UNICODE);
Enter fullscreen mode Exit fullscreen mode

DLT SMS

Required for template-based, DLT-registered messages:

Fast2sms::dlt(
    numbers: '9999999999',
    templateId: 'YOUR_TEMPLATE_ID',
    variablesValues: ['John Doe'],
    senderId: 'YOUR_SENDER_ID'
);
Enter fullscreen mode Exit fullscreen mode

OTP SMS

Fast2sms::otp('9999999999', '123456');
Enter fullscreen mode Exit fullscreen mode

Fluent Interface

For full control over every parameter:

use Shakil\Fast2sms\Enums\SmsRoute;

Fast2sms::to('9999999999')
    ->route(SmsRoute::DLT)
    ->senderId('YOUR_SENDER_ID')
    ->templateId('YOUR_TEMPLATE_ID')
    ->variables(['John Doe'])
    ->send();
Enter fullscreen mode Exit fullscreen mode

Queue Integration

All three SMS types have dedicated queue helpers for non-blocking dispatch:

Fast2sms::quickQueue('9999999999', 'Hello from queue!');
Fast2sms::otpQueue('9999999999', '123456');
Fast2sms::dltQueue(
    numbers: '9999999999',
    templateId: 'YOUR_TEMPLATE_ID',
    variablesValues: ['John Doe'],
    senderId: 'YOUR_SENDER_ID'
);
Enter fullscreen mode Exit fullscreen mode

For advanced queue control:

Fast2sms::to('9999999999')
    ->message('Test message')
    ->route(SmsRoute::QUICK)
    ->onConnection('redis')
    ->onQueue('sms')
    ->delay(now()->addMinutes(10))
    ->queue();
Enter fullscreen mode Exit fullscreen mode

Laravel Notifications Channel

Use Fast2SMS as a first-class Laravel notification channel:

use Illuminate\Notifications\Notification;
use Shakil\Fast2sms\Notifications\Messages\SmsMessage;
use Shakil\Fast2sms\Enums\SmsRoute;

class OrderShipped extends Notification
{
    public function via($notifiable)
    {
        return ['fast2sms'];
    }

    public function toSms($notifiable)
    {
        return (new SmsMessage)
            ->route(SmsRoute::DLT)
            ->template('TEMPLATE_ID', ['Order #123'])
            ->from('SENDER_ID');
    }
}
Enter fullscreen mode Exit fullscreen mode

Your notifiable model needs a routeNotificationForSms method:

public function routeNotificationForSms(): string
{
    return $this->phone;
}
Enter fullscreen mode Exit fullscreen mode

Phone Number Validation

The package ships a custom validation rule for 10-digit Indian mobile numbers:

use Shakil\Fast2sms\Rules\Fast2smsPhone;

$request->validate([
    'phone' => ['required', new Fast2smsPhone],
]);
Enter fullscreen mode Exit fullscreen mode

Balance Monitoring

Check your wallet balance programmatically:

$response = Fast2sms::checkBalance();

if ($response->success()) {
    echo "Balance: {$response->balance}";
    echo "SMS Count: {$response->smsCount}";
}
Enter fullscreen mode Exit fullscreen mode

Monitor balance via Artisan and fire an event when it drops below a threshold:

php artisan sms:monitor --threshold=500
Enter fullscreen mode Exit fullscreen mode

Listen for the event in your AppServiceProvider:

use Shakil\Fast2sms\Events\LowBalanceDetected;

Event::listen(function (LowBalanceDetected $event) {
    Notification::route('mail', 'dev@example.com')
        ->notify(new LowSmsBalanceNotification($event->balance, $event->threshold));
});
Enter fullscreen mode Exit fullscreen mode

Schedule it to run automatically:

$schedule->command('sms:monitor')->hourly();
Enter fullscreen mode Exit fullscreen mode

Error Handling

All failures throw Fast2smsException:

use Shakil\Fast2sms\Exceptions\Fast2smsException;

try {
    Fast2sms::quick('9999999999', 'Hello World');
} catch (Fast2smsException $e) {
    logger()->error('SMS failed: ' . $e->getMessage());
}
Enter fullscreen mode Exit fullscreen mode

Resources


Final Thoughts

Laravel Fast2SMS was built to make SMS integration feel native to Laravel — not like bolting on a third-party REST client. Whether you're sending a single OTP or dispatching thousands of DLT messages through a queue, the API stays consistent and the code stays clean.

If you're building for Indian users, give it a try:

composer require itxshakil/laravel-fast2sms
Enter fullscreen mode Exit fullscreen mode

Found a bug or have a feature in mind? Open an issue or submit a PR on GitHub — contributions are always welcome. And if the package saves you time, a ⭐ on the repo goes a long way in helping other Laravel developers find it.

Top comments (0)