Installation et premier SMS
composer require envoisms/envoisms-php, puis $client = new EnvoiSMS\Client(getenv('ENVOISMS_API_KEY')). $client->send(['to' => '+212600000000', 'message' => '…', 'from' => 'MonBusiness']) renvoie l'identifiant du message, que vous retrouvez avec getMessage() et dans vos webhooks.
- 'from' : votre Sender ID validé, ou omis pour l'expéditeur par défaut
- sendBulk(['messages' => [...], 'from' => ...]) pour un envoi groupé
- getMessage($id) et listMessages(50, 0) pour suivre vos envois
Envois rejouables et gestion des erreurs
Chaque send() et sendBulk() porte un Idempotency-Key, généré ou passé en second argument : un nouvel essai après un timeout ne facture jamais le même message deux fois. Le client rejoue lui-même les réponses 5xx et les erreurs cURL jusqu'à maxRetries fois (2 par défaut), avec un délai exponentiel, puis lève EnvoiSMSError avec statusCode et errorCode.
- new Client(getenv('ENVOISMS_API_KEY'), maxRetries: 3, timeoutSeconds: 20)
- catch (EnvoiSMS\EnvoiSMSError $e) : $e->statusCode, $e->errorCode
SMS ou WhatsApp : choisir le canal
Le SMS est le canal par défaut : il atteint tous les mobiles marocains (IAM, Inwi, Orange) sans autre configuration que la clé API. 'channel' => 'whatsapp' envoie depuis votre propre numéro WhatsApp Business : il doit être connecté (sinon 403 WHATSAPP_NOT_CONNECTED), et un texte libre n'est accepté que dans les 24 heures après le dernier message du client (sinon 400 OUT_OF_24H_WINDOW). Hors de cette fenêtre, envoyez un template approuvé. Rien n'est facturé quand l'API refuse.
- 'template' => ['name' => 'order_shipped', 'language' => 'fr', 'variables' => ['89240']]
- 'cascade' => true : repli automatique en SMS si le numéro n'a pas WhatsApp
Codes OTP et webhooks
$client->sendOtp(['to' => …, 'brand' => 'MonBusiness', 'code_length' => 6, 'expiry' => 600]) renvoie un session_id ; $client->checkOtp($sessionId, $code) renvoie verified. getOtpSession() lit l'état d'une session sans consommer de tentative. Pour un webhook de statut, Client::verifyWebhookSignature($rawBody, $signature, $secret) vérifie l'en-tête X-EnvoiSMS-Signature sur le corps brut de la requête.
- 'channel' => 'whatsapp' dans sendOtp() : code WhatsApp via l'expéditeur partagé, sans connexion
- getBalance(), listPacks(), createTopup() pour le compte
- createOptout($phone) pour enregistrer un STOP