Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Sms Laravel Package

ibrand/laravel-sms

ibrand/laravel-sms is a Laravel package that simplifies sending SMS messages from your application. It provides a consistent API for working with SMS gateways, so you can plug in a provider, send notifications or verification codes, and keep SMS logic cleanly separated from your business code.

View on GitHub
Deep Wiki
Context7

Getting Started

Install

composer require ibrand/laravel-sms

The package ships with Laravel auto-discovery, so on 5.5+ the service provider and Sms facade are registered automatically. On older versions add iBrand\Sms\ServiceProvider to config/app.php and alias the facade.

Publish and inspect the config first

php artisan vendor:publish --provider="iBrand\Sms\ServiceProvider"

This drops a config/ibrand-sms.php (name may vary slightly by tag) containing the default gateway plus a gateways array. Read this file before touching code — it tells you exactly which drivers are shipped and which credential keys each one expects (aliyun, yunpian, tencent-cloud, etc.). That config file is the authoritative documentation for this package, more so than the README.

Fill in credentials Each gateway block wants its own set: access key/secret, sign name (sign_name), and — for Aliyun-style gateways — a pre-approved template_code plus a param mapping. Prefer wiring these through .env so they survive config:cache.

First use case — a single OTP send

use iBrand\Sms\Facades\Sms;

Sms::make()->send('13800138000', '您的验证码是 1234,5 分钟内有效。');

The make() call returns a fresh sender bound to the configured default gateway; send() is the one method you'll use 90% of the time. For template-based gateways the second argument becomes an array of template variables instead of free text — check the driver you're using.

Implementation Patterns

Wrap it behind your own service, don't sprinkle the facade everywhere

namespace App\Services;

use iBrand\Sms\Facades\Sms;

class SmsService
{
    public function sendCode(string $mobile, string $code): bool
    {
        $result = Sms::make('aliyun')->send($mobile, [
            'code' => $code,
        ]);

        // Gateway responses typically come back as an array with
        // Code/Message keys — normalise before returning.
        return ($result['Code'] ?? $result['code'] ?? 0) === 'OK';
    }
}

This isolates the package's array-shaped response contract in one place. When you eventually migrate off this package (see Gotchas), you rewrite one class instead of 40 call sites.

Explicit gateway per call site Sms::make() with no argument uses default from config; Sms::make('yunpian') pins a specific driver. Use the explicit form anywhere the channel actually matters (marketing blasts vs. OTP), and keep the default for fire-and-forget internal alerts.

Queue it, always

public function handle()
{
    Sms::make()->send($this->mobile, $this->message);
}

There is no built-in retry, queueing, or rate limiting in this package. Every production send should go through a ShouldQueue job where you control $tries, $backoff, and throttling via Redis::throttle(). Put a per-number throttle in front of the job dispatch too — carriers in China will block your sign name fast if you burst.

Template-driven messages For gateways like Aliyun the message body is fixed server-side and you only supply variables. Build a small map of your own logical message types (otp, order_shipped, payment_failed) to the gateway's template_code + param keys, so application code never hardcodes a provider's template ID:

$templates = [
    'otp' => ['template' => 'SMS_123456', 'vars' => fn($code) => ['code' => $code]],
];

Laravel notification channel (optional) If you want $user->notify(new SendOtp($code)), write a small NotificationChannel that delegates to your SmsService. The package doesn't ship one, but it's ~20 lines and keeps SMS consistent with mail/database notifications.

Gotchas and Tips

The release date is the headline risk. Last tagged release is January 2020. That predates Laravel 7, and certainly predates the PHP 8.1 deprecation wave. Expect to hit: ReturnTypeWillChange warnings, str_random()-era helpers, and typed-property incompatibilities in whichever Aliyun/cloud SDK it pulls in. Pin laravel/framework and php in your composer.json before you discover this in staging. For anything on Laravel 9+, budget time to fork and patch — do not assume it installs cleanly.

Config caching silently breaks driver overrides. Because gateways read config at resolution time, anything you mutate at runtime (config(['ibrand-sms.gateways.aliyun.key' => ...])) is ignored once php artisan config:cache has run. Push all credentials into .env and rebuild the cache on deploy.

make() is the reset button. The underlying manager caches the resolved driver. If you send via aliyun, then try to send via yunpian on the same manager instance, you may get the first driver again. Always re-call Sms::make($gateway) rather than reusing a Sms instance across gateways.

Responses are inconsistent across drivers. Aliyun returns ['Code' => 'OK', 'Message' => ...], Yunpian returns a different shape, and network failures might surface as an exception or as a falsy return depending on the driver's HTTP client. Do not write if (Sms::make()->send(...)) — write an explicit normaliser per driver, and wrap every call in a try/catch since the package's error handling is inconsistent.

Template variable mismatches fail at the gateway, not in PHP. Aliyun will reject your send with a cryptic isv.SMS_TEMPLATE_ILLEGAL-style error if a param key or the sign name doesn't match the approved template exactly. Log the raw response body in non-production — the exception message alone often hides the useful part.

Phone numbers must match the gateway's expected format. Chinese gateways want 13800138000; international drivers want the +86 prefix. Validate and normalise at the boundary of your SmsService, not inside the package — it does no normalisation.

Extension point: custom drivers. If you need an in-house or regional provider, the package is driver-oriented — implement whichever gateway contract the manager expects, bind it via the gateways config (usually 'driver' => 'your-name' plus a extensions / manager-extend() hook), and you're done. This is the cleanest way to keep using the package while modernising behind it.

No observability. There are no events, no logging hooks, and no metrics. If you're sending at any volume, wrap send() with your own instrumentation (success/failure counts by gateway, latency, provider error codes) — otherwise you'll find out about a dead gateway from a customer, not a dashboard.

Verdict for day-to-day use: treat this as a thin, mostly-frozen adapter over Chinese SMS gateways. It's fine as a quick integration if you're on Laravel 6/7, but given the 2020 last release and near-zero dependents, plan the escape hatch up front — keep every call behind your own SmsService interface so swapping to a maintained package (or a direct SDK call) later is a one-file change.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager