PHPackages                             nugsoft/signalbridge-laravel-sdk - 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. [Mail &amp; Notifications](/categories/mail)
4. /
5. nugsoft/signalbridge-laravel-sdk

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

nugsoft/signalbridge-laravel-sdk
================================

Laravel SDK for SignalBridge SMS Gateway - Send SMS messages through multiple vendors with unified API

v2.0.0(2mo ago)1449MITPHPPHP ^8.1|^8.2|^8.3|^8.4

Since Nov 27Pushed 2mo agoCompare

[ Source](https://github.com/nugsoft/signalbridge-laravel-sdk)[ Packagist](https://packagist.org/packages/nugsoft/signalbridge-laravel-sdk)[ RSS](/packages/nugsoft-signalbridge-laravel-sdk/feed)WikiDiscussions main Synced today

READMEChangelog (2)Dependencies (12)Versions (3)Used By (0)

SignalBridge Laravel SDK
========================

[](#signalbridge-laravel-sdk)

[![Latest Version on Packagist](https://camo.githubusercontent.com/249bf2ff1aca8efd5487eaad6abead91134b176a7c3e71381652694a10628d07/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6e7567736f66742f7369676e616c6272696467652d6c61726176656c2d73646b2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/nugsoft/signalbridge-laravel-sdk)[![Total Downloads](https://camo.githubusercontent.com/bf4bc3efbe4c817a3f16f1a4d04f5bb1dea43cc5dddbd2f61bf2668c78d882fa/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6e7567736f66742f7369676e616c6272696467652d6c61726176656c2d73646b2e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/nugsoft/signalbridge-laravel-sdk)

Official Laravel SDK for [SignalBridge](https://signal-bridge.nugsoftapps.net) — a unified multi-channel communication and payment gateway.

Send SMS, WhatsApp messages, and initiate Mobile Money transactions through a single, clean Laravel API. Built by Nugsoft.

Channels
--------

[](#channels)

ChannelStatusMethods**SMS**✅ Available`send()`, `sendBatch()`, `calculateSegments()`, `estimateCost()`**WhatsApp**✅ Available`send()`, `sendTemplate()`**Mobile Money**✅ Available`initiate()`, `verify()`, `disburse()`**USSD**🔜 Planned`push()`, `session()`, `respond()`Features
--------

[](#features)

- **Multi-channel API** — SMS, WhatsApp, Mobile Money, and USSD (planned) through one SDK
- **Channel-fluent interface** — `SignalBridge::sms()->send(...)`, `SignalBridge::whatsapp()->sendTemplate(...)`
- **Backward compatible** — existing `SignalBridge::sendSms()` calls still work
- **Balance &amp; transaction management** — account-level operations on the main client
- **Webhook management** — full CRUD for outbound event webhooks
- **Export** — download messages and transactions as CSV
- **Typed exceptions** — specific exception classes for each error type
- **Facade + DI support** — use either style
- **Laravel 10, 11, 12, 13** — tested on all current versions
- **PHP 8.1+**

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

[](#requirements)

- PHP 8.1 or higher
- Laravel 10.0, 11.0, 12.0, or 13.0
- Guzzle HTTP 7.0+

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

[](#installation)

```
composer require nugsoft/signalbridge-laravel-sdk
```

Optionally publish the config file:

```
php artisan vendor:publish --tag=signalbridge-config
```

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

[](#configuration)

Add to your `.env`:

```
SIGNALBRIDGE_TOKEN=your_api_token_here
SIGNALBRIDGE_URL=https://signal-bridge.nugsoftapps.net/api
```

**Getting your token:**

```
curl -X POST https://signal-bridge.nugsoftapps.net/api/tokens \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "password": "your-password", "expires_in_days": 365}'
```

> You can also generate tokens from the SignalBridge dashboard under **Settings → API Tokens**.

---

Usage
-----

[](#usage)

### Quick Start

[](#quick-start)

```
use Nugsoft\SignalBridge\Facades\SignalBridge;

// SMS
SignalBridge::sms()->send('256700000000', 'Hello from SignalBridge!');

// WhatsApp
SignalBridge::whatsapp()->send('256700000000', 'Hello on WhatsApp!');

// Mobile Money — collect payment
SignalBridge::mobileMoney()->initiate('256700000000', 5000);

// Mobile Money — send payout
SignalBridge::mobileMoney()->disburse('256700000000', 50000);
```

### Dependency Injection

[](#dependency-injection)

```
use Nugsoft\SignalBridge\SignalBridgeClient;

class NotificationService
{
    public function __construct(private SignalBridgeClient $signalBridge) {}

    public function sendWelcome(string $phone, string $name): void
    {
        $this->signalBridge->sms()->send($phone, "Welcome {$name}!");
    }
}
```

---

SMS
---

[](#sms)

### Send a Single SMS

[](#send-a-single-sms)

```
$result = SignalBridge::sms()->send(
    recipient: '256700000000',
    message: 'Your OTP is 123456',
    options: [
        'sender_id'    => 'MyApp',           // Optional
        'metadata'     => ['user_id' => 42], // Optional: stored for your records
        'is_test'      => false,             // Optional: test mode (no charge)
        'scheduled_at' => '2026-06-01T09:00:00Z', // Optional: ISO 8601
    ]
);
// $result['data']['message_id'], $result['data']['cost'], $result['data']['status']
```

### Send a Batch of SMS

[](#send-a-batch-of-sms)

```
$result = SignalBridge::sms()->sendBatch(
    messages: [
        ['recipient' => '256700000000', 'message' => 'Hi Alice!', 'metadata' => ['user_id' => 1]],
        ['recipient' => '256700000001', 'message' => 'Hi Bob!',   'metadata' => ['user_id' => 2]],
    ],
    options: ['is_test' => false]
);
// $result['data']['successful'], $result['data']['failed']
```

### Segment Calculation &amp; Cost Estimation

[](#segment-calculation--cost-estimation)

```
$sms = SignalBridge::sms();

$segments = $sms->calculateSegments('Hello World'); // 1
$cost     = $sms->estimateCost('Hello World', segmentPrice: 1.00); // 1.00
```

**Encoding rules:**

- GSM 7-bit (standard): 160 chars = 1 segment, 153 chars/segment thereafter
- Unicode (emoji, Arabic, Chinese…): 70 chars = 1 segment, 67 chars/segment thereafter

---

WhatsApp
--------

[](#whatsapp)

### Send a Plain Message

[](#send-a-plain-message)

```
SignalBridge::whatsapp()->send(
    recipient: '256700000000',
    message: 'Your order #1234 has been shipped.',
    options: ['metadata' => ['order_id' => 1234]]
);
```

### Send a Template Message

[](#send-a-template-message)

Templates must be pre-approved in [Meta Business Manager](https://business.facebook.com).

```
SignalBridge::whatsapp()->sendTemplate(
    recipient: '256700000000',
    templateName: 'order_confirmation',
    components: [
        [
            'type' => 'body',
            'parameters' => [
                ['type' => 'text', 'text' => 'Alice'],
                ['type' => 'text', 'text' => '#ORD-9821'],
                ['type' => 'text', 'text' => 'UGX 45,000'],
            ],
        ],
    ],
    options: ['language' => 'en_US']
);
```

---

Mobile Money
------------

[](#mobile-money)

### Collect a Payment (Request-to-Pay)

[](#collect-a-payment-request-to-pay)

```
$tx = SignalBridge::mobileMoney()->initiate(
    phone: '256700000000',
    amount: 15000,
    currency: 'UGX',
    options: [
        'reference'    => 'INV-2026-001',
        'description'  => 'Invoice payment',
        'callback_url' => 'https://yourapp.com/webhooks/momo',
        'metadata'     => ['invoice_id' => 101],
    ]
);

$transactionId = $tx['data']['transaction_id'];
$status        = $tx['data']['status']; // 'pending'
```

### Poll Transaction Status

[](#poll-transaction-status)

```
$result = SignalBridge::mobileMoney()->verify('txn-uuid-here');
// $result['data']['status'] — 'pending' | 'completed' | 'failed'
```

> Prefer webhooks over polling. Register a `callback_url` in `initiate()` or configure a webhook via `createWebhook()`.

### Disburse (Send Money)

[](#disburse-send-money)

```
SignalBridge::mobileMoney()->disburse(
    phone: '256700000000',
    amount: 50000,
    currency: 'UGX',
    options: [
        'reference'   => 'SALARY-APR-2026',
        'description' => 'April salary',
    ]
);
```

---

Account Operations
------------------

[](#account-operations)

These methods are on the main `SignalBridgeClient` and apply across all channels.

### Balance

[](#balance)

```
$balance = SignalBridge::getBalance('UGX');
// ['balance' => 996.0, 'currency' => 'UGX', 'segment_price' => 1.0, ...]

$summary = SignalBridge::getBalanceSummary();
```

### Transaction History

[](#transaction-history)

```
$transactions = SignalBridge::getTransactions([
    'type'       => 'debit',        // 'credit' | 'debit'
    'start_date' => '2026-01-01',
    'end_date'   => '2026-04-30',
    'per_page'   => 50,
    'page'       => 1,
]);
```

### Export Data as CSV

[](#export-data-as-csv)

```
// Save messages to a file
$csv = SignalBridge::exportMessages(['start_date' => '2026-04-01']);
Storage::put('exports/messages.csv', $csv);

// Save transactions to a file
$csv = SignalBridge::exportTransactions(['type' => 'debit']);
Storage::put('exports/transactions.csv', $csv);
```

---

Webhook Management
------------------

[](#webhook-management)

SignalBridge can POST events to your application when message or payment statuses change.

```
// Register a webhook
$webhook = SignalBridge::createWebhook(
    url: 'https://yourapp.com/webhooks/signalbridge',
    events: ['message.delivered', 'message.failed', 'payment.completed'],
    isActive: true
);
$secret = $webhook['data']['secret']; // Store this — shown only once

// List, update, delete
$list = SignalBridge::listWebhooks();
SignalBridge::updateWebhook($webhookId, ['is_active' => false]);
SignalBridge::deleteWebhook($webhookId);

// Rotate secret
$new = SignalBridge::regenerateWebhookSecret($webhookId);
```

**Available events:** `message.sent`, `message.delivered`, `message.failed`, `message.permanently_failed`, `payment.completed`, `payment.failed`, `*` (all)

---

Exception Handling
------------------

[](#exception-handling)

```
use Nugsoft\SignalBridge\Exceptions\InsufficientBalanceException;
use Nugsoft\SignalBridge\Exceptions\InsufficientPermissionsException;
use Nugsoft\SignalBridge\Exceptions\NoClientException;
use Nugsoft\SignalBridge\Exceptions\RateLimitedException;
use Nugsoft\SignalBridge\Exceptions\ServiceUnavailableException;
use Nugsoft\SignalBridge\Exceptions\SignalBridgeException;
use Nugsoft\SignalBridge\Exceptions\UnauthorizedException;
use Nugsoft\SignalBridge\Exceptions\ValidationException;

try {
    SignalBridge::sms()->send('256700000000', 'Hello');

} catch (InsufficientBalanceException $e) {
    $required  = $e->getRequiredBalance();
    $available = $e->getCurrentBalance();

} catch (ValidationException $e) {
    $errors     = $e->getErrors();
    $firstError = $e->getFirstError();

} catch (RateLimitedException $e) {
    // Slow down requests

} catch (ServiceUnavailableException $e) {
    // No active vendor configured

} catch (UnauthorizedException $e) {
    // Invalid or expired token

} catch (InsufficientPermissionsException $e) {
    // Role doesn't have access

} catch (SignalBridgeException $e) {
    $data = $e->getData(); // Raw API response body
}
```

---

Real-World Examples
-------------------

[](#real-world-examples)

### OTP / Verification Code

[](#otp--verification-code)

```
use Nugsoft\SignalBridge\Facades\SignalBridge;
use Illuminate\Support\Facades\Cache;

public function sendOtp(Request $request): \Illuminate\Http\JsonResponse
{
    $code = random_int(100000, 999999);
    Cache::put("otp:{$request->phone}", $code, now()->addMinutes(5));

    SignalBridge::sms()->send(
        recipient: $request->phone,
        message: "Your verification code is {$code}. Valid for 5 minutes.",
        options: ['metadata' => ['action' => 'otp', 'ip' => $request->ip()]]
    );

    return response()->json(['success' => true]);
}
```

### Order Confirmation via WhatsApp Template

[](#order-confirmation-via-whatsapp-template)

```
public function confirmOrder(Order $order): void
{
    SignalBridge::whatsapp()->sendTemplate(
        recipient: $order->customer_phone,
        templateName: 'order_confirmation',
        components: [
            ['type' => 'body', 'parameters' => [
                ['type' => 'text', 'text' => $order->customer_name],
                ['type' => 'text', 'text' => $order->reference],
                ['type' => 'text', 'text' => number_format($order->total) . ' UGX'],
            ]],
        ]
    );
}
```

### Collect Payment and Listen via Webhook

[](#collect-payment-and-listen-via-webhook)

```
// 1. Initiate collection
$tx = SignalBridge::mobileMoney()->initiate(
    phone: $invoice->customer_phone,
    amount: $invoice->total,
    options: [
        'reference'    => $invoice->number,
        'callback_url' => route('webhooks.momo'),
        'metadata'     => ['invoice_id' => $invoice->id],
    ]
);

// 2. Handle webhook (routes/api.php → POST /webhooks/momo)
public function handle(Request $request): \Illuminate\Http\Response
{
    $status = $request->input('status');   // 'completed' | 'failed'
    $meta   = $request->input('metadata');

    if ($status === 'completed') {
        Invoice::find($meta['invoice_id'])->markPaid();
    }

    return response()->noContent();
}
```

### Batch SMS from Database

[](#batch-sms-from-database)

Fetch phone numbers from your database and send in batches. The API accepts up to 100 messages per request, so chunk large datasets accordingly.

```
use App\Models\User;
use Nugsoft\SignalBridge\Facades\SignalBridge;

// Simple — send one message to all active users
User::where('is_active', true)
    ->select('phone', 'name')
    ->chunk(100, function ($users) {
        $messages = $users->map(fn ($user) => [
            'recipient' => $user->phone,
            'message'   => "Hi {$user->name}, your account has been updated.",
            'metadata'  => ['user_id' => $user->id],
        ])->toArray();

        SignalBridge::sms()->sendBatch($messages);
    });
```

```
// Personalised messages — different content per recipient
$notifications = Notification::with('user')
    ->where('status', 'pending')
    ->get()
    ->chunk(100);

foreach ($notifications as $batch) {
    $messages = $batch->map(fn ($n) => [
        'recipient' => $n->user->phone,
        'message'   => $n->body,
        'metadata'  => ['notification_id' => $n->id],
    ])->toArray();

    $result = SignalBridge::sms()->sendBatch($messages);

    // Mark sent
    $batch->each->update(['status' => 'sent']);
}
```

```
// With balance check before sending
$phones  = User::where('subscribed', true)->pluck('phone');
$balance = SignalBridge::getBalance('UGX');
$cost    = $phones->count() * SignalBridge::sms()->calculateSegments($message) * $balance['segment_price'];

if ($balance['available_balance'] < $cost) {
    throw new \RuntimeException("Insufficient balance. Need {$cost} UGX, have {$balance['available_balance']} UGX.");
}

$phones->chunk(100)->each(function ($chunk) use ($message) {
    SignalBridge::sms()->sendBatch(
        $chunk->map(fn ($phone) => ['recipient' => $phone, 'message' => $message])->toArray()
    );
});
```

---

Configuration Reference
-----------------------

[](#configuration-reference)

```
// config/signalbridge.php
return [
    'url'               => env('SIGNALBRIDGE_URL', 'https://signal-bridge.nugsoftapps.net/api'),
    'token'             => env('SIGNALBRIDGE_TOKEN'),
    'timeout'           => env('SIGNALBRIDGE_TIMEOUT', 30),
    'default_sender_id' => env('SIGNALBRIDGE_SENDER_ID'),
    'logging'           => env('SIGNALBRIDGE_LOGGING', true),
];
```

VariableRequiredDefaultDescription`SIGNALBRIDGE_TOKEN`✅—API authentication token`SIGNALBRIDGE_URL`❌Production URLAPI base URL`SIGNALBRIDGE_TIMEOUT`❌`30`HTTP request timeout (seconds)`SIGNALBRIDGE_SENDER_ID`❌—Default SMS sender ID (max 11 chars)`SIGNALBRIDGE_LOGGING`❌`true`Log API errors to Laravel log**Laravel compatibility:** 10, 11, 12, 13

---

Testing
-------

[](#testing)

```
composer test
```

License
-------

[](#license)

MIT. See [LICENSE](LICENSE).

Credits
-------

[](#credits)

- **Asaba William** — CTO

---

**Made with ❤️ by Nugsoft**

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance86

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity54

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

Every ~147 days

Total

2

Last Release

72d ago

Major Versions

v1.0.0 → v2.0.02026-04-23

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/110377726?v=4)[Nugsoft Technologies](/maintainers/Nugsoft)[@nugsoft](https://github.com/nugsoft)

---

Top Contributors

[![Williamug](https://avatars.githubusercontent.com/u/15543507?v=4)](https://github.com/Williamug "Williamug (20 commits)")

---

Tags

laravelmobile-moneysmsussdwhatsapplaravelnotificationssmsmessagingsignalbridgenugsoftafrica-talkingspeedamobile

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/nugsoft-signalbridge-laravel-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/nugsoft-signalbridge-laravel-sdk/health.svg)](https://phpackages.com/packages/nugsoft-signalbridge-laravel-sdk)
```

###  Alternatives

[laravel/socialite

Laravel wrapper around OAuth 1 &amp; OAuth 2 libraries.

5.7k108.5M887](/packages/laravel-socialite)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M131](/packages/roots-acorn)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)[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.

5022.0k](/packages/simplestats-io-laravel-client)[api-platform/laravel

API Platform support for Laravel

58171.6k14](/packages/api-platform-laravel)

PHPackages © 2026

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