mujhtech/sendchamp
A Laravel package that integrates Sendchamp into your application, providing a notification channel and simple API wrapper for sending SMS, WhatsApp and email messages. Configure your Sendchamp credentials once, then dispatch notifications through Laravel's familiar channels.
Install and publish
composer require mujhtech/sendchamp
php artisan vendor:publish --tag=sendchamp-config
If the tag isn’t registered, publish by provider instead:
php artisan vendor:publish --provider="Mujhtech\Sendchamp\SendchampServiceProvider"
Where to look first
composer.json — confirm the Laravel version constraint. The last release (Oct 2022) predates Laravel 10/11, so check illuminate/support before committing it to a modern app.src/ — the service provider (for the config key, facade alias, and container binding), the facade class (for the accessor name), and the main client class (for the actual method surface).config/sendchamp.php — public key, mode (test/live), sender name, and base URL.Environment variables
SENDCHAMP_PUBLIC_KEY=
SENDCHAMP_MODE=test
SENDCHAMP_SENDER_NAME=
The exact variable names must be read from the published config — don’t assume the SENDCHAMP_* prefix; it may differ.
First use case
Transactional SMS for OTP or order notifications. That’s the realistic reason to reach for this package, and it’s the path most worth validating end-to-end in test mode before wiring anything else.
Sanity check before you build on it
This is a 5-star package with 0 dependents and no release in over two years. Budget an hour to read src/ rather than trusting README examples, and treat the package as a thin convenience wrapper — not a maintained dependency.
Wrap it behind your own gateway
Don’t sprinkle Sendchamp::sendSms(...) across controllers. Bind a small interface and let the package be one implementation:
interface SmsGateway {
public function send(string $to, string $message): void;
}
final class SendchampGateway implements SmsGateway
{
public function send(string $to, string $message): void
{
// Adapt to the package's actual method signature
}
}
$this->app->bind(SmsGateway::class, SendchampGateway::class);
This is the single highest-value pattern here: it isolates the unmaintained dependency behind a seam you control, and makes it trivial to swap to raw Http:: calls later.
Queue everything
SMS is a network call — never send inline in a request. Use a job with retries and backoff:
final class SendSms implements ShouldQueue
{
public int $tries = 3;
public array $backoff = [10, 30, 60];
public function __construct(
public string $to,
public string $message,
) {}
public function handle(SmsGateway $sms): void
{
$sms->send($this->to, $this->message);
}
}
Notification channel
If you send more than one or two message types, wrap the package in a custom notification channel so message construction lives in toSendchamp() methods rather than scattered service classes.
OTP flow
Generate a numeric code, store it hashed with a short TTL (cache or a dedicated table), dispatch the SMS job, then verify against the hash with an attempt counter. Keep generation and sending as separate concerns — the package is only the transport leg.
Test mode as a config dimension
Sendchamp’s test mode returns simulated responses. Model it explicitly:
test in local/staging, live in production.SENDCHAMP_MODE !== 'live' when app()->isProduction()).Testing
If the client uses Laravel’s HTTP client (likely), Http::fake() covers you. Otherwise bind a fake SmsGateway — another argument for the wrapper pattern.
Age and abandonment. No release since October 2022, 5 stars, 0 dependents. Assume the Sendchamp API has since added endpoints and changed payload shapes that this wrapper doesn’t know about. Fork it or vendor the client class into app/ rather than depending on it indefinitely.
Verify endpoints against current docs. Read the client class and compare every URL and payload key to the live Sendchamp API reference. An outdated wrapper failing silently on a shifted field name is the most likely failure mode.
Laravel auto-discovery. If extra.laravel.providers in the package’s composer.json targets an old namespace convention, discovery may work but the facade alias or config merge can differ. Confirm with php artisan about or config('sendchamp').
Config cache. After changing env values, run php artisan config:clear — cached config is the usual culprit for “my new key isn’t being used.”
Phone number formatting. Sendchamp expects international format without the leading zero (+234..., not 0803...). Normalise at the gateway boundary; a malformed number typically surfaces as a provider-side rejection, not a transport error.
Error handling. Don’t assume the package throws rich, typed exceptions. Wrap calls, capture the raw response, and log request/response pairs on non-2xx. The wrapper may return a response object where failures are only visible in the body.
Idempotency and rate limits. OTP endpoints get hammered by double-taps and retries. Dedupe on a cache key per recipient per window, and keep retry backoff generous so a provider 429 doesn’t cascade into three duplicate SMS.
Debugging. Log the outgoing payload at the gateway boundary before handing off to the package. If it uses Http, Http::fake() plus Http::preventStrayRequests() will confirm exactly what leaves your app.
Extension points. Publish and edit the config, bind your own implementation of the client class in the container if it’s resolved from there, or extend the facade root. In practice, forking the client class into your own namespace is cleaner than subclassing a package nobody is patching.
Version pinning. Pin an exact version in composer.json rather than a caret range. There is no forward-fix path if an upstream release breaks you.
How can I help you explore Laravel packages today?