Laravel Fast2SMS v2.0.0 — WhatsApp Support, Notification Channels & a Smarter DX
When I shipped v1 of laravel fast2sms, the goal was simple: send SMS to Indian phone numbers from Laravel without wrestling raw API arrays. v2.0.0 takes that same idea much further.

The headline is WhatsApp Business API support — text, images, documents, locations, templates, reactions, stickers, and interactive messages, all through the same familiar Fast2sms facade. Beyond that, v2 brings drop-in Laravel Notification Channels, a typed exception hierarchy, expressive testing utilities, and cost-saving guards that protect your wallet in production.
⚠️ This is a major release with breaking changes. See the Upgrade Guide before updating.
Let me walk you through what matters.
Table of Contents
What this package actually does
At its core, this package acts as a thin Laravel-friendly layer over the Fast2SMS API.
Instead of manually crafting HTTP requests, handling headers, parsing responses, and managing failures — you interact with a clean, expressive API that feels native to Laravel.
It doesn’t replace Fast2SMS. It simplifies how you use it.
How this saves you time
A typical Fast2SMS integration involves:
- Writing raw HTTP requests
- Managing authentication headers
- Handling retries and failures
- Structuring payloads correctly (DLT, variables, etc.)
- Helps prevent unnecessary SMS usage and cost
This package removes that repetitive setup.
In most cases, what takes 1–2 hours of setup can be reduced to a few minutes with a single method call.
WhatsApp Business API
This is the big one. Starting in v2.0.0, the package supports the Fast2SMS WhatsApp Business API through Fast2sms::whatsapp().
Send a plain text message:
use Shakil\Fast2sms\Facades\Fast2sms;
Fast2sms::whatsapp()
->to('9999999999')
->text('Your order has been shipped and is on its way!')
->send();Send an image with a caption:
Fast2sms::whatsApp()
->to('9999999999')
->image('https://yourapp.com/invoice.png', caption: 'Your invoice for order #1042')
->send();Send a document:
Fast2sms::whatsApp()
->to('9999999999')
->document('https://yourapp.com/receipt.pdf', filename: 'receipt.pdf')
->send();Send a location:
Fast2sms::whatsApp()
->to('9999999999')
->location(lat: 28.6139, lng: 77.2090, name: 'New Delhi')
->send();Send a registered template:
Fast2sms::whatsApp()
->to('9999999999')
->template(id: 'YOUR_TEMPLATE_ID', variables: ['John', 'Order #1042'])
->send();React to a message, send a sticker, or build interactive button flows — the full WhatsApp API surface is available through the same fluent chain.
Laravel Notification Channels
v2 ships two drop-in notification channels: SmsChannel and WhatsAppChannel. Your existing notification classes work exactly the way you’d expect.
use Shakil\Fast2sms\Channels\SmsChannel;
use Shakil\Fast2sms\Channels\WhatsAppChannel;
use Shakil\Fast2sms\Messages\SmsMessage;
use Shakil\Fast2sms\Messages\WhatsAppMessage;
class OrderShipped extends Notification
{
public function via($notifiable): array
{
return [SmsChannel::class, WhatsAppChannel::class];
}
public function toFast2sms($notifiable): SmsMessage
{
return SmsMessage::create()
->otp('Your OTP is 482910. Valid for 10 minutes.');
}
public function toWhatsApp($notifiable): WhatsAppMessage
{
return WhatsAppMessage::create()
->text('Your order has been shipped!');
}
}Add the routing methods to your User model and you’re done:
public function routeNotificationForFast2sms(): string
{
return $this->phone_number;
}
public function routeNotificationForWhatsapp(): string
{
return $this->phone_number;
}
No facade, no manual number passing. Just idiomatic Laravel.
Typed Exception Hierarchy
In v1, every API failure threw a single Fast2smsException. In v2 you can catch exactly what you need:
use Shakil\Fast2sms\Exceptions\AuthenticationException;
use Shakil\Fast2sms\Exceptions\RateLimitException;
use Shakil\Fast2sms\Exceptions\InsufficientBalanceException;
use Shakil\Fast2sms\Exceptions\NetworkException;
try {
Fast2sms::otp('9999999999', '845621');
} catch (InsufficientBalanceException $e) {
// Notify your team — wallet is empty
} catch (RateLimitException $e) {
// Back off and retry
} catch (AuthenticationException $e) {
// API key is wrong or expired
} catch (NetworkException $e) {
// Fast2SMS was unreachable
}The full list of typed exceptions is in the changelog.
Rich Fake Assertions for Testing
v2 ships 16 assertion methods on Fast2smsFake so your feature tests are expressive and readable — no more inspecting raw recorded calls.
Fast2sms::fake();
// ... trigger your code ...
Fast2sms::assertSmsSentTo('9999999999');
Fast2sms::assertSmsSentTo('9999999999', fn ($sms) =>
str_contains($sms->message, '482910')
);
Fast2sms::assertWhatsAppSentTo('9999999999');
Fast2sms::assertNothingSent();
// Clean up for tests that need real sending
Fast2sms::stopFaking();Fluent Message Builders with Credit Helpers
SmsMessage and WhatsAppMessage are first-class objects with named constructors and chainable setters. SmsMessage also ships with credit helpers so you can estimate cost before you send:
use Shakil\Fast2sms\Messages\SmsMessage;
$message = SmsMessage::create()
->withContent('Your appointment is confirmed for tomorrow at 10am.')
->withRoute(SmsRoute::QUICK);
$message->charCount(); // character count
$message->isUnicode(); // true if Unicode encoding is needed
$message->creditCount(); // SMS credits this will consume
$message->exceedsOneSms(); // true if longer than one SMSNo more guessing whether a long message costs 1 credit or 3.
Built-in safeguards to avoid wasted SMS costs
In real-world apps, SMS costs often increase due to small mistakes like duplicate sends, invalid numbers, or retry issues.
This release includes a few optional safeguards that protect your wallet in production.:
- Removes duplicate numbers automatically (enabled by default)
- Filters out invalid recipients before sending
- Prevents duplicate sends within a short time window
- Allows rate limiting to avoid over-sending
- Checks wallet balance before sending
- Lets you estimate SMS credits before sending
These are simple additions, but they help keep costs under control as your application scales.
New Artisan Commands
# List every event the package fires, with descriptions
php artisan fast2sms:events
# Generate an IDE helper file for full autocompletion
php artisan fast2sms:ide-helper
Run fast2sms:ide-helper once after install and get full autocompletion on every facade method in PhpStorm or VS Code.
Getting Started
Requirements: PHP ^8.3 (8.4 and 8.5 also tested), Laravel 11, 12, or 13.
composer require itxshakil/laravel-fast2smsphp artisan vendor:publish --tag=fast2sms-configFAST2SMS_API_KEY="your-api-key"
FAST2SMS_DEFAULT_SENDER_ID="FSTSMS"
FAST2SMS_DEFAULT_ROUTE="dlt"Upgrading from v1
The public sending API — Fast2sms::quick(), ::dlt(), ::otp(), and now ::viaWhatsApp() — is completely unchanged. Most v1 code will work without modification.
The breaking changes are in internals: exception types, DTOs, and return type hints. The full step-by-step migration is in UPGRADING.md.
Links
- ⭐ GitHub: github.com/itxshakil/laravel-fast2sms
- 📦 Packagist: packagist.org/packages/itxshakil/laravel-fast2sms
- 📋 Full Changelog: CHANGELOG.md
- 📖 Upgrade Guide: UPGRADING.md
- 🐛 Issues: github.com/itxshakil/laravel-fast2sms/issues
If this saved you time, a star on GitHub helps other Laravel developers find the package.
If you’re already using Fast2SMS in a Laravel project, this package can simplify your integration and make your code easier to manage as your application grows.
You can get started in just a few minutes.
Built by Shakil Alam — Laravel developer, open-source contributor.




