PHP
PHP 8.1+. Soit l’extension cURL native (pas de dépendance) soit
Guzzle pour du code plus propre dans les
projets plus gros.
<?php
$apiKey = getenv('LISOLOO_API_KEY');$apiUrl = '$BASE_URL/api/v1/lisoloo/sms-api';Envoyer un SMS
Section intitulée « Envoyer un SMS »<?php
$ch = curl_init();curl_setopt_array($ch, [ CURLOPT_URL => "$apiUrl/send", CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ "app-key: $apiKey", 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => json_encode([ 'to' => ['+243998857000'], 'message' => 'Bonjour de Lisoloo !', 'sender_id' => 'MYAPP', ]), CURLOPT_TIMEOUT => 10,]);
$response = curl_exec($ch);$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);curl_close($ch);
if ($status !== 201) { throw new RuntimeException("Erreur Lisoloo $status : $response");}
$body = json_decode($response, true);echo $body['data']['message_id'];<?php
use GuzzleHttp\Client;
$client = new Client([ 'base_uri' => $apiUrl, 'headers' => [ 'app-key' => $apiKey, 'Content-Type' => 'application/json', ], 'timeout' => 10.0,]);
$response = $client->post('/send', [ 'json' => [ 'to' => ['+243998857000'], 'message' => 'Bonjour de Lisoloo !', 'sender_id' => 'MYAPP', ],]);
$body = json_decode((string) $response->getBody(), true);echo $body['data']['message_id'];Une classe client réutilisable
Section intitulée « Une classe client réutilisable »<?php
final class LisolooClient{ public function __construct( private string $apiKey, private string $baseUrl = '$BASE_URL/api/v1/lisoloo/sms-api', private float $timeout = 10.0, ) {}
/** * @param string[] $to * @param array<int, array{date: string, time: string}>|null $scheduledDates * @param array<string, mixed>|null $recurringSchedule */ public function send( array $to, string $message, ?string $senderId = null, string $sendingType = 'immediate', ?array $scheduledDates = null, ?array $recurringSchedule = null, ?string $callbackUrl = null, ): array { $body = compact('to', 'message') + ['sending_type' => $sendingType]; if ($senderId !== null) $body['sender_id'] = $senderId; if ($callbackUrl !== null) $body['callback_url'] = $callbackUrl; if ($scheduledDates !== null) $body['scheduled_dates'] = $scheduledDates; if ($recurringSchedule !== null) $body['recurring_schedule'] = $recurringSchedule;
return $this->request('POST', '/send', $body)['data']; }
public function getStatus(string $messageId): array { return $this->request('GET', "/status/$messageId")['data']; }
public function getBalance(): array { return $this->request('GET', '/balance')['data']; }
private function request(string $method, string $path, ?array $body = null): array { $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $this->baseUrl . $path, CURLOPT_CUSTOMREQUEST => $method, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => $this->timeout, CURLOPT_HTTPHEADER => [ "app-key: $this->apiKey", 'Content-Type: application/json', ], ]); if ($body !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); }
$response = curl_exec($ch); $status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE); curl_close($ch);
$decoded = json_decode((string) $response, true); if ($status >= 400) { throw new RuntimeException( sprintf('Lisoloo %d : %s (%s)', $status, $decoded['message'] ?? 'Inconnu', $decoded['error_code'] ?? 'pas-de-code', ), ); } return $decoded; }}Utilisation :
<?php
$client = new LisolooClient(getenv('LISOLOO_API_KEY'));
// Instantané$result = $client->send(['+243998857000'], 'Bonjour !', 'MYAPP');
// Planifié$client->send( to: ['+243998857000'], message: 'Rappel', sendingType: 'scheduled', scheduledDates: [['date' => '2026-06-01', 'time' => '08:00']],);
// Récurrent$client->send( to: ['+243998857000'], message: 'Hebdomadaire', sendingType: 'recurring', recurringSchedule: [ 'start_date' => '2026-06-01', 'end_date' => '2026-12-31', 'frequency' => 'weekly', 'interval' => 1, 'times' => ['09:00'], ],);Récepteur webhook Laravel
Section intitulée « Récepteur webhook Laravel »<?php
use App\Http\Controllers\LisolooWebhookController;
Route::post('/lisoloo/webhook', LisolooWebhookController::class);<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;use Illuminate\Support\Facades\Cache;
final class LisolooWebhookController{ public function __invoke(Request $req) { $auth = $req->header('authorization', ''); if (! str_starts_with($auth, 'Basic ')) { abort(401); } [$user, $pass] = explode(':', base64_decode(substr($auth, 6)), 2);
if (! hash_equals(config('lisoloo.webhook_user'), $user) || ! hash_equals(config('lisoloo.webhook_pass'), $pass)) { abort(401); }
$event = $req->json()->all(); if (Cache::has("lisoloo:event:{$event['event_id']}")) { return response()->noContent(); // replay idempotent } Cache::put("lisoloo:event:{$event['event_id']}", true, now()->addDays(7));
// … votre logique métier …
return response()->noContent(); }}