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

Kavenegar Laravel Package

masihjay-z/kavenegar

Laravel integration for the Kavenegar SMS API, providing a simple way to send SMS messages, OTP codes, and lookup-based notifications from your PHP applications through a clean, framework-friendly wrapper.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat masihjay-z/kavenegar as a thin, unmaintained convenience wrapper around Kavenegar's REST API, not a first-party integration. Adoption signals are essentially zero (0 stars, 0 dependents, score 0) and it targets Laravel 4/5, so your first hour should be spent reading source, not writing feature code.

1. Install and inspect before you trust the API surface.

composer require masihjay-z/kavenegar

Then immediately open composer.json in the package and check:

  • the exact namespace (e.g. Masihjay\Kavenegar\... — verify, don't assume),
  • the illuminate/support constraint and required PHP version,
  • whether it declares extra.laravel.providers for auto-discovery (it likely predates Laravel 5.5 discovery).

2. Register the provider and facade manually in config/app.php (Laravel 4/5 convention):

'providers' => [
    Masihjay\Kavenegar\KavenegarServiceProvider::class, // verify from src/
],

'aliases' => [
    'Kavenegar' => Masihjay\Kavenegar\Facades\Kavenegar::class, // verify
],

3. Publish config and supply credentials.

php artisan vendor:publish --provider="Masihjay\Kavenegar\KavenegarServiceProvider"
KAVENEGAR_API_KEY=your-api-key
KAVENEGAR_SENDER=10004346

4. Where to look first: composer.json, then src/ for the service provider, the facade, and the config keys. The package's README is the only documentation — do not assume config key names or method names match the official kavenegar/laravel package; this wrapper is old enough that send vs Send vs sendSms is genuinely uncertain until you read the code.

5. First use case: an OTP / verification code, the dominant Kavenegar workload in Iranian Laravel apps.

Kavenegar::send($mobile, 'کد ورود شما: 12345');

Confirm the real signature from source before shipping. If you are on Laravel 6+, PHP 8+, or need queued notifications, delivery callbacks, or lookup templates, stop here and write a small Http:: client or use the official Kavenegar SDK instead.

Implementation Patterns

Wrap it behind your own interface from day one. This is the single highest-leverage habit with a package this thin and this unmaintained — it converts an adoption risk into a removable detail.

interface SmsSender {
    public function send(string $mobile, string $message, ?string $sender = null): bool;
}

class KavenegarSender implements SmsSender
{
    public function send(string $mobile, string $message, ?string $sender = null): bool
    {
        // delegate to the package facade; normalize response + errors here
    }
}

Bind it in a service provider ($this->app->bind(SmsSender::class, KavenegarSender::class)) so call sites depend on your contract, not the facade.

Queue everything; never send inline in a request. SMS is a paid outbound network call with latency. Dispatch a job onto a dedicated queue:

dispatch(new SendOtp($user, $code))->onQueue('sms');

This gives you retries, backoff, and a place to add rate limiting without touching controllers.

Integrate via a Notification channel, not ad-hoc controller calls. One channel means one logging policy, one retry policy, one place to swap providers.

class SmsChannel
{
    public function __construct(private SmsSender $sender) {}

    public function send($notifiable, Notification $notification)
    {
        $this->sender->send(
            $notifiable->routeNotificationFor('sms'),
            $notification->toSms($notifiable)
        );
    }
}

Expose routeNotificationForSms() on your User model so Laravel can resolve the number.

Read config through config(), never env() at runtime. Publish the package config, then in your own config layer:

// config/services.php or config/sms.php
'sms' => [
    'otp'       => env('KAVENEGAR_SENDER_OTP'),
    'marketing' => env('KAVENEGAR_SENDER_MARKETING'),
],

env() returns null once php artisan config:cache runs — a classic "OTPs stopped working in production" bug.

Route senders explicitly for multiple lines. Don't rely on the package's single default sender when you have transactional and marketing lines; pass the sender per message type.

Fake it in tests. Bind a FakeSmsSender / LogSmsSender in the container so CI never burns credit or touches the network, and assert on recorded messages rather than the package's boolean return.

Add observability at the wrapper, not the package. Log mobile (masked), template/message type, provider status code, and Kavenegar's return.message. This is the only telemetry you'll get.

Gotchas and Tips

  • The package is effectively abandoned. Zero stars, zero dependents, Laravel 4/5-era. Check the last commit date and the illuminate/support constraint. On Laravel 9+ you may be tempted by --with-all-dependencies or --ignore-platform-reqs; resist — you're inheriting a fork-and-own obligation. The official kavenegar/laravel package or a ~40-line Http client is lower risk.
  • Kavenegar returns HTTP 200 with errors in the body. This is the biggest trap. The API responds 200 OK with a JSON payload whose return.status is 400+ for invalid keys, insufficient credit, blacklisted numbers, or bad sender lines. Never treat a non-exception return as success — parse the status/code inside your SmsSender::send() and log return.message (usually Persian).
  • The facade may hide the error surface. If it collapses responses to true/false, you'll have no diagnostic. Log the raw response at your wrapper layer; you'll need it the first time OTPs "silently stop working."
  • Preserve UTF-8 Persian text. Long messages split into multi-part SMS billed per part. Keep OTP templates well under 70 characters to stay single-part and cheap.
  • Credit and rate limits are real. Kavenegar enforces per-second caps and rejects bursts. Use Redis::throttle or a RateLimited job middleware; it's cheaper than a support ticket.
  • No delivery receipts or inbound webhooks in older wrappers. If you need delivery callbacks or inbound SMS (/sms/receive), you implement the controller and verify secrets yourself — assume the package doesn't.
  • Facade alias collisions. A global Kavenegar alias can clash with other packages or a local class. Prefer constructor-injecting your SmsSender interface over resolving the facade anywhere in application code.
  • No timeout / retry config to rely on. The wrapper likely uses synchronous HTTP with whatever defaults Guzzle had at the time. Put timeouts, retries, and backoff in your job layer, not the package.
  • Credential handling. Keep the API key in .env and out of logs; older config files sometimes dump request params on error, which can leak the key into storage/logs.
  • Extension point to plan for: the only durable extension point is your own SmsSender implementation. Write it so that removing the package means deleting one class — that's the whole migration path.
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.
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
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core