Looking to hire Laravel developers? Try LaraJobs

smsaero_laravel maintained by smsaero

Description
Laravel integration for the SmsAero API: facade, DI, notification channel.
Last update
2026/06/19 20:55 (dev-master)
License
Links
Downloads
0

Comments
comments powered by Disqus

PHP Laravel library for sending SMS messages via SMS Aero API

Latest Stable Version PHP Version Require Total Downloads License

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() inside config/smsaero.php.
  • php artisan config:cache bakes the values into bootstrap/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