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

Netgsm Laravel Package

tarfin-labs/netgsm

Laravel package for sending SMS through NetGSM, a Turkish SMS gateway. It offers a simple, fluent API for sending single or bulk messages, checking delivery reports, and managing account details, with configuration handled through Laravel's config and service container.

View on GitHub
Deep Wiki
Context7

Getting Started

  • composer require tarfin-labs/netgsm, then publish the config (php artisan vendor:publish --tag=netgsm-config) and put credentials in .env — at minimum username, password and the approved message header (msgheader). Nothing works until NetGSM has whitelisted that header for your account.
  • First places to look: config/netgsm.php (credential keys and any endpoint/timeout options), the Netgsm facade root, and the README's usage block for the exact send/report method signatures — the public surface is small, so the README plus the facade is usually the whole story.
  • First use case: send a single transactional SMS from a queued job and persist the returned job id, then look that id up in the delivery report. That two-step loop (send → reconcile by job id) is the mental model for everything else in the package.
  • Verify the wiring with a real send to your own number in a staging environment; the provider returns transport-level success even for some rejected requests, so a green HTTP response is not proof of delivery.

Implementation Patterns

  • Wrap it, don't sprinkle it. Put the facade behind your own SmsSender/SmsService class so call sites stay testable and you can swap providers later. Notifications should go through a custom NotificationChannel that delegates to that service.
  • Always queue. A send is a synchronous HTTP round trip; doing it inline in a controller adds hundreds of milliseconds to the user's request and makes retries awkward. Use a job with $tries, backoff(), and ShouldBeUnique/rate limiting for bulk batches.
  • Persist the job id. Store it (as a string — see gotchas) next to your own message record with a pending status. Delivery reports are the only reliable source of truth for "delivered" vs "rejected", so a scheduled command that polls pending messages older than N minutes and updates statuses is the standard pattern.
  • OTP flows are just SMS with a lifecycle: generate a short numeric code, store a hash with a TTL and attempt counter, send via the same service, verify with per-number and per-IP throttling. Keep the verification logic in your app — the package only moves the message.
  • Reporting/reconciliation should map provider status codes onto your own enum early; don't leak raw provider strings into your domain or your UI.
  • Testing: fake the HTTP layer (Http::fake()) or bind a stub implementation of your own service interface in the container. Assert on what you tried to send, not on the provider.
  • Multi-tenant / multi-brand: the config is global, so per-tenant credentials (different headers) mean either a dedicated service instance constructed with explicit credentials or carefully scoped config()->set() calls — the latter is fragile under Octane and queue workers that process several tenants.

Gotchas and Tips

  • 5.3.0 changes the report job id type from int to string. Treat this as a silent breaking change if you type-hinted int $jobId anywhere, compared with === against an int, or stored the id in an INT/BIGINT column. Since NetGSM ids should be treated as opaque identifiers, storing them as VARCHAR and typing them as string is the correct end state — audit your schema and any strict comparisons before upgrading.
  • HTTP 200 does not mean accepted. NetGSM returns application-level error codes in the body; inspect the response payload and throw a domain exception on non-success codes rather than assuming the facade did it for you.
  • Character encoding costs money. A single Turkish character or emoji can push a message from GSM-7 into UCS-2 and multiply the billable segment count. Prefer ASCII-safe text for OTP and transactional messages, and check segment count before sending bulk.
  • Config caching: php artisan config:cache after any env change; stale credentials after a deploy are the most common "it worked locally" failure.
  • Bulk sends need chunking and throttling on your side — the provider will rate-limit or start rejecting, and retry storms make it worse. Send in chunks with a delay between batches.
  • Set explicit HTTP timeouts if the config exposes them; a hanging send inside a queue worker can exhaust your worker pool.
  • Log the job id (and the number's last four digits, never the full number) on every send and every report lookup — NetGSM support will ask for it, and it's the only way to trace a disputed message.
  • Extension points worth knowing: publishing and editing the config for endpoint/timeout tweaks, and binding your own client/HTTP transport in the container if you need to point tests at a sandbox or add retry middleware.
  • Pin the version in composer.json with a caret constraint and read the changelog on minors — this release shows minor bumps can carry return-type changes that PHP's type system will only catch at the call site, not at install time.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource