Official PHP SDK for the Safwatech OTP / verification platform — OTP (push / SMS / email / WhatsApp), TOTP authenticator (RFC 6238) with backup codes, magic links, silent push approval, and WebAuthn / passkeys.
composer require safwatech/otpRequires PHP ≥ 8.1. Runtime deps: guzzlehttp/guzzle, ext-json.
use Safwatech\Otp\OTPClient;
$client = new OTPClient([
'api_key' => 'sk_test_…',
'base_url' => 'https://otp.safwatech.com.ly',
]);
$sent = $client->sendOtp('+218911234567', channel: 'sms', referenceId: 'order-42');
// Sandbox keys echo back `otp_code` so you can round-trip without delivery.
if (!empty($sent['result']['otp_code'])) {
$client->verifyOtp('+218911234567', $sent['result']['otp_code'], referenceId: 'order-42');
}API keys are issued from the client portal. sk_test_* keys put the call in
sandbox mode — no real delivery, no quota consumption, responses are
stamped with X-Sandbox: true.
Every endpoint returns the platform's JSON envelope as an associative array:
['status' => 'success', 'result' => ['...']]Errors throw OTPClientException:
use Safwatech\Otp\OTPClientException;
try {
$client->sendOtp('+218911234567');
} catch (OTPClientException $e) {
if ($e->status === 429) {
sleep($e->retryAfter ?? 1);
// retry…
}
}| Surface | Methods |
|---|---|
| OTP | sendOtp · verifyOtp · getStatus · usage |
| Scheduled | scheduleOtp · cancelScheduled · listScheduled |
| TOTP | enrollTotp · verifyTotp · totpStatus · unenrollTotp · generateBackupCodes |
| Magic links | sendMagicLink · getMagicLink · cancelMagicLink · waitForMagicLink |
| Silent push auth | requestAuth · getAuthRequest · cancelAuthRequest · waitForAuth |
| WebAuthn / passkeys | webauthnRegister · webauthnAuthenticate · getWebauthn · cancelWebauthn · waitForWebauthn |
The waitFor* helpers poll the matching get* endpoint until the request
reaches a terminal state (e.g. consumed | expired | cancelled for magic
links) or $timeoutSeconds elapses; they return the final polled response.
use Safwatech\Otp\Webhooks;
$ok = Webhooks::verify(
rawBody: file_get_contents('php://input'),
secret: $_ENV['OTP_WEBHOOK_SECRET'],
signatureHeader: $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '',
timestampHeader: $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '',
);
if (!$ok) {
http_response_code(401);
exit;
}The header format is X-Webhook-Signature: v1=<hex> over "{timestamp}.{body}"
(HMAC-SHA256). A 300 s tolerance window is enforced by default.
- Live API reference: https://otp.safwatech.com.ly/docs
- Runnable scripts:
sdks/examples/*.phpin the source repo (python_example.php,magic_link.php,silent_auth.php,totp_enroll.php,webauthn.php,verify_webhook.php).
composer install
composer testMIT. See LICENSE.