Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Msg91 Php Laravel Package

kaydee123/msg91-php

PHP 8.0–8.5 client for MSG91 SMS & OTP: send single/bulk and template-based SMS, DLT-compliant messaging for India, send/verify/resend OTP (text/voice), fluent chainable API, strong error handling, framework-agnostic.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:
    composer require kaydee123/msg91-php
    
  2. Initialize the client with your MSG91 Auth Key (found in MSG91 Dashboard):
    use Kaydee123\Msg91\Msg91Client;
    $client = new Msg91Client('YOUR_AUTH_KEY');
    

First Use Case: Sending a Template-Based SMS

$response = $client->sms()
    ->template('YOUR_TEMPLATE_ID')
    ->numbers('919876543210')
    ->send();

First Use Case: Sending an OTP

$response = $client->otp()
    ->template('YOUR_OTP_TEMPLATE_ID')
    ->number('919876543210')
    ->send();

Where to look first:


Implementation Patterns

Daily Workflows

1. SMS Workflow (Transactional)

// For transactional messages (e.g., order confirmations)
$response = $client->sms()
    ->transactional() // Explicitly set route (default)
    ->template('ORDER_CONFIRMATION_TEMPLATE_ID')
    ->variables([
        'order_id' => 'ORD12345',
        'amount' => '99.99',
        'date' => date('Y-m-d'),
    ])
    ->numbers('919876543210')
    ->send();

2. OTP Workflow (Registration)

// Generate and send OTP during user registration
$response = $client->otp()
    ->template('REGISTRATION_OTP_TEMPLATE_ID')
    ->number('919876543210')
    ->length(6)       // Custom OTP length
    ->expiry(5)       // Shorter expiry for security
    ->send();

// Store OTP reference (e.g., in session or DB) for later verification
session(['otp_reference' => $response->getFlowId()]);

// Verify OTP on form submission
$isValid = $client->otp($userSubmittedOtp)
    ->number('919876543210')
    ->verify();

3. Bulk SMS with Recipient-Specific Variables

// Send personalized messages to multiple users
$recipients = [
    ['mobiles' => '919876543210', 'name' => 'John', 'amount' => '100.00'],
    ['mobiles' => '919876543211', 'name' => 'Jane', 'amount' => '200.00'],
];

$response = $client->sms()
    ->template('PAYMENT_RECEIPT_TEMPLATE_ID')
    ->recipients($recipients)
    ->send();

4. DLT-Compliant Promotional SMS

// For promotional campaigns (India)
$response = $client->sms()
    ->promotional()
    ->sender_id('YOUR_SENDER_ID')
    ->mobiles('919876543210,919876543211')
    ->dlt_template_id('YOUR_DLT_TEMPLATE_ID')
    ->message('Exclusive offer: 20% off! Use code PROMO20')
    ->send();

Integration Tips

1. Laravel Service Provider

Register the client as a singleton in AppServiceProvider:

public function register()
{
    $this->app->singleton(Msg91Client::class, function ($app) {
        return new Msg91Client(config('services.msg91.auth_key'));
    });
}

2. Configuration File (config/services.php)

'msg91' => [
    'auth_key' => env('MSG91_AUTH_KEY'),
    'base_url' => env('MSG91_BASE_URL', 'https://control.msg91.com/api/'),
    'timeout' => env('MSG91_TIMEOUT', 60),
    'debug' => env('MSG91_DEBUG', false),
],

3. Dependency Injection in Controllers

use Kaydee123\Msg91\Msg91Client;

class AuthController extends Controller
{
    public function __construct(private Msg91Client $msg91) {}

    public function sendOtp(Request $request)
    {
        $response = $this->msg91->otp()
            ->template('REGISTRATION_OTP_TEMPLATE_ID')
            ->number($request->phone)
            ->send();

        return response()->json($response->getData());
    }
}

4. Retry Logic for Failed OTPs

public function resendOtp(Request $request)
{
    try {
        $response = $this->msg91->otp()
            ->number($request->phone)
            ->viaText() // or viaVoice()
            ->retry();

        return response()->json(['success' => true]);
    } catch (\Kaydee123\Msg91\Exceptions\ApiException $e) {
        if ($e->getStatusCode() === 400 && strpos($e->getMessage(), 'Flow ID') !== false) {
            // Handle invalid flow ID (e.g., retry with new OTP)
            return $this->sendOtp($request);
        }
        return response()->json(['error' => $e->getMessage()], 400);
    }
}

5. Logging Responses

$response = $client->sms()
    ->template('TEMPLATE_ID')
    ->numbers('919876543210')
    ->send();

if ($client->getConfig()->getDebug()) {
    \Log::info('MSG91 Response', [
        'data' => $response->getData(),
        'status' => $response->getStatus(),
        'message' => $response->getMessage(),
    ]);
}

Gotchas and Tips

Pitfalls

1. Missing Template ID for Indian Numbers

  • Issue: OTPs sent to Indian numbers (91...) require a template() to be set due to DLT compliance.
  • Fix: Always include ->template('YOUR_OTP_TEMPLATE_ID') for Indian numbers.
  • Debug: Check for InvalidArgumentException if template is missing.

2. DLT Template ID Mismatch

  • Issue: Using a non-DLT template for promotional SMS in India triggers error 211: DLT Template Id Missing.
  • Fix: Ensure dlt_template_id is set for promotional SMS:
    ->dlt_template_id('YOUR_DLT_TEMPLATE_ID')
    

3. Flow ID Expiry

  • Issue: OTP Flow ID expires after 24 hours. Retrying after expiry fails with 400: Flow ID Missing or Invalid.
  • Fix: Regenerate the OTP if retry fails:
    try {
        $client->otp()->number('919876543210')->retry();
    } catch (\Kaydee123\Msg91\Exceptions\ApiException $e) {
        if ($e->getStatusCode() === 400) {
            $client->otp()->template('TEMPLATE_ID')->number('919676543210')->send();
        }
    }
    

4. Sender ID Restrictions

  • Issue: Sender IDs must be registered with MSG91 and DLT (for India). Using an unregistered ID fails with 203: Invalid sender ID.
  • Fix: Verify your sender ID in the MSG91 Dashboard.

5. Rate Limits

  • Issue: MSG91 enforces rate limits (e.g., 1 SMS/second for free tier). Exceeding limits returns 429: Too Many Requests.
  • Fix: Implement exponential backoff:
    $attempts = 0;
    $maxAttempts = 3;
    $delay = 1000; // 1 second
    
    while ($attempts < $maxAttempts) {
        try {
            $response = $client->sms()->template('ID')->numbers('919876543210')->send();
            break;
        } catch (\Kaydee123\Msg91\Exceptions\ApiException $e) {
            if ($e->getStatusCode() !==
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity