smartpings/php-sdk
A PHP SDK for SmartPings that gives PHP applications a simple, Composer-installable client for the SmartPings API. It wraps authentication and API requests behind a clean, framework-agnostic interface, so it fits into Laravel or any modern PHP project.
Install and inspect before wiring anything up.
composer require smartpings/php-sdk
With 0 stars and 0 dependents, this is an unproven package — treat the install as a code review step. Before you write a single line of integration code:
vendor/smartpings/php-sdk/ and read the README plus the main client class (usually src/Client.php, src/SmartPings.php, or similar). Confirm the namespace, constructor signature, and whether it ships a Laravel service provider or facade at all.composer.json inside the package: PHP version constraint, Guzzle/PSR-18 dependency, and whether it uses illuminate/support (if not, you're integrating a framework-agnostic SDK by hand).examples/ or tests/ directory — if there are tests, they're the best documentation of real request/response shapes.Credentials. The SDK almost certainly takes an API key (and possibly a secret/sender ID) via constructor. Keep these out of the SDK's defaults and in config/services.php:
// config/services.php
'smartpings' => [
'key' => env('SMARTPINGS_API_KEY'),
'secret' => env('SMARTPINGS_SECRET'),
'sender' => env('SMARTPINGS_SENDER_ID'),
],
First use case. Start with the lowest-risk, highest-value flow: a single transactional SMS or an OTP verification send. Get one message out in php artisan tinker before building any abstraction:
$client = new \SmartPings\Client(config('services.smartpings.key'));
$client->sms()->send('+15551234567', 'Hello from Laravel');
Once that returns a real response object, you know the payload shape, the exception type, and the message ID field — everything else is plumbing.
Bind the client as a singleton. Don't new the client in controllers. Register it once so connection config, HTTP client, and auth are shared:
// app/Providers/SmartPingsServiceProvider.php
public function register(): void
{
$this->app->singleton(\SmartPings\Client::class, fn () => new \SmartPings\Client(
config('services.smartpings.key'),
config('services.smartpings.secret'),
));
}
If the SDK ships its own provider, publish its config (php artisan vendor:publish) and skip the manual binding.
Wrap it in a thin domain service. Never let SDK classes leak into controllers or jobs — you want one seam to swap providers or mock in tests:
class SmsService
{
public function __construct(private \SmartPings\Client $client) {}
public function send(string $to, string $body): string
{
$response = $this->client->sms()->send($to, $body);
return $response->id; // verify the actual accessor in the source
}
}
Use a Laravel Notification channel. This is the pattern that pays off day-to-day — you get via(), queuing, and per-user channel preferences for free:
class SmartPingsChannel
{
public function send($notifiable, Notification $notification): void
{
$message = $notification->toSmartPings($notifiable);
app(SmsService::class)->send($notifiable->routeNotificationFor('sms'), $message);
}
}
Then $user->notify(new OrderShipped($order)) works across SMS, WhatsApp, and push by just changing via().
Queue bulk and broadcast sends. Any fan-out (order updates, alerts) belongs in a job with $tries, $backoff, and a rate limiter. SMS providers bill per message and throttle aggressively — a RateLimiter::for('sms', fn ($job) => Limit::perSecond(10)) middleware on the job is cheap insurance.
OTP / verification flow. The verification API is typically two calls: start (send code) and check (verify code). Model it explicitly:
// start
$requestId = $verification->start($phone, 'sms');
Cache::put("otp:{$phone}", $requestId, now()->addMinutes(5));
// check
$result = $verification->check($phone, $request->code);
Store the request/session ID server-side rather than trusting the client, and throttle resends per phone number to stop abuse.
WhatsApp and push. WhatsApp requires pre-approved templates — assume the SDK takes a template name plus ordered parameters, not free text. Push likely takes a device token and a payload array. Keep these in separate small services rather than one god-class, since the failure modes (template rejection vs. invalid token) are completely different.
Testing. Mock your SmsService in feature tests; for the SDK itself, if it uses Guzzle, swap in a MockHandler, or use Http::fake() if it's built on the Laravel HTTP client. Assert that the service was called, not the SDK internals:
$this->mock(SmsService::class)->shouldReceive('send')->once();
src/ directory is the only source of truth."smartpings/php-sdk": "1.2.3") rather than ^1.0, and review diffs on upgrade.Psr\Http\Client\ClientInterface or Guzzle options array, inject a client with timeout: 5, connect_timeout: 2.+15551234567, not (555) 123-4567. Normalize before the call or you'll get cryptic 400s. Pull in propaganistas/laravel-phone if you're accepting user input.\Exception on API errors. Wrap calls in your service layer and translate to your own exceptions so controllers and jobs can handle "invalid number" vs. "auth failed" differently.SmartPings::sms(). If you want the Laravel feel, write one yourself — it's five lines and saves app() calls everywhere.web.SmsService wrapper is the migration point to Twilio/Vonage. Keeping the SDK confined to that one class is the single most valuable architectural decision you'll make here.How can I help you explore Laravel packages today?