PHPackages                             gatewire/client - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. gatewire/client

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

gatewire/client
===============

Official PHP SDK for the GateWire SMS Infrastructure.

00PHP

Since Mar 3Pushed 2mo agoCompare

[ Source](https://github.com/md-lotfi/gatewire-php)[ Packagist](https://packagist.org/packages/gatewire/client)[ RSS](/packages/gatewire-client/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

GateWire PHP SDK
================

[](#gatewire-php-sdk)

[![Latest Stable Version](https://camo.githubusercontent.com/13cc58835fe9689a93bbe915e8a47b52ca76d076671e0c2a5681b0ae35af53f9/68747470733a2f2f706f7365722e707567782e6f72672f67617465776972652f636c69656e742f762f737461626c65)](https://packagist.org/packages/gatewire/client)[![License](https://camo.githubusercontent.com/99d94a2e0982fa66f765922f17b75a615d6d9475feed314caf897037716ea3fb/68747470733a2f2f706f7365722e707567782e6f72672f67617465776972652f636c69656e742f6c6963656e7365)](https://packagist.org/packages/gatewire/client)

The official PHP library for the **[GateWire SMS Infrastructure](https://gatewire.raystate.com)**.

GateWire is a decentralized mesh network that lets developers send OTPs to North African carriers (**Mobilis**, **Djezzy**, **Ooredoo**) reliably and at a fraction of the cost of international gateways.

---

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

[](#requirements)

- PHP **8.1** or higher
- [Composer](https://getcomposer.org/)
- `guzzlehttp/guzzle` — installed automatically by Composer

---

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

[](#installation)

```
composer require gatewire/client
```

---

Quick Start
-----------

[](#quick-start)

The typical OTP flow uses three methods in sequence.

### 1. Initialize the client

[](#1-initialize-the-client)

Obtain your API token from the [GateWire Dashboard](https://gatewire.raystate.com).

```
require 'vendor/autoload.php';

use GateWire\GateWire;

$gw = new GateWire('YOUR_API_TOKEN');
```

### 2. Send an OTP

[](#2-send-an-otp)

```
use GateWire\Exceptions\GateWireException;

try {
    $res = $gw->dispatch('+213555123456', 'login_otp');
    // $res['reference_id'] => "wg_01HX..."
    // $res['status']       => "pending"

    $referenceId = $res['reference_id'];
} catch (GateWireException $e) {
    echo 'Error ' . $e->getCode() . ': ' . $e->getMessage();
}
```

The second argument (`template_key`) is optional. When omitted, the backend uses your account's default OTP template. The message content is always controlled server-side — there is no message body parameter.

### 3. Verify the OTP

[](#3-verify-the-otp)

Once the user submits the code they received, verify it:

```
try {
    $result = $gw->verifyOtp($referenceId, $userEnteredCode);
    // $result['status']  => "verified"
    // $result['message'] => "Success"
} catch (GateWireException $e) {
    // code 400: invalid, expired, cancelled, or already used
    echo 'Verification failed: ' . $e->getMessage();
}
```

### 4. Check OTP status

[](#4-check-otp-status)

Poll or webhook-verify the delivery status at any point:

```
$info = $gw->status($referenceId);
// $info['reference_id'] => "wg_01HX..."
// $info['status']       => "sent"
// $info['created_at']   => "2026-03-03T14:22:00Z"
```

---

OTP Lifecycle
-------------

[](#otp-lifecycle)

```
pending → dispatched → sent → verified          (happy path)
                            → failed            (delivery failed)
                            → expired           (code TTL exceeded)
                            → cancelled         (manually cancelled)

```

StatusMeaning`pending`OTP queued, awaiting a device to pick it up`dispatched`Assigned to a device, being sent`sent`Delivered to the carrier`verified`User entered the correct code`failed`Delivery failed (device error, carrier rejection)`expired`Code TTL exceeded before verification`cancelled`OTP was cancelled before delivery---

Laravel Integration
-------------------

[](#laravel-integration)

### Register a singleton in `app/Providers/AppServiceProvider.php`

[](#register-a-singleton-in-appprovidersappserviceproviderphp)

```
use GateWire\GateWire;

public function register(): void
{
    $this->app->singleton(GateWire::class, function () {
        return new GateWire(config('services.gatewire.key'));
    });
}
```

### Add credentials to `config/services.php`

[](#add-credentials-to-configservicesphp)

```
'gatewire' => [
    'key' => env('GATEWIRE_API_KEY'),
],
```

### Add the key to `.env`

[](#add-the-key-to-env)

```
GATEWIRE_API_KEY=your_api_token_here

```

### Use via dependency injection

[](#use-via-dependency-injection)

```
use GateWire\GateWire;
use GateWire\Exceptions\GateWireException;

class OtpController extends Controller
{
    public function send(Request $request, GateWire $gw): JsonResponse
    {
        try {
            $res = $gw->dispatch($request->input('phone'), 'login_otp');
            return response()->json(['reference_id' => $res['reference_id']]);
        } catch (GateWireException $e) {
            return response()->json(['error' => $e->getMessage()], $e->getCode() ?: 500);
        }
    }

    public function verify(Request $request, GateWire $gw): JsonResponse
    {
        try {
            $gw->verifyOtp($request->input('reference_id'), $request->input('code'));
            return response()->json(['verified' => true]);
        } catch (GateWireException $e) {
            return response()->json(['error' => $e->getMessage()], 400);
        }
    }
}
```

---

Error Handling
--------------

[](#error-handling)

All API errors throw `GateWire\Exceptions\GateWireException`. The exception code matches the HTTP status code returned by the server.

```
use GateWire\Exceptions\GateWireException;

try {
    $res = $gw->dispatch('+213555123456', 'login_otp');
} catch (GateWireException $e) {
    match ($e->getCode()) {
        400 => /* Invalid or expired OTP code (during verifyOtp) */,
        402 => /* Insufficient balance — top up your account */,
        429 => /* Daily or hourly OTP limit reached */,
        503 => /* No available devices in the network right now */,
        default => /* Unexpected server error */,
    };
}
```

CodeMeaning400Invalid, expired, cancelled, or already-used OTP code402Insufficient balance429Daily OTP limit or hourly bonus credit limit reached503No available devices to dispatch the OTP500Unexpected server-side error---

API Reference
-------------

[](#api-reference)

Base URL: `https://gatewire.raystate.com/api/v1`

MethodHTTP callDescription`dispatch(phone, templateKey?)``POST /send-otp`Send an OTP`verifyOtp(referenceId, code)``POST /verify-otp`Verify an OTP code`status(referenceId)``GET  /status/{reference_id}`Check OTP status---

Testing
-------

[](#testing)

The SDK ships with a PHPUnit 10 test suite covering all public methods, request shapes, and error paths. No network calls are made — responses are mocked with Guzzle's `MockHandler`.

Install dev dependencies and run the suite:

```
composer install
composer test
# or directly:
./vendor/bin/phpunit
```

Expected output:

```
PHPUnit 10.5.x by Sebastian Bergmann and contributors.

......................                                            22 / 22 (100%)

OK (22 tests, 45 assertions)

```

**Coverage:**

Test fileWhat is tested`tests/GateWireTest.php``dispatch()`, `verifyOtp()`, `status()` — success responses, request body shape, correct HTTP method + endpoint path, all documented error codes (400, 402, 429, 503, 500), non-JSON response guard`tests/GateWireExceptionTest.php``GateWireException::fromResponse()` — message, code, instance type---

Support
-------

[](#support)

- **Issues:** [GitHub Issues](https://github.com/md-lotfi/gatewire-php/issues)
- **Email:**

License
-------

[](#license)

The GateWire PHP SDK is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

###  Health Score

19

—

LowBetter than 10% of packages

Maintenance56

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity12

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://www.gravatar.com/avatar/16031f6100b4b011a676e3a4cb9ae75c50e0371c443ea76bc0b9896cbe297724?d=identicon)[md-lotfi](/maintainers/md-lotfi)

---

Top Contributors

[![md-lotfi](https://avatars.githubusercontent.com/u/37027992?v=4)](https://github.com/md-lotfi "md-lotfi (4 commits)")

### Embed Badge

![Health badge](/badges/gatewire-client/health.svg)

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

###  Alternatives

[spatie/ssh

A lightweight package to execute commands over an SSH connection

8322.8M41](/packages/spatie-ssh)[log1x/pagi

A better WordPress pagination.

59105.4k](/packages/log1x-pagi)[kepex/laravel-crud-generator

php artisan command to generate fully working crud with grid paginated server side only by having database tables

10216.7k](/packages/kepex-laravel-crud-generator)

PHPackages © 2026

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