Easily integrate multiple SMS gateways into your Laravel application with a unified API.
- Twilio
- AlphaBd
- BulkSmsDhaka
- SSL Wireless (ISMS Plus)
- Log (for local/staging environments)
- Add the repository to your
composer.json:
"repositories": [
{
"type": "vcs",
"url": "https://gitlab.com/enzaime/sms.git"
}
]- Require the package:
composer require enzaime/smsTwilio Driver:
Requires the Twilio PHP SDK (
twilio/sdk).This package includes it, but if you use Twilio elsewhere, ensure it is installed:
composer require twilio/sdk
Add the following to your .env file:
SMS_DEFAULT_DRIVER=twilio|alpha_bd|bulk_sms_dhaka|ssl_wireless|log
TWILIO_SID=your-twilio-sid
TWILIO_AUTH_TOKEN=your-twilio-auth-token
TWILIO_NUMBER=your-twilio-number
BULKSMSDHAKA_API_KEY=your-bulksmsdhaka-api-key
BULKSMSDHAKA_CALLER_ID=your-bulksmsdhaka-caller-id
SSLWIRELESS_API_TOKEN=your-isms-plus-api-token
SSLWIRELESS_SID=your-approved-sender-id
# Only needed for the secure OTP route
SSLWIRELESS_SECRET_KEY=your-isms-plus-secret-key
# Optional; defaults to https://smsplus.sslwireless.com/api/v3
SSLWIRELESS_API_URL=https://smsplus.sslwireless.com/api/v3Twilio: Recipient number must be in international format (e.g.,
+8801xxxxxxxxx).
EnzSms::driver('ssl_wireless')->send('01xxxxxxxxx', 'Testing');
EnzSms::driver('ssl_wireless')->send(['01xxxxxxxxx', '01yyyyyyyyy'], 'Testing');Things worth knowing before you point production at it:
- The sending IP must be whitelisted in the ISMS Plus portal, or every
request comes back
4003 IP Blacklisted— as an HTTP 200. send()returns the number of recipients the gateway accepted, which is not always the number it was handed: the gateway reports a verdict per recipient insmsinfo, and every refusal is logged with its reason.- Numbers are normalised to MSISDN form (
01712345678and+8801712345678both become8801712345678), and a number repeated within one call is sent once — the gateway refuses a duplicate rather than delivering it twice. - A list is split at 100 recipients per request, the gateway's cap, and goes to the bulk endpoint; a single number goes to the single-send endpoint.
- Neither the API token nor the message body ever reaches a log line.
One-time codes have their own endpoint, and it is worth using: the body is encrypted, the request is signed, and the gateway rate-limits it per recipient (code 4033) in a way the ordinary route does not.
EnzSms::driver('ssl_wireless')->sendOtp('01xxxxxxxxx', 'Your code is 123456');- Requires
SSLWIRELESS_SECRET_KEY(the Secret Key from the portal, which is not the API key). Without itsendOtp()refuses and logs — it will not quietly fall back to the plain route and put the code on the wire in clear text. - The body is AES-256-CBC encrypted under a key derived from the Secret Key,
with a fresh IV per message, and the request carries an HMAC-SHA256
X-Signature. A4035in the log means the signature did not match. - The route takes one recipient at a time; a list becomes one request each.
- Drivers offering this expose
Enzaime\Sms\Contracts\OtpContract, so a caller can check before reaching for it:
$driver = EnzSms::getDriver('ssl_wireless');
if ($driver instanceof \Enzaime\Sms\Contracts\OtpContract) {
$driver->sendOtp($number, $code);
}The Log driver is ideal for development and staging. Instead of sending SMS, it logs messages to your Laravel log files.
To use:
- Set in
.env:SMS_DEFAULT_DRIVER=log
- Or specify in code:
EnzSms::driver('log')->send('01xxxxxxxxx', 'This will be logged, not sent');
Check storage/logs/laravel.log for logged SMS messages.
EnzSms::send('01xxxxxxxxx', 'Testing');$sms = new \Enzaime\Sms\SmsService();
$sms->send('01xxxxxxxxx', 'Testing');EnzSms::driver('twilio')->send('+8801xxxxxxxxx', 'Testing');Note:
- If no driver is specified, Bangladeshi numbers use the default driver (
bulk_sms_dhakaoralpha_bd), foreign numbers usetwilio.
driver(string $name = '')— Set the driver for sending SMS. Returns the SmsService instance for chaining.send(string|array $numberOrList, string $text, string $type = '')— Send SMS to one or multiple numbers.isLocal(string $number)— Check if a number is local (Bangladeshi).getDriver(string $driver = '')— Get the current driver instance.getFallbackDriver()— Get the fallback driver instance.
You can use the SMS channel in your Laravel notifications:
use Illuminate\Notifications\Notification;
class InvoicePaid extends Notification
{
public function via($notifiable)
{
return ['sms'];
}
public function toSms($notifiable)
{
return 'Your invoice has been paid!';
}
}- Register the channel in your
NotificationServiceProviderif needed. - Your notifiable model should have a
mobileorcontact_noproperty, or arouteNotificationForSmsmethod.
To use a custom driver:
EnzSms::driver('custom_driver')->send('01xxxxxxxxx', 'Custom driver test');MIT