smsgist / smsgist-php
PHP SDK for the SMSGist messaging platform — send SMS and email from any PHP application
Requires
- php: ^8.1
- ext-curl: *
- ext-json: *
- ext-mbstring: *
- ext-openssl: *
Requires (Dev)
- phpunit/phpunit: ^10.0
- psr/log: ^3.0
Suggests
- psr/log: Required for custom logger support (PSR-3)
README
PHP SDK for the SMSGist messaging platform. Send SMS and email from any PHP application.
Works with vanilla PHP, Laravel, Symfony, or any PHP 8.1+ project.
Installation
composer require smsgist/smsgist-php
Configuration
Set these environment variables:
SMSGIST_CLIENT_ID=your-client-id
SMSGIST_CLIENT_SECRET=your-client-secret
SMSGIST_APP_KEY=your-32-byte-encryption-key
SMSGIST_URI=https://api.smsgist.com
Get your credentials from the SMSGist Dashboard.
Quick Start
use SMSGist\Client;
$client = Client::create();
// Send SMS
$response = $client->send('sms')
->to('0240000001')
->from('MyApp')
->message('Hello from SMSGist!')
->exec();
echo $response->messageId; // "9b1deb4d-3b7d-..."
echo $response->status; // "queued"
echo $response->totalCost; // 0.03
Sending SMS
// Basic SMS
$response = $client->send('sms')
->to('0240000001', '0240000002')
->from('MyApp')
->message('Hello World')
->exec();
// OTP with priority routing
$response = $client->send('sms')
->to('0240000001')
->messageOtp('Your verification code is 123456')
->exec();
// With idempotency key (prevents duplicate sends)
$response = $client->send('sms')
->to('0240000001')
->message('Order #1234 confirmed')
->idempotencyKey('order-confirm-1234')
->exec();
Sending Email
// Basic email
$response = $client->send('email')
->to('user@example.com')
->from('My App')
->subject('Welcome!')
->message('<h1>Hello</h1><p>Welcome to our platform.</p>')
->exec();
// With reply-to and attachments
$response = $client->send('email')
->to('user@example.com')
->from('Billing')
->subject('Your Invoice')
->message('<p>Please find your invoice attached.</p>')
->replyTo('billing@myapp.com')
->attachFile('/path/to/invoice.pdf')
->attach('summary.csv', $csvContent)
->exec();
// Disable open/click tracking
$response = $client->send('email')
->to('user@example.com')
->subject('Password Reset')
->message('<p>Click <a href="https://myapp.com/reset/abc123">here</a> to reset.</p>')
->noTracking()
->exec();
Response Objects
SendResponse
Returned by exec():
$response->messageId; // string — unique message ID
$response->status; // "queued", "sent", "dryrun"
$response->recipientsCount; // int
$response->segments; // int (SMS only, 0 for email)
$response->totalCost; // float
$response->costPerUnit; // float
$response->recipients; // RecipientRef[] — per-recipient tracking IDs
Delivery Status
$status = $client->getDeliveryStatus($response->messageId);
$status->messageId;
$status->status; // "queued", "sending", "sent"
$status->totalRecipients; // int
$status->delivered; // int
$status->pending; // int
$status->failed; // int
foreach ($status->recipients as $r) {
echo $r->recipient; // "0240000001"
echo $r->sendStatus; // "sent"
echo $r->deliveryStatus; // "delivered"
echo $r->deliveredAt; // DateTimeImmutable or null
echo $r->error; // null or error message
}
Retry Failed Messages
$retryResponse = $client->retry($messageId);
// Returns a new SendResponse with a new messageId
Credit Balance
$credits = $client->getCreditBalance();
$credits->balance; // 150.50
$credits->reserved; // 10.00
$credits->available; // 140.50
$credits->currency; // "GHS"
Webhooks
SMSGist sends webhook events when message status changes. Verify incoming webhooks:
use SMSGist\Webhook;
use SMSGist\Events;
// Verify the signature (HMAC-SHA256 + replay protection)
$isValid = Webhook::verifySignature(
body: file_get_contents('php://input'),
signature: $_SERVER['HTTP_X_SMSGIST_SIGNATURE'],
timestamp: $_SERVER['HTTP_X_SMSGIST_TIMESTAMP'],
secret: 'your-webhook-secret',
);
if (!$isValid) {
http_response_code(401);
exit;
}
// Parse the event
$event = Webhook::parse(file_get_contents('php://input'));
switch ($event->event) {
case Events::MESSAGE_DELIVERED:
// Mark message as delivered in your system
break;
case Events::MESSAGE_FAILED:
// Handle failure
break;
case Events::MESSAGE_OPENED:
// Track email open
break;
}
Event Types
| Constant | Value | Channel |
|---|---|---|
Events::MESSAGE_QUEUED | message.queued | SMS, Email |
Events::MESSAGE_SENT | message.sent | SMS, Email |
Events::MESSAGE_DELIVERED | message.delivered | SMS, Email |
Events::MESSAGE_FAILED | message.failed | SMS, Email |
Events::MESSAGE_OPENED | message.opened | Email only |
Events::MESSAGE_CLICKED | message.clicked | Email only |
Events::MESSAGE_BOUNCED | message.bounced | Email only |
Events::MESSAGE_COMPLAINED | message.complained | Email only |
Modes
Control how messages are sent during development:
use SMSGist\Mode;
// Dry run — logs only, no real sends
$client = Client::create(['mode' => Mode::DryRun]);
// Test — sends to test phone/email instead of real recipients
$client = Client::create([
'mode' => Mode::Test,
'test_phone' => '0240000000',
'test_email' => 'dev@myapp.com',
]);
// Live — sends to real recipients (default)
$client = Client::create(['mode' => Mode::Live]);
| Mode | SMS | |
|---|---|---|
| Live | Sends to real recipients | Sends to real recipients |
| Test | Sends to test_phone | Sends to test_email |
| DryRun | Logs only | Sends to test_email if set, otherwise logs only |
The backend credential mode is the source of truth. Client-level mode override is for local development only.
Error Handling
All errors throw exceptions:
use SMSGist\Exception\SMSGistException;
use SMSGist\Exception\ValidationException;
use SMSGist\Exception\ApiException;
use SMSGist\Exception\MissingConfigException;
try {
$response = $client->send('sms')
->to('0240000001')
->message('Hello')
->exec();
} catch (ValidationException $e) {
// Missing recipients, empty message, etc.
} catch (ApiException $e) {
echo $e->statusCode; // HTTP status code
echo $e->responseBody; // Raw response body
} catch (SMSGistException $e) {
// Any other SDK error
}
Laravel Integration
The package auto-discovers in Laravel. No manual registration needed.
Publish Config
php artisan vendor:publish --tag=smsgist-config
This creates config/smsgist.php where you can customize settings.
Using the Facade
use SMSGist\Laravel\Facades\SMSGist;
$response = SMSGist::send('sms')
->to('0240000001')
->message('Hello from Laravel!')
->exec();
Using Dependency Injection
use SMSGist\Client;
class NotificationController extends Controller
{
public function __construct(private Client $smsgist) {}
public function sendWelcome(string $phone)
{
return $this->smsgist->send('sms')
->to($phone)
->message('Welcome!')
->exec();
}
}
Webhook Route (Laravel)
// routes/api.php
Route::post('/webhooks/smsgist', function (Request $request) {
$isValid = Webhook::verifySignature(
body: $request->getContent(),
signature: $request->header('X-SMSGist-Signature'),
timestamp: $request->header('X-SMSGist-Timestamp'),
secret: config('smsgist.webhook_secret'),
);
if (!$isValid) {
return response('Invalid signature', 401);
}
$event = Webhook::parse($request->getContent());
// Handle event...
return response('OK', 200);
});
Requirements
- PHP 8.1+
- ext-curl
- ext-json
- ext-openssl
- ext-mbstring
License
MIT