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 Usms Laravel Package

class-atlas/laravel-usms

Laravel-USMS provides a clean, configurable integration for sending SMS through the USMS gateway. It offers a Laravel-friendly API, publishable configuration, and straightforward delivery handling for transactional and notification messages.

View on GitHub
Deep Wiki
Context7

Getting Started

v3 is a small but breaking release: the only API change is that createBrandName() now requires a second $description argument. Everything else about the package (sending messages, credentials, config) is unchanged from v2.

  1. Install and pin the major: composer require classatlas/laravel-usms:^3.0. Laravel package auto-discovery registers the service provider and the USms facade — check composer.json of the package if you need to register manually in an older app skeleton.
  2. Publish the config (php artisan vendor:publish --tag=usms-config or equivalent — confirm the tag in the package README) and put the uBill credentials in .env. Run php artisan config:clear after editing.
  3. Look first at config/usms.php, the USms facade docblock, BrandNameCreateCode (the statusID enum) and USmsRejectedException — those four files tell you almost everything about what the gateway can refuse and why.
  4. First use case: create the brand name (sender ID) you'll send from, then send a message with it. From v3 the brand create looks like:
use ClassAtlas\USms\Facades\USms;

$brand = USms::createBrandName(
    'MyBrand',
    'https://mybrand.ge — payment reminders and notices to our customers'
);

Treat brand creation as one-time onboarding, not a runtime call: the description is reviewed by uBill, so the brand may not be usable immediately.

Implementation Patterns

Wrap brand creation in an artisan command, not a controller. A one-off usms:create-brand command (or a seeder) keeps the description in version control, is re-runnable by ops, and avoids creating a new brand every deploy. Store the resulting brand name/id in config or a settings table and read from there at send time.

Validate the description before it hits the API. Mirror uBill's rules with a FormRequest or rule set so operators get a field error instead of a USmsRejectedException in the logs:

$request->validate([
    'brand' => ['required', 'string'],
    'description' => ['required', 'string', 'max:500'], // max:500 uses mb_strlen
]);

Prompt for the content uBill expects: website, Facebook/Instagram page or application, plus how the brand name will be used. A description that only says "test" or repeats the brand name will be refused.

Branch on the enum, not on strings. Both new refusals arrive as USmsRejectedException with their own BrandNameCreateCode case, so map them to actionable messages:

use ClassAtlas\USms\Exceptions\USmsRejectedException;
use ClassAtlas\USms\Enums\BrandNameCreateCode;

try {
    USms::createBrandName($name, $description);
} catch (USmsRejectedException $e) {
    $message = match ($e->code) {
        BrandNameCreateCode::DESCRIPTION_REQUIRED => 'Add a description referencing your website or social page.',
        BrandNameCreateCode::DESCRIPTION_TOO_LONG => 'Description must be 500 characters or fewer.',
        default => 'uBill rejected the brand name: '.$e->getMessage(),
    };
}

(Confirm the exact property name on the exception — code/statusId/getCode() — in the package source; the enum cases themselves are DESCRIPTION_REQUIRED = 60 and DESCRIPTION_TOO_LONG = 61.)

Centralise the facade behind a thin service. A BrandRegistrar / SmsSender class with constructor-injected config makes it trivial to swap in a fake in tests and keeps the two-argument call in one place if the signature moves again.

Send asynchronously. Message sending belongs in a queued job with sensible retries and a dead-letter path; catch USmsRejectedException inside the job and mark it failed permanently rather than retrying a deterministic rejection.

Testing. Assert the description is actually forwarded, because that's the whole point of v3:

USms::shouldReceive('createBrandName')
    ->once()
    ->with('MyBrand', Mockery::on(fn ($d) => str_contains($d, 'mybrand.ge')));

If the package ships a USms::fake(), prefer it; otherwise bind a Mockery mock of the underlying client into the container.

Gotchas and Tips

  • The upgrade is mechanically small but silently incompatible. Any call with one argument now throws a PHP ArgumentCountError before it ever reaches uBill — and the old one-argument behaviour would be refused by the API anyway. Grep for createBrandName including tests, factories, seeders and mocks. Mockery expectations with ->with('MyBrand') will fail with an argument-count mismatch until updated.
  • 500 characters is a hard API limit, and it's characters, not bytes. Georgian text and emoji are multibyte — use Laravel's max:500 rule (which uses mb_strlen) rather than a manual strlen() check, or you'll reject valid descriptions or accept invalid ones.
  • Validation max:500 is not the same as "good enough". The description is judged on content: it must name the website, Facebook/Instagram page or application and explain the intended use. Treat DESCRIPTION_REQUIRED as a content-quality refusal, not just an empty-field one.
  • Don't create brands in a request loop. A repeated create for an existing brand will come back rejected; catch and treat "already exists" as success so a re-deploy doesn't fail the pipeline.
  • Log the statusID. When an unexpected USmsRejectedException surfaces, log statusID plus the brand name, never the raw credential or the full request payload. Add a case to your match when uBill adds new codes, otherwise they fall through to default.
  • The description is captured at creation time. There's no evidence in this release of a way to amend it later; get it right on the first create, and record the exact string you sent alongside the brand for future reference.
  • Config caching bites in production. env() calls in the package config only resolve when the config isn't cached — after changing credentials, run php artisan config:cache on deploy rather than assuming .env edits take effect.
  • Pin the major. ^3.0 stops a future silent break; this release is the proof that the package will make required-argument changes when the gateway forces it.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin