smsaero / smsaero_laravel
Laravel integration for the SmsAero API: facade, DI, notification channel.
Requires
- php: ^8.1
- illuminate/notifications: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
- smsaero/smsaero_api: ^1.2
Requires (Dev)
- laravel/pint: ^1.18
- mockery/mockery: ^1.6
- orchestra/testbench: ^8.0|^9.0|^10.0
- phpstan/phpstan: ^1.12
This package is auto-updated.
Last update: 2026-06-19 18:57:05 UTC
README
Laravel integration for the SmsAero API: facade, dependency injection, and a queueable notification channel on top of the smsaero/smsaero_api library.
Documentation in Russian: README.RUS.md
Installation (from Packagist):
composer require smsaero/smsaero_laravel
The service provider and SmsAero facade are registered automatically via package discovery.
Configuration:
Publish the configuration file:
php artisan vendor:publish --tag=smsaero-config
Set credentials in .env. Get them from the account settings page: https://smsaero.ru/cabinet/settings/apikey/
SMSAERO_EMAIL=your@email.com SMSAERO_API_KEY=your-api-key SMSAERO_SIGN="SMS Aero"
Usage example:
Facade
use SmsAero\Laravel\Facades\SmsAero; SmsAero::message()->send([ 'number' => '70000000000', 'text' => 'Hello, World!', ]); $balance = SmsAero::user()->getBalance();
Available domain clients: message(), contact(), group(), user(), viber(), whatsapp(), telegram(), mobileId().
High-level send (typed)
sendSms() fills sign from config, normalizes the response, throws typed exceptions and returns a SmsAeroResult:
use SmsAero\Laravel\Facades\SmsAero; $result = SmsAero::sendSms('70000000000', 'Hello, World!'); // $result->id, $result->status, $result->cost, $result->recipient, $result->raw
On success=false it throws ApiException; on a transport failure, ConnectionException.
Strict mode
guard() runs every domain call through response normalization and typed exceptions:
$balance = SmsAero::guard()->user()->getBalance(); SmsAero::guard()->message()->send(['number' => '70000000000', 'text' => 'Hi', 'sign' => 'SMS Aero']);
The raw passthrough SmsAero::message()->send([...]) (returns array, throws the base \Exception) is kept for backward compatibility.
Dependency injection
use SmsAero\SmsAeroMessage; public function __construct(private SmsAeroMessage $sms) {} $this->sms->send(['number' => '70000000000', 'text' => 'Hello, World!']);
Notification channel
use Illuminate\Notifications\Notification; use SmsAero\Laravel\Notifications\SmsAeroMessage; class OrderShipped extends Notification { public function via(object $notifiable): array { return ['smsaero']; } public function toSmsAero(object $notifiable): SmsAeroMessage { return SmsAeroMessage::create("Order #{$this->id} shipped")->sign('MyShop'); } }
The recipient number is resolved from routeNotificationForSmsAero(), then the sms channel route, then the phone / phone_number attribute:
public function routeNotificationForSmsAero(): string { return $this->phone; }
Queueing
Add implements ShouldQueue to the notification to deliver it through a queue:
class OrderShipped extends Notification implements ShouldQueue { use Queueable; }
Testing:
SmsAero::fake() swaps the client with a recording double and exposes assertions:
use SmsAero\Laravel\Facades\SmsAero; $fake = SmsAero::fake(); // ... code under test sends SMS ... $fake->assertSent(); $fake->assertSentTo('70000000000'); $fake->assertSentCount(1); $fake->assertNothingSent();
Exceptions:
The notification channel throws typed exceptions:
SmsAero\Laravel\Exceptions\SmsAeroException— base exception for all exceptions raised by the package.SmsAero\Laravel\Exceptions\ConnectionException— network failure, gate unavailability, empty or malformed response. Retryable by the queue.SmsAero\Laravel\Exceptions\ApiException— API rejection (success=false). The full response body is available on$exception->response.
Direct facade/DI calls return arrays and raise the base \Exception from the smsaero/smsaero_api library.
Security:
- Credentials are read only from
env()insideconfig/smsaero.php. php artisan config:cachebakes the values intobootstrap/cache/config.php— do not ship that file in a Docker image together with a real.env; provide secrets through runtime mechanisms (Docker/K8s secrets, Vault).- Add
api_key,apiKey,authorization,SMSAERO_*to your Sentry/log scrubber and mask phone numbers. - Validate
callbackUrl(Mobile ID) on the application side (https only, trusted host) — it is a potential SSRF vector.
Compatibility:
- PHP 8.1+
- Laravel 10, 11, 12
License:
MIT License