laravel-msegat maintained by aghfatehi
laravel-msegat
A professional Laravel package for integrating with Msegat SMS, OTP, and WhatsApp APIs.
Production-ready for SaaS, enterprise, and open-source projects. Supports Laravel 10, 11, and 12 with PHP 8.2+.
Installation
composer require aghfatehi/laravel-msegat
Laravel auto-discovery registers the service provider and facade automatically.
Publish Configuration
php artisan vendor:publish --provider="Aghfatehi\Msegat\MsegatServiceProvider" --tag=msegat-config
Publish Migrations
php artisan vendor:publish --provider="Aghfatehi\Msegat\MsegatServiceProvider" --tag=msegat-migrations
php artisan migrate
Configuration
Add to your .env:
MSEGAT_USERNAME=your_username
MSEGAT_API_KEY=your_api_key
MSEGAT_SENDER=YourSender
MSEGAT_BASE_URL=https://www.msegat.com/gw/
MSEGAT_TIMEOUT=30
MSEGAT_RETRIES=3
MSEGAT_VERIFY_SSL=true
MSEGAT_QUEUE_ENABLED=false
MSEGAT_LOGGING_ENABLED=true
MSEGAT_WEBHOOK_SECRET=your_webhook_secret
Config Options
| Variable | Default | Description |
|---|---|---|
MSEGAT_USERNAME |
— | Msegat account username |
MSEGAT_API_KEY |
— | Msegat API key |
MSEGAT_SENDER |
'' |
Default sender name |
MSEGAT_BASE_URL |
https://www.msegat.com/gw/ |
API base URL |
MSEGAT_TIMEOUT |
30 |
HTTP request timeout (seconds) |
MSEGAT_RETRIES |
3 |
Max retry attempts on failure |
MSEGAT_VERIFY_SSL |
true |
Verify SSL certificate |
MSEGAT_QUEUE_ENABLED |
false |
Enable async webhook processing |
MSEGAT_LOGGING_ENABLED |
true |
Enable request/response logging |
MSEGAT_WEBHOOK_SECRET |
'' |
Secret for webhook signature verification |
Usage
SMS
use Aghfatehi\Msegat\Facades\Msegat;
// Single recipient
$response = Msegat::sms()
->to('966512345678')
->message('Hello World')
->send();
// Multiple recipients
$response = Msegat::sms()
->to(['966512345678', '966598765432'])
->message('Bulk message')
->send();
// Custom sender
$response = Msegat::sms()
->sender('CustomAD')
->to('966512345678')
->message('Custom sender test')
->send();
// Scheduled message
$response = Msegat::sms()
->to('966512345678')
->message('Scheduled message')
->at('2026-12-01 10:00:00')
->send();
// Get bulk ID
$response = Msegat::sms()
->to(['966512345678', '966598765432'])
->message('Get bulk ID')
->options(['reqBulkId' => true])
->send();
$bulkId = $response->bulkId;
Personalized Messages
$response = Msegat::sms()
->to(['966512345678', '966598765432'])
->message('Hello {name}, your order {order} is ready')
->sendPersonalized([
['name' => 'Ahmed', 'order' => '1001'],
['name' => 'Mohammed', 'order' => '1002'],
]);
OTP
// Send OTP
$otpResponse = Msegat::otp()
->to('966512345678')
->sendOtp();
$otpId = $otpResponse->otpId;
// Verify OTP
$verification = Msegat::otp()
->to('966512345678')
->verifyOtp('123456');
if ($verification->successful) {
// OTP verified
}
WhatsApp (Abstract)
WhatsApp endpoints are not yet publicly documented by Msegat. Calling send() on WhatsApp mode returns a graceful fallback response.
$response = Msegat::whatsapp()
->to('966512345678')
->template('welcome')
->variables(['name' => 'Ahmed'])
->send();
// Returns unsuccessful response with informative message
Balance
$balance = Msegat::getBalance();
$credits = $balance->balance; // float
Message Cost Calculation
$cost = Msegat::sms()
->to(['966512345678', '966598765432'])
->message('Test message')
->calculateCost();
// Returns float
Sender Management
// List senders
$senders = Msegat::getSenders();
// Add sender
// (available via direct API call - endpoint: addSender.php)
Retrieve Messages
$messages = Msegat::forBulkId('BULK123')
->getMessages();
$messages = Msegat::forBulkId('BULK123')
->page(2)
->limit(10)
->getMessages();
Test Message
Msegat::sms()
->to('966512345678')
->sendTestMessage();
Queue Support
// Dispatch to default queue
Msegat::sms()
->to('966512345678')
->message('Queued message')
->queue();
// Custom queue connection
Msegat::sms()
->to('966512345678')
->message('Queued message')
->queue('redis', 'high');
The SendSmsJob retries up to 3 times with a 5-second backoff.
Events
| Event | Payload | Description |
|---|---|---|
MessageSending |
$data (array) |
Before sending SMS |
MessageSent |
$response (SmsResponse) |
After SMS sent |
OtpGenerated |
$number, $response (OtpResponse) |
After OTP sent |
OtpVerified |
$number, $code, $response (OtpResponse) |
After OTP verified |
WebhookReceived |
$type, $payload (array) |
When webhook is received |
Example listener registration in EventServiceProvider:
protected $listen = [
\Aghfatehi\Msegat\Events\MessageSent::class => [
\App\Listeners\LogMsegatMessage::class,
],
];
Webhooks
The package registers four webhook routes under the /webhook/msegat/ prefix:
| Route | Purpose |
|---|---|
POST /webhook/msegat/delivery |
Delivery reports |
POST /webhook/msegat/status |
Message status updates |
POST /webhook/msegat/incoming |
Incoming messages |
POST /webhook/msegat/failed |
Failed messages |
Signature Verification
Set MSEGAT_WEBHOOK_SECRET in .env and each webhook request must include:
X-Msegat-Signature: HMAC-SHA256 oftimestamp.payloadX-Msegat-Timestamp: Unix timestamp
Requests outside a 5-minute tolerance window are rejected.
Notification Channel
namespace App\Notifications;
use Illuminate\Notifications\Notification;
class WelcomeSms extends Notification
{
public function via($notifiable): array
{
return ['msegat'];
}
public function toMsegat($notifiable): string
{
return "Welcome {$notifiable->name} to our platform!";
}
}
Add routeNotificationForMsegat() to your notifiable model:
public function routeNotificationForMsegat(): string
{
return $this->phone;
}
Artisan Commands
# Check account balance
php artisan msegat:balance
# List registered senders
php artisan msegat:senders
Testing
composer test
With coverage:
composer test-coverage
The test suite includes:
- Unit Tests: DTOs, enums, exceptions, phone formatter
- Feature Tests: SMS sending, OTP, balance, webhooks, config
- Integration Tests: Events, queues
Code Quality
# Laravel Pint (PSR-12)
composer lint
# Auto-fix
composer lint-fix
# PHPStan (level 6)
composer analyse
# Rector
composer rector
Database Migrations
| Table | Purpose |
|---|---|
msegat_sms_logs |
SMS send history |
msegat_otp_requests |
OTP request tracking |
msegat_delivery_reports |
Delivery report storage |
msegat_webhook_logs |
Webhook event log |
msegat_failed_requests |
Failed request records |
Troubleshooting
| Error Code | Meaning | Solution |
|---|---|---|
M0002 / 1020 |
Invalid login | Check MSEGAT_USERNAME and MSEGAT_API_KEY |
1060 |
Insufficient balance | Top up your Msegat account |
1110 |
Sender missing | Set MSEGAT_SENDER or use ->sender() |
1120 |
Invalid numbers | Use international format (9665xxxxxxxx) |
1064 |
Free OTP invalid content | Use approved OTP template or upgrade account |
Changelog
See CHANGELOG for recent changes.
Security
If you discover any security-related issues, please email instead of using the issue tracker.
Credits
License
The MIT License (MIT). See LICENSE for details.