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

Sms Api Laravel Package

octopush/sms-api

Laravel package for integrating the Octopush SMS API. Configure your credentials, send SMS messages through a simple facade or a dedicated Laravel notification channel, and add transactional or alert messaging to PHP applications with a clean, framework-friendly API.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a small, plain-PHP client for the Octopush REST API — it is not a Laravel package. There is no service provider, no config file, and no facade. Treat it as a transport you wrap yourself.

Install

composer require octopush/sms-api

If Composer resolution fails (the package hasn't been tagged since Jan 2022), pin it in composer.json or vendor the handful of classes under app/Support/Octopush/ and autoload them via composer.json autoload.classmap. Either way, wrap it immediately so a later swap to Http:: calls doesn't ripple through your codebase.

Credentials — keep them out of config/app.php:

// config/services.php
'octopush' => [
    'login'   => env('OCTOPUSH_LOGIN'),
    'api_key' => env('OCTOPUSH_API_KEY'),
    'sender'  => env('OCTOPUSH_SENDER', 'MyApp'),
    'simulate'=> env('OCTOPUSH_SIMULATE', false),
],

First use case — send a single transactional alert. Instantiate with the login + API key, set a sender, recipients, campaign type/purpose, and call the send method:

$sms = new \Octopush\SMS_API_Client(config('services.octopush.login'), config('services.octopush.api_key'));
$sms->set_sms_sender(config('services.octopush.sender'));
$sms->set_sms_recipients(['+33612345678']);
$sms->set_sms_text('Your code is 4821');
$sms->set_sms_type('sms_premium');   // or 'sms_low_cost'
$sms->set_sms_purpose('alert');      // or 'marketing'
$result = $sms->send();

Look at the returned payload first — it carries the campaign id and a numeric status code — before you wire it into anything user-facing. The README in the repo is the source of truth for the exact method names; they have shifted between the older sms.php style and the current v1 API style, so confirm signatures against the tag you installed.

Implementation Patterns

Bind it once, inject everywhere. Register a singleton in AppServiceProvider returning your own thin wrapper (App\Services\Sms\OctopushSender), not the vendor class. Your wrapper implements an internal SmsSender contract with one method (send(string $to, string $text, array $options = [])). Everything downstream — controllers, jobs, notifications — depends on the contract, which is what makes testing and provider swaps cheap.

Config-driven campaign type. Map your own two or three buckets onto Octopush's type × purpose matrix in config, so callers say ->send($to, $text, priority: 'high') and the wrapper picks sms_premium/marketing vs sms_low_cost/alert. Marketing traffic has different consent and STOP-handling obligations than transactional alerts; encoding that in one place prevents accidental marketing sends on the alert path.

Notification channel. The highest-leverage integration is a custom channel:

class SmsChannel
{
    public function send($notifiable, Notification $notification): void
    {
        if (! $phone = $notifiable->routeNotificationFor('sms')) {
            return;
        }
        app(SmsSender::class)->send($phone, $notification->toSms($notifiable)->text);
    }
}

Then via() returns [SmsChannel::class] alongside mail/database and you get retries, queueing, and per-user preferences for free.

Queue it and chunk it. Wrap sends in a queued job. For campaigns, chunk recipients (100–500 per call, depending on what the API accepts in recipients) and dispatch one job per chunk with $tries = 1 and retryUntil unset — see gotchas on duplicates. Record the returned campaign id per chunk so you can reconcile later.

OTP flow. Generate a code, Hash::make() it into the cache keyed by phone with a short TTL, send via the alert/premium path, and verify with Hash::check plus an attempt counter. Keep the code out of logs and out of the job payload where you can avoid it.

Delivery reports / inbound replies. Expose a POST /webhooks/octopush route, verify the payload (shared secret or IP allow-list), store status transitions in an sms_messages table keyed by campaign id + recipient, and return 200 fast — do the reconciliation in a queued job. Never let webhook handling block on your own outbound calls.

Testability. Point the client at a fake by binding a FakeSmsSender in tests, and set OCTOPUSH_SIMULATE=true for staging so you don't burn credits during manual QA. If you ever ditch the library for Http::, Http::fake(['api.octopush.com/*' => ...]) gives you assertion-level testing for free.

Gotchas and Tips

HTTP 200 does not mean success. The API returns errors inside the JSON body with a numeric code. Always inspect the response code field and throw a domain exception on anything non-success — otherwise a rejected recipient (bad prefix, blocked number) looks identical to a delivered message in your logs.

Phone formats will bite you. Send E.164 (+33612345678), no spaces, no leading 00, no national format. Validate and normalize on ingest with a library like propaganistas/laravel-phone rather than trusting stored values; a malformed number is charged or rejected without a useful error.

Alphanumeric senders are country-restricted. An 11-character alphanumeric sender (MyApp) is fine across much of Europe but gets overwritten by a shortcode or rejected in several countries (notably parts of the US/Canada). Keep a config map of per-country fallback senders, and verify per destination before launching a campaign.

Segmentation and credits. Billing is per 160-char GSM-7 segment (70 for UCS-2 once you include an emoji or non-Latin character). A 200-character message with one emoji can silently cost 3× what you budgeted. Compute segments before sending and truncate or block long marketing texts.

No idempotency key. A timeout or a queue retry can double-send and double-charge. Set explicit timeouts on the HTTP call, log the outbound attempt before dispatching, and make your retry policy "no automatic retries on send" — surface failures for a manual re-send instead. This is the single biggest financial risk in the package.

Marketing consent is your job. purpose = marketing doesn't add STOP management for you. You need opt-in storage, a STOP keyword handler on the inbound webhook, and suppression-list checks before the send call. Alerts/OTP bypass that, which is why routing them through different methods matters.

The package is stale (last release Jan 2022). Expect no PHP 8.3+ fixes and no Laravel 11 support. It's a thin cURL/JSON wrapper — if you hit friction, spending an hour reimplementing the two endpoints you actually use with Laravel's Http client is usually cheaper than patching vendored code, and it makes the whole thing fakeable.

Don't log secrets or full numbers. The API key rides in a header; scrub it from exception messages and Laravel's HTTP client logs. Mask phone numbers in application logs (+336••••5678) for GDPR hygiene, and be deliberate about storing message bodies.

Extension points are thin by design. There's nothing to hook into — no events, no middleware, no driver contract. Your wrapper is the extension point. Put the response-code mapping, segment calculation, suppression check, and logging there, and keep the vendor call as the last three lines of the method.

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