laravel-notification-channels/smsc-ru
Laravel notification channel for SMS.ru, letting you send SMS through the SMS.ru API using Laravel's built-in notification system. Configure your API credentials, define a notification, and deliver messages with a simple channel integration.
Architecture fit
This is a channel adapter, not a framework. It plugs into Laravel's existing notification pipeline (Notifiable → Notification::send() → channel driver), which means it inherits routing, queueing, and via() channel selection from the host application. For a Laravel codebase already using notifications for email, the architectural footprint is one toSmscru() method per notification class plus a published config file. That is about as low-friction as third-party integration gets, and it also means the package is trivially replaceable — there is no data model, no migrations, no service container coupling beyond a single ServiceProvider.
The structural weakness is the same as its strength: it is a thin HTTP wrapper with no abstraction layer. There is no provider-agnostic SmsChannel interface, so swapping vendors later means editing every notification class that calls SmscRuMessage::create(). If SMS is a peripheral feature, this is fine. If SMS becomes a primary auth or alerting path, the coupling is worth pre-empting.
Integration feasibility
Low effort, roughly one developer-day end to end including staging verification against real handset numbers. The standard flow is: composer require, publish config, set SMSCRU_LOGIN / SMSCRU_PASSWORD (or API key) in env, add toSmscru() to notifications, and route via either a routeNotificationForSmscru() method on the notifiable or Notification::route('smscru', $phone). No infrastructure, no webhook endpoint required for outbound-only use.
Two feasibility caveats: the package's credentials are provider-specific (SMSC.ru account with positive balance, sender ID approval in Russia), and the README targets Laravel 5.3 while the April 2025 release suggests later-framework support was retrofitted. Compatibility must be verified rather than assumed.
Technical risk
Overall: low code risk, medium-to-high supply-chain risk.
laravel-notification-channels umbrella. Reported dependents are effectively zero, which is a weak proxy but a real signal that the user base is small and the maintainer has little incentive to keep pace with Laravel releases. The 2025-04-15 release is the countervailing data point — someone is still shipping.send(object $notifiable, Notification $notification) and Laravel 11/12 changed application bootstrapping and config conventions. A package born at 5.3 and last touched in 2025 has probably absorbed these, but that assumption needs a five-minute composer why-not check against your pinned Laravel version.Key questions
composer.json, and has it been tested against Laravel 11/12?Http facade (retryable, mockable, no extra dependency) or a bundled SDK/Guzzle client?send() signature and return type aligned with Laravel 9+ conventions, or is it relying on deprecated contracts?translit, message format (fmt), and sender-ID configuration, or are those hardcoded?Stack fit
Clean fit for Laravel 8+ applications that already use Illuminate\Notifications. It requires no changes to queue workers, no new infrastructure, and no container bindings beyond the auto-discovered service provider. It is a poor fit for non-Laravel PHP, Symfony, or framework-agnostic service architectures — the adapter is inseparable from the notification contract, and there is no standalone SMSC client inside it worth extracting.
Migration path
Two distinct scenarios:
Greenfield SMS: adopt directly. Publish config, wire credentials, add toSmscru() to each notification, route phone numbers. Keep a thin internal wrapper (App\Notifications\Channels\SmsChannel) that delegates to this package so the vendor reference lives in exactly one place — this is cheap insurance and the single most valuable recommendation here.
Replacing an existing SMS path: do not migrate notification classes and vendor simultaneously. Run the new channel behind a feature flag on a via() array that can toggle between providers per notification type, verify parity on delivery, then delete the old channel. Because via() returns an array, side-by-side comparison (or dual-send to a test number) is achievable without code branching.
Compatibility
Verify before committing: pinned Laravel version against the package's composer.json constraints; PHP version (8.1+ likely required by any 2025 release); Guzzle/PHP extensions; and whether the package's config keys match the SMSC API credentials your account actually issues (login/password legacy vs. API key vs. apikey parameter — SMSC has changed its auth story over time). Also confirm your notification classes' toSmscru() return type is SmscRuMessage as the package expects, not a string.
Sequencing
SMSCRU_ENABLED flag.Maintenance
Near-zero runtime maintenance, low but non-zero dependency maintenance. The package adds one composer line; the cost is tracking Laravel majors on its release cadence, which is unpredictable given the project's size. Budget a small annual assessment: does the latest tag still support our Laravel version? If it lags a major, the fallback is a ~150-line in-house channel (the outbound API call is not complex) — a realistic and pre-scoped escape hatch, which is why the internal wrapper matters.
Support
No commercial support. Documentation lives in the README; community support is GitHub issues with a likely multi-day-to-never response window. Internal ownership should rest with the backend team that owns notifications — not with a platform team — because troubleshooting requires reading the package source, which is small enough to do. Document credentials, sender ID, and the provider's account console in the team runbook; the SMSC.ru side (balance, sender approval, moderation) is the more likely operational surprise than the Laravel side.
Scaling
One HTTP request per recipient per notification — there is no batching in the channel. At low hundreds of messages per day this is irrelevant. At high volume, throughput is bounded by SMSC's API rate limits and by HTTP latency inside queue workers, not by the package. Ensure SMS notifications are queued (ShouldQueue) so worker pools absorb the latency and Laravel's retry mechanism absorbs transient 5xx. Watch provider-side costs: SMS is metered per segment, and unconstrained message length silently multiplies spend.
Failure modes
| Mode | Symptom | Mitigation |
|---|---|---|
| Bad credentials / expired API key | Every send fails, likely as an exception or silent boolean | Alert on notification failure rate; rotate keys on a calendar |
| Provider balance exhausted | Sends rejected at API level | Monitor balance in SMSC console; alert at threshold |
| HTTP timeout / provider 5xx | Queue retries then dead-letters | Rely on queue retry; cap attempts to avoid duplicate SMS on retry |
| Rate-limit rejection | Burst sends fail | Queue + rate limiting middleware on the notification path |
| Silent drop (channel swallows error) | No SMS, no exception | Add explicit success/failure logging around the wrapper; this is the highest-risk unknown |
| Encoding / segment overflow | Truncated or multi-segment messages | Pin translit and length validation in the wrapper |
| Package abandoned upstream | Cannot upgrade Laravel | Pre-scoped in-house replacement via the wrapper interface |
The dominant operational risk is not failure — it is invisible failure. A notification channel that returns quietly on error will mask an SMS outage until a user complains. Instrument the wrapper on day one.
Ramp-up
An afternoon for a Laravel-fluent developer. There is no new mental model: the package reuses notification routing, queueing, and channel selection that the team already knows. The only genuinely new knowledge is the SMSC.ru account surface (sender IDs, moderation, balance, message formatting) and that is provider documentation, not package documentation. No dedicated training, no runbook beyond the credential and balance section.
Bottom line: adopt only if SMSC.ru is already your SMS vendor and you are on a Laravel version the package supports. Ship it behind a thin internal wrapper so the vendor dependency stays a one-file concern, and instrument delivery failures before the first critical-path use case. If SMS is a core product capability rather than a peripheral channel, skip the package and write the ~150-line channel yourself — the marginal maintenance cost is lower than the dependency risk.
How can I help you explore Laravel packages today?