Looking to hire Laravel developers? Try LaraJobs

laravel-msegat maintained by aghfatehi

Description
A professional Laravel package for integrating with Msegat SMS, OTP, and WhatsApp APIs. Production-ready for SaaS, enterprise, and open-source projects.
Last update
2026/06/05 17:53 (dev-main)
License
Links
Downloads
0

Comments
comments powered by Disqus

laravel-msegat

A professional Laravel package for integrating with Msegat SMS, OTP, and WhatsApp APIs.

CI Latest Version Total Downloads License PHP Version

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 of timestamp.payload
  • X-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.