PHPackages                             gennet/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/sms

ActiveLibrary

gennet/sms
==========

Framework-independent PHP SDK for the Gennet SMS API

00PHPCI passing

Since Aug 24Pushed todayCompare

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

READMEChangelogDependenciesVersions (1)Used By (0)

Gennet SMS PHP SDK
==================

[](#gennet-sms-php-sdk)

A framework-independent PHP SDK for the Gennet SMS API. No Laravel dependency — a Laravel-specific SDK will be built separately on top of this core package.

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

[](#requirements)

- PHP &gt;= 8.1
- `guzzlehttp/guzzle` ^7.8

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

[](#installation)

```
composer require gennet/sms
```

Usage
-----

[](#usage)

```
use Gennet\Sms\GennetClient;

$gennet = new GennetClient(
    apiToken: getenv('GENNET_API_TOKEN')
);

$response = $gennet->messages()->send(
    sid: 'GENNET',
    msisdn: '8801712345678',
    message: 'Hello from Gennet',
    csmsId: 'ORDER1001'
);

print_r($response->data());
```

### Bulk SMS

[](#bulk-sms)

```
$response = $gennet->messages()->sendBulk(
    sid: 'GENNET',
    msisdn: ['8801712345678', '8801812345678'],
    message: 'Bulk message',
    batchCsmsId: 'BATCH1001'
);
```

### Dynamic SMS

[](#dynamic-sms)

```
use Gennet\Sms\ValueObjects\DynamicMessage;

$response = $gennet->messages()->sendDynamic(
    sid: 'GENNET',
    messages: [
        new DynamicMessage(msisdn: '8801712345678', text: 'Hello A', csmsId: 'MSG1001'),
        new DynamicMessage(msisdn: '8801812345678', text: 'Hello B', csmsId: 'MSG1002'),
    ],
);
```

### Status, balance, transfer, and incoming SMS

[](#status-balance-transfer-and-incoming-sms)

```
$gennet->messages()->status(csmsId: 'ORDER1001');
$gennet->balance()->get();
$gennet->balance()->transfer(sid: 'GENNET', toSid: 'OTHER_SID', amount: 100.0);
$gennet->incoming()->list();
```

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

[](#configuration)

```
$gennet = new GennetClient(
    apiToken: getenv('GENNET_API_TOKEN'),
    baseUrl: 'https://isms.gennet.com.bd',
    timeout: 15.0,
    connectTimeout: 5.0,
    endpoints: [
        'send' => '/api/v3/sms-send',
        // Only /api/v3/sms-send is confirmed against production today.
        // Override the rest here once your account's routes are confirmed.
        'bulk' => '/api/v3/sms-send-bulk',
        'dynamic' => '/api/v3/sms-send-dynamic',
        'status' => '/api/v3/sms-status',
        'balance' => '/api/v3/balance',
        'transfer' => '/api/v3/balance-transfer',
        'incoming' => '/api/v3/incoming',
    ],
);
```

> **Note:** Only `POST /api/v3/sms-send` is confirmed against the production API at this time. The other endpoint paths above are placeholders — pass your account's real values via the `endpoints` option once confirmed. See "API routes requiring confirmation" below.

Authentication
--------------

[](#authentication)

The SDK sends the configured API token via the `X-API-TOKEN` header by default:

```
X-API-TOKEN:

```

The token is never logged, and it is redacted from any exception message before the exception is thrown. Query-parameter authentication is not used.

Error handling
--------------

[](#error-handling)

The Gennet SMS API can return HTTP 200 with an internal failure payload, e.g.:

```
{
  "status": "FAILED",
  "status_code": 4029,
  "status_meaning": "Too many requests",
  "description": "..."
}
```

The SDK inspects the JSON body on every response — not just the HTTP status code — and converts internal failures into typed exceptions:

- `Gennet\Sms\Exceptions\GennetException` — base class for all SDK exceptions.
- `ApiException` — generic API-level failure.
- `AuthenticationException` — invalid/expired token.
- `ValidationException` — invalid parameters caught locally, before any HTTP call.
- `RateLimitException` — thrown for `status_code: 4029` ("Too many requests").
- `InsufficientBalanceException` — thrown when the account balance is too low.
- `TransportException` — network/connection failures (DNS, timeout, etc.).
- `ServerException` — HTTP 5xx or unparsable responses.

```
use Gennet\Sms\Exceptions\RateLimitException;
use Gennet\Sms\Exceptions\GennetException;

try {
    $gennet->messages()->send(sid: 'GENNET', msisdn: '8801712345678', message: 'Hi', csmsId: 'ORDER1001');
} catch (RateLimitException $e) {
    // back off and retry later, at the caller's discretion
} catch (GennetException $e) {
    // any other SDK error
}
```

Retry policy
------------

[](#retry-policy)

The SDK **never** automatically retries SMS-sending requests (`send`, `sendBulk`, `sendDynamic`, `transfer`), because the API does not yet guarantee idempotency for these calls. Automatic retries are only safe to consider for read-only requests such as `status`, `balance()->get()`, and `incoming()->list()`, and even then the SDK leaves that decision to the caller.

Testing
-------

[](#testing)

The SDK is fully testable without calling production by injecting a Guzzle client backed by `GuzzleHttp\Handler\MockHandler`:

```
use Gennet\Sms\GennetClient;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;

$mock = new MockHandler([
    new Response(200, [], json_encode(['status' => 'SUCCESS'])),
]);
$guzzle = new Client(['handler' => HandlerStack::create($mock)]);

$gennet = new GennetClient(apiToken: 'test-token', httpClient: $guzzle);
```

Run the test suite:

```
composer install
vendor/bin/phpunit
```

API routes still requiring confirmation
---------------------------------------

[](#api-routes-still-requiring-confirmation)

Only `POST /api/v3/sms-send` has been confirmed against the production API. The following endpoint paths are placeholders and must be confirmed (and overridden via the `endpoints` constructor option if different) before production use:

- Bulk SMS
- Dynamic SMS
- SMS delivery/status lookup
- SMS balance check
- SMS balance transfer
- Incoming SMS list

License
-------

[](#license)

MIT

###  Health Score

20

—

LowBetter than 12% of packages

Maintenance65

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 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.

### 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)")

### Embed Badge

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

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

PHPackages © 2026

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