PHPackages                             gennet/laravel-sms - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. gennet/laravel-sms

ActiveLibrary

gennet/laravel-sms
==================

Official standalone Laravel SDK for the Gennet SMS API

v1.0.0(today)01↑2900%MITPHPPHP &gt;=8.2CI failing

Since Aug 24Pushed todayCompare

[ Source](https://github.com/engrmukul/gennet-laravel-sms)[ Packagist](https://packagist.org/packages/gennet/laravel-sms)[ RSS](/packages/gennet-laravel-sms/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (5)Versions (2)Used By (0)

Gennet Laravel SMS
==================

[](#gennet-laravel-sms)

Official **standalone** Laravel SDK for the [Gennet SMS API](https://isms.gennet.com.bd).

This package talks to the Gennet SMS API directly over HTTP (Guzzle). It does **not**depend on the generic `gennet/sms` PHP SDK — it is self-contained and installs on its own into any Laravel 11/12/13 application.

Requirements
------------

[](#requirements)

- PHP &gt;= 8.1
- Laravel 11, 12 or 13

Installation
------------

[](#installation)

```
composer require gennet/laravel-sms
```

The service provider and `GennetSms` facade are auto-discovered.

Publish the config file:

```
php artisan vendor:publish --tag=gennet-sms-config
```

Configuration
-------------

[](#configuration)

Add to your `.env`:

```
GENNET_SMS_API_TOKEN=
GENNET_SMS_SENDER_ID=GENNET
GENNET_SMS_BASE_URL=https://isms.gennet.com.bd
GENNET_SMS_TIMEOUT=15
GENNET_SMS_CONNECT_TIMEOUT=5
```

Endpoint paths are also configurable and default to the verified Gennet SMS API v3 routes:

```
GENNET_SMS_ENDPOINT_SEND=/api/v3/send-sms
GENNET_SMS_ENDPOINT_BULK=/api/v3/send-sms/bulk
GENNET_SMS_ENDPOINT_DYNAMIC=/api/v3/send-sms/dynamic
GENNET_SMS_ENDPOINT_STATUS=/api/v3/send-sms/status
GENNET_SMS_ENDPOINT_BALANCE=/api/v3/balance
GENNET_SMS_ENDPOINT_TRANSFER=/api/v3/transfer-balance
GENNET_SMS_ENDPOINT_INCOMING=/api/v3/incoming-messages-list
```

Never commit real tokens or credentials to source control.

Usage
-----

[](#usage)

### Single SMS

[](#single-sms)

```
use Gennet\LaravelSms\Facades\GennetSms;

$response = GennetSms::send(
    msisdn: '8801712345678',
    message: 'Hello from Laravel'
);
```

A secure 20-character alphanumeric `csms_id` is generated automatically when omitted. You may provide your own, or override the configured sender ID per call:

```
$response = GennetSms::send(
    msisdn: '8801712345678',
    message: 'Your OTP is 123456',
    csmsId: 'OTP123456'
);

$response = GennetSms::send(
    msisdn: '8801712345678',
    message: 'Hello',
    csmsId: 'ORDER1001',
    sid: 'GENNET'
);
```

### Bulk SMS

[](#bulk-sms)

```
GennetSms::bulk(
    msisdns: ['8801712345678', '8801812345678'],
    message: 'Hello everyone',
    batchCsmsId: 'BATCH1001'
);
```

### Dynamic (personalized) SMS

[](#dynamic-personalized-sms)

```
GennetSms::dynamic([
    ['msisdn' => '8801712345678', 'message' => 'Hello Karim', 'csms_id' => 'MSG1001'],
    ['msisdn' => '8801812345678', 'message' => 'Hello Rahim', 'csms_id' => 'MSG1002'],
]);
```

The Laravel-friendly `message` key is mapped internally to the API's `text` field.

### Delivery status (DLR)

[](#delivery-status-dlr)

```
GennetSms::status(referenceId: '...');
```

### Balance

[](#balance)

```
$response = GennetSms::balance();
```

### Balance transfer

[](#balance-transfer)

```
GennetSms::transferBalance(
    fromSid: 'SID1',
    toSid: 'SID2',
    amount: 1000,
    remarks: 'Transfer to child account'
);
```

### Incoming messages

[](#incoming-messages)

```
GennetSms::incoming();
```

The production backend currently only requires/validates `api_token` for this endpoint. Additional array keys passed to `incoming()` are forwarded as extra query parameters for forward compatibility, but are not guaranteed to be understood by the API.

### Dependency injection

[](#dependency-injection)

```
use Gennet\LaravelSms\Contracts\GennetSmsContract;

class SmsService
{
    public function __construct(
        private GennetSmsContract $sms
    ) {}

    public function send(): void
    {
        $this->sms->send('8801712345678', 'Hello');
    }
}
```

### Laravel Notification channel

[](#laravel-notification-channel)

```
use Gennet\LaravelSms\Notifications\GennetSmsChannel;
use Gennet\LaravelSms\Notifications\GennetSmsMessage;

class OtpNotification extends \Illuminate\Notifications\Notification
{
    public function via(object $notifiable): array
    {
        return [GennetSmsChannel::class];
    }

    public function toGennetSms(object $notifiable): GennetSmsMessage
    {
        return new GennetSmsMessage('Your OTP is 123456');
    }
}
```

```
class User extends Authenticatable
{
    public function routeNotificationForGennetSms(): string
    {
        return $this->phone;
    }
}
```

`GennetSmsMessage` also supports `->from('SENDERID')` and `->clientReference('CSMS1001')`.

Exception handling
------------------

[](#exception-handling)

HTTP 200 does not always mean success — the Gennet API can return `status: "FAILED"`with a `status_code` inside a 200 response. This SDK detects that and throws a typed exception instead:

```
use Gennet\LaravelSms\Exceptions\ApiException;
use Gennet\LaravelSms\Exceptions\RateLimitException;
use Gennet\LaravelSms\Exceptions\InsufficientBalanceException;
use Gennet\LaravelSms\Exceptions\AuthenticationException;
use Gennet\LaravelSms\Exceptions\TransportException;

try {
    GennetSms::send(msisdn: '8801712345678', message: 'Hello');
} catch (RateLimitException $e) {
    // status_code 4029 — retry later
} catch (InsufficientBalanceException $e) {
    // status_code 4008
} catch (AuthenticationException $e) {
    // status_code 4001 — invalid API token
} catch (TransportException $e) {
    // network/DNS/timeout failure — no response was received
} catch (ApiException $e) {
    // any other API-level failure
    $e->apiStatusCode();
    $e->payload();
}
```

The full exception hierarchy: `GennetSmsException` → `ApiException` → `AuthenticationException`, `ValidationException`, `RateLimitException`, `InsufficientBalanceException`, `ServerException`. `TransportException` is thrown directly from `GennetSmsException` for connection-level failures.

**No automatic retries.** `send`, `bulk`, `dynamic` and `transferBalance` are never retried automatically by this SDK, because retrying could cause duplicate SMS deliveries or duplicate balance transfers. Retry only if your application logic explicitly decides to.

Verified API routes
-------------------

[](#verified-api-routes)

All endpoint defaults in this package were verified directly against the production Gennet SMS API v3 route definitions and controller/request classes — none were guessed:

OperationMethodPathSingle SMSPOST`/api/v3/send-sms`Bulk SMSPOST`/api/v3/send-sms/bulk`Dynamic SMSPOST`/api/v3/send-sms/dynamic`Status (DLR)GET`/api/v3/send-sms/status`BalanceGET`/api/v3/balance`Transfer balancePOST`/api/v3/transfer-balance`Incoming messagesGET`/api/v3/incoming-messages-list`Security
--------

[](#security)

- API tokens are sent via the `X-API-TOKEN` header and as `api_token` in the request body/query (matching the backend's accepted contract) — never logged.
- Exception messages and payloads never include the API token.
- No automatic retries on send/bulk/dynamic/transfer operations.
- HTTPS is the default transport (`https://isms.gennet.com.bd`).

Testing
-------

[](#testing)

```
composer install
composer test
```

Tests use Orchestra Testbench and a Guzzle `MockHandler` — no real API calls are made.

License
-------

[](#license)

MIT

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance100

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/50988414?v=4)[Mizanur Rahaman](/maintainers/engrmukul)[@engrmukul](https://github.com/engrmukul)

---

Top Contributors

[![engrmukul](https://avatars.githubusercontent.com/u/50988414?v=4)](https://github.com/engrmukul "engrmukul (1 commits)")

---

Tags

laravelsdksmssms apigennet

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/gennet-laravel-sms/health.svg)

```
[![Health](https://phpackages.com/badges/gennet-laravel-sms/health.svg)](https://phpackages.com/packages/gennet-laravel-sms)
```

###  Alternatives

[spatie/laravel-health

Monitor the health of a Laravel application

88412.7M190](/packages/spatie-laravel-health)[craftcms/cms

Craft CMS

3.6k3.7M3.5k](/packages/craftcms-cms)[fleetbase/core-api

Core Framework and Resources for Fleetbase API

1239.7k25](/packages/fleetbase-core-api)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

353.6k](/packages/eslazarev-wildberries-sdk)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5226.7k](/packages/simplestats-io-laravel-client)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
