SMS Gateway OVHcloud : intégration API, Email-to-SMS et HTTP-to-SMS

Guide pratique : choisir API REST, Email-to-SMS ou HTTP-to-SMS, sécuriser clés OVH, gérer retries/idempotence, templates et mise en production pour PrestaShop.

Ordinateur affichant du code avec des schémas d'intégration API pour OVHcloud.

Table des matières :

  1. SMS Gateway OVHcloud : choisir entre API REST, Email-to-SMS et HTTP-to-SMS
  2. Pré-requis OVHcloud et modèle d’authentification : ce que vous devez verrouiller
  3. Intégration API OVHcloud (PHP 8.2/8.3) : envoi robuste, timeouts et idempotence
  4. Email-to-SMS : utile en fallback, mais fragile si vous ne contrôlez pas votre MTA
  5. HTTP-to-SMS : simplicité apparente, dette technique réelle
  6. Intégrer proprement dans PrestaShop (8.x) : module, hooks, file et conformité
  7. Checklist de mise en production (sans folklore)

SMS Gateway OVHcloud : choisir entre API REST, Email-to-SMS et HTTP-to-SMS

Le SMS Gateway OVHcloud couvre en pratique trois modes d’émission, qui n’ont ni les mêmes garanties, ni les mêmes contraintes d’intégration : (1) l’API REST OVHcloud (le chemin moderne, traçable, instrumentable), (2) l’Email-to-SMS (pragmatique, souvent utilisé pour du fallback ou des systèmes legacy), et (3) le HTTP-to-SMS (souvent présenté comme “simple”, mais avec des implications de sécurité et d’observabilité qui le rendent coûteux à long terme).

Sur un e-commerce PrestaShop, le critère n°1 n’est pas “est-ce que ça envoie un SMS”, mais est-ce que je peux prouver qu’il a été soumis, réessayé, corrélé à une commande, et qu’en cas d’échec je peux diagnostiquer vite. L’API REST est celle qui se prête le mieux à cette exigence : vous avez un identifiant de job, des statuts, des erreurs HTTP exploitables, et vous pouvez loguer proprement. Email-to-SMS et HTTP-to-SMS peuvent dépanner, mais vous perdez vite le contrôle (statuts flous, erreurs non structurées, intégrations qui dérivent).

Pour choisir vite (et éviter de “refaire” dans 6 mois), ce tableau aide à objectiver :

Critère API REST OVHcloud Email-to-SMS HTTP-to-SMS
Traçabilité (jobId, statut, erreurs structurées) Excellente Faible (SMTP ≠ delivery SMS) Moyenne à faible (selon endpoint)
Sécurité (auth forte, rotation, moindre privilège) Bonne (AK/AS/CK) Moyenne (dépend du SMTP/MTA) Souvent faible si legacy (secrets mal gérés)
Observabilité (logs, corrélation, métriques) Excellente Complexe (chaîne MTA) Variable, souvent pauvre
Intégration applicative (timeouts, retries, backoff) Maîtrisable Indirecte Maîtrisable mais pièges fréquents
Usage recommandé Transactionnel, volumétrie, SLA Fallback / legacy Contrainte héritée uniquement

Enfin, gardez en tête les contraintes intrinsèques du SMS : encodage GSM-7 vs UCS-2, segmentation (1 SMS = 160 caractères GSM-7, mais 153 par segment en concaténé ; en UCS-2 c’est 70/67), et normalisation des numéros en E.164 (ex. +33612345678). Si vous ne traitez pas ces points dans votre code, vous aurez des effets de bord “incompréhensibles” côté métier (messages tronqués, coûts qui explosent parce que l’encodage bascule en UCS-2, numéros refusés car mal formatés).

Mini-scenario (terrain) : une boutique FR envoie “Votre colis est expédié — lien de suivi : …” et ajoute un emoji “📦”. Résultat : bascule en UCS-2, le message passe de 1 segment à 2 voire 3, et votre coût par notification grimpe sans que personne ne comprenne pourquoi. Le correctif n’est pas “négocier le prix”, c’est de valider l’alphabet (ou de supprimer certains caractères) et de mesurer le ratio segments/message en production.

Pré-requis OVHcloud et modèle d’authentification : ce que vous devez verrouiller

Côté OVHcloud, l’API s’appuie classiquement sur un triplet Application Key / Application Secret / Consumer Key (AK/AS/CK) associé à des droits. Techniquement, c’est propre : vous pouvez restreindre les permissions et tracer l’usage. Opérationnellement, le piège est ailleurs : trop d’équipes mettent ces secrets dans un config.php ou pire, dans le dépôt Git. En e-commerce, ça finit toujours par fuiter (CI logs, support, backups, erreurs PHP affichées).

Pour éviter ça, appliquez un minimum de discipline “12-factor”. La recommandation est explicite : “Store config in the environment.” (The Twelve-Factor App, section Config — https://12factor.net/config). Sur PrestaShop auto-hébergé, ça se traduit par : variables d’environnement au niveau PHP-FPM/Apache, ou un fichier .env.local hors VCS si vous êtes sur une stack Symfony modernisée. Si vous industrialisez déjà vos déploiements, alignez-vous sur une approche “secrets manager” (Vault/SSM) et injectez au runtime.

Quelques verrous pratiques (souvent oubliés) qui évitent des heures de debug :

  • Synchronisation de l’horloge serveur (NTP) : la signature OVH inclut un timestamp. Une dérive de temps (VM mal réglée, conteneur sans time sync) peut déclencher des erreurs d’auth difficiles à distinguer d’un “mauvais secret”.
  • Rotation et cloisonnement : une AK/AS/CK par environnement (prod / staging), et idéalement par application (back-office, worker). En cas de fuite, vous révoquez sans paralyser tout le SI.
  • Moindre privilège : ne donnez à la Consumer Key que les routes strictement nécessaires à l’envoi et au suivi. Vous limitez l’impact d’une compromission.
  • Endpoint cohérent : en Europe, l’endpoint est généralement https://eu.api.ovh.com/1.0. Évitez les endpoints “au hasard” dans le code : une variable d’environnement OVH_ENDPOINT simplifie la migration et la gestion multi-sites.

Pour la documentation et le test des routes (utile pour valider les droits AK/AS/CK et inspecter les paramètres attendus), une référence directe et stable est la console d’API OVHcloud : https://api.ovh.com/console/#/sms (à utiliser surtout en phase d’intégration, pas comme “outil de prod”).

Dernier verrou : la surface réseau. Pour l’API REST, imposez TLS et bloquez l’exfiltration : egress restrict (si votre infra le permet), durcissement des permissions du serveur, et monitoring des appels sortants. Sur les hébergements mutualisés, vous n’aurez pas toujours le contrôle, mais vous pouvez au moins : (a) réduire les droits de la CK au strict nécessaire, (b) isoler les clés par environnement (prod/staging), (c) tracer chaque envoi avec un identifiant corrélé (id commande / id panier / id client).

Intégration API OVHcloud (PHP 8.2/8.3) : envoi robuste, timeouts et idempotence

Contexte version : les exemples ci-dessous visent PHP 8.2+ (8.3 idéalement) et une intégration “propre” utilisable depuis PrestaShop 8.x (et versions ultérieures si compatibles). Côté HTTP client, vous avez deux options réalistes : (1) utiliser le SDK officiel OVH (quand il est compatible de vos contraintes), (2) appeler l’API via un client HTTP standard (cURL / Symfony HttpClient / Guzzle) pour maîtriser timeouts, retries, circuit-breaker.

Un point non négociable : ne faites pas l’appel SMS dans le thread de la requête front (checkout, page account). Le SMS est un side-effect ; si l’API met 2 secondes à répondre, vous venez de dégrader votre TTFB et votre conversion. Si vous avez besoin d’arguments terrain sur la méthode de mesure, utilisez une approche reproductible de profiling côté boutique (voir Audit performance PrestaShop : méthode reproductible et preuves terrain).

Exemple minimaliste en PHP (cURL) pour poster un job d’envoi. À adapter à l’endpoint exact et aux paramètres attendus par votre service OVHcloud (le nom de service SMS ressemble souvent à sms-xxxxxx). Le point important est la structure : timeouts courts, JSON explicite, et log des erreurs.

<?php
// PHP 8.2+

$endpoint = 'https://eu.api.ovh.com/1.0';
$serviceName = getenv('OVH_SMS_SERVICE'); // ex: sms-123456
$url = $endpoint . '/sms/' . rawurlencode($serviceName) . '/jobs/';

$payload = [
  'charset'   => 'UTF-8',
  'class'     => 'phoneDisplay',
  'coding'    => '7bit', // ou 'unicode' selon vos besoins
  'message'   => 'Votre commande #1234 est expédiée.',
  'receivers' => ['+33612345678'],
  'sender'    => 'MyShop',
  'noStopClause' => false,
];

$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => [
    'Content-Type: application/json',
    // NOTE: L’auth OVH n’est pas un simple Bearer.
    // Utilisez le SDK OVH ou implémentez correctement la signature.
  ],
  CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CONNECTTIMEOUT_MS => 500,
  CURLOPT_TIMEOUT_MS => 1500,
]);

$raw = curl_exec($ch);
$err = curl_error($ch);
$code = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

if ($raw === false || $code >= 400) {
  error_log('[OVH SMS] HTTP=' . $code . ' err=' . $err . ' body=' . ($raw ?: ''));
  throw new RuntimeException('SMS send failed');
}

$response = json_decode($raw, true);
// Stockez un identifiant de job si disponible pour traçabilité.

Deux remarques cruciales :

1) Authentification OVH : l’API OVH utilise une signature (timestamp + secret + méthode + URL + body) ; n’essayez pas de “reconstruire ça à la main” sans tests et sans validation. En pratique, utilisez le client officiel ou encapsulez une implémentation testée + tests d’intégration.

2) Idempotence et retries : si vous réessayez sur timeout, vous risquez d’envoyer deux SMS. La solution robuste : générer une clé idempotente applicative (ex. orderId + event + receiver + day) et la persister en base, puis ne pas réémettre si la clé existe. Si vous voulez une méthodologie d’intégration “forte volumétrie” (files, retries, DLQ), voyez Intégration API : synchronisation bidirectionnelle et automatisation pour forte volumétrie.

Pour rendre les retries “bons” (et pas juste “plus”), une règle simple fonctionne bien en boutique :

  • Sur 429 / quotas : retry avec backoff (par ex. 10s, 30s, 2min), en respectant éventuellement un Retry-After s’il est présent.
  • Sur timeouts / erreurs réseau transitoires : 1 à 3 retries maximum (sinon vous créez une tempête), avec jitter (une petite part d’aléatoire).
  • Sur 4xx fonctionnelles (numéro invalide, message trop long, sender refusé) : pas de retry, mais un statut failed_permanent et un log exploitable (cause, receiver, event).

Côté logs, une structure minimale fait gagner du temps en exploitation : order_id, event, receiver_e164, idempotency_key, ovh_job_id (si disponible), attempt, http_status, duration_ms. C’est ce qui permet de répondre à “combien de SMS ont échoué hier entre 18h et 20h, et sur quels événements ?” sans ouvrir la base à la main.

Email-to-SMS : utile en fallback, mais fragile si vous ne contrôlez pas votre MTA

L’Email-to-SMS consiste à envoyer un email vers une passerelle (adresse fournie par l’opérateur), qui transforme le contenu en SMS. L’avantage est évident : n’importe quel code sait envoyer un mail. L’inconvénient est structurel : vous n’avez pas un modèle d’erreur propre (SMTP != DLR SMS), et la chaîne MTA (PrestaShop → SMTP → relais → passerelle) ajoute des points de panne où les logs sont rarement corrélés.

Si vous le faites quand même (souvent pour du plan de secours), traitez-le comme un système de production : imposez un SMTP authentifié, forcez TLS, mettez DKIM/SPF/DMARC côté domaine expéditeur, et surtout loguez l’ID de message SMTP (Message-ID) en base pour pouvoir tracer. Si vous êtes sur un hébergement qui vous impose un SMTP tiers, c’est encore plus important : vous aurez des ratés silencieux, et sans preuve de soumission SMTP, le support tourne en rond.

Le piège le plus fréquent : l’encodage. Beaucoup de passerelles Email-to-SMS n’aiment pas le HTML, ni les multi-part. Envoyez du text/plain strict, court, sans caractères “exotiques” si vous voulez rester en GSM-7. Et si vous devez accepter l’UCS-2 (accents, emojis), mesurez l’impact en segments (donc en coût) et forcez une politique de tronquage côté application.

Quelques garde-fous concrets (simples mais rarement appliqués) :

  • Sujet vs corps : selon la passerelle, c’est parfois le subject qui est prioritaire, parfois le body. Décidez une règle unique (ex. “corps uniquement”), documentez-la et testez-la.
  • Longueur maximale : fixez une limite applicative (ex. 140 caractères “utiles”) pour absorber les variations de conversion et réduire les surprises de segmentation.
  • Éviter les entêtes inutiles : certaines passerelles se comportent mal si le mail contient des pièces jointes, des signatures automatiques, ou un Content-Transfer-Encoding exotique.
  • Fallback = fallback : si l’API REST échoue, ne déclenchez pas automatiquement Email-to-SMS sans idempotence, sinon vous transformez une panne partielle en double-envoi.

HTTP-to-SMS : simplicité apparente, dette technique réelle

Le HTTP-to-SMS (souvent un endpoint “legacy” avec paramètres en querystring ou formulaire) est tentant : un POST et c’est fini. En réalité, c’est rarement “fini”, parce que ce mode pousse les équipes à contourner les bonnes pratiques (auth faible, secrets dans l’URL, logs qui exposent les paramètres, absence de retries structurés). Sur des stacks PrestaShop anciennes (1.6/1.7) encore en vie, on le voit souvent parce que c’est “le seul moyen rapide” ; ça devient ensuite un point dur lors des migrations.

Si vous êtes contraint de l’utiliser, durcissez a minima :

  • Interdisez les secrets en querystring (sinon ils se retrouvent dans les logs Nginx/Apache, dans l’historique navigateur, dans les APM).
  • Fixez des timeouts courts (connect + total), et ne bloquez jamais le front.
  • Centralisez l’appel HTTP dans un service unique (pas d’appels dispersés dans des overrides/modules).

Ajoutez aussi deux protections “low cost” :

  • Masquage applicatif : si vous loguez les requêtes sortantes, masquez systématiquement les champs password, token, key, etc. (sinon votre système de logs devient une fuite).
  • Contrôle de réponse : beaucoup d’endpoints legacy renvoient 200 OK avec une erreur dans le body. Traitez le body comme une donnée métier (parse et statut), sinon vous croyez envoyer “avec succès” alors que rien n’est parti.

Pour le diagnostic en prod, le HTTP-to-SMS est souvent confondu avec des erreurs “infra” côté boutique (timeouts PHP-FPM, saturation Apache/LiteSpeed, etc.). Quand vous voyez apparaître des symptômes type “page qui mouline” ou “checkout intermittent”, remontez d’abord vos logs serveur et vos erreurs PHP avant d’accuser l’opérateur SMS. Sur ce sujet, la checklist de triage de Erreur HTTP 503 : diagnostiquer PHP et logs Apache/LiteSpeed est directement réutilisable.

Intégrer proprement dans PrestaShop (8.x) : module, hooks, file et conformité

Le cœur PrestaShop n’est pas un orchestrateur d’événements fiable. Si vous collez l’envoi SMS dans un hook sans isolation, vous allez créer des doublons (hooks déclenchés plusieurs fois, statut de commande modifié par back-office, relance client, etc.) et des pannes difficiles à rejouer. La voie propre : un module sans override, avec un service d’envoi, une couche de persistance (table ps_...), et une file (ou à défaut un cron) qui exécute les jobs hors requête web. Pour cadrer cette approche, alignez-vous sur Module PrestaShop sans override : méthode de cadrage, tests et livraison du code.

Architecture de base (qui tient la charge et reste débogable) :

  • Event source : hook actionOrderStatusPostUpdate (ou équivalent), ou action back-office contrôlée.
  • Command : création d’un enregistrement “SMS à envoyer” (statut pending, payload minimal, idempotency key).
  • Worker : cron toutes les minutes (ou worker long running) qui traite en batch : pending → sent/failed, avec retries bornés et backoff.

Une table de persistance minimaliste (utile pour la preuve et le support) ressemble souvent à ceci :

Champ Type (exemple) Pourquoi
id_sms_job int clé interne
id_order int corrélation commande
event varchar ex. order_shipped, payment_ok
receiver varchar numéro normalisé E.164
message text contenu envoyé (ou template + variables si vous préférez)
idempotency_key varchar anti double-envoi
provider_job_id varchar nullable identifiant OVH (si disponible)
status enum pending/sent/failed_permanent/failed_retryable
attempts int pilotage retries
last_error text nullable diagnostic
created_at/sent_at datetime preuve temporelle

Sur PrestaShop 8, vous pouvez exploiter Symfony (DI container) pour injecter un client HTTP et un logger PSR-3. Ne sous-estimez pas le gain : logs structurés + corrélation = support plus rapide. Et si vous mettez déjà en place une démarche de profilage et d’optimisation, gardez la cohérence outillage (APM, logs, métriques) : https://www.expertise-prestashop.fr/2026/08/25/optimisation-code-source-audit-performance-php-symfony-avec-profilage/.

La conformité n’est pas optionnelle : en UE, le consentement pour la prospection par SMS doit être géré proprement (opt-in, preuve, désinscription, finalité). La définition RGPD du consentement est sans ambiguïté : « toute manifestation de volonté, libre, spécifique, éclairée et univoque » (Règlement (UE) 2016/679, article 4(11)). Traduction technique : vous stockez quoi a été consenti, quand, par qui (client / admin), sur quel texte, et vous appliquez des règles de rétention. Pour une lecture pragmatique et à jour côté France : CNIL.

Point d’attention opérationnel (souvent sous-estimé) : en France, selon l’usage (transactionnel vs prospection) et les règles opérateurs, le contenu peut devoir inclure une mécanique de désinscription. OVHcloud expose par exemple des options liées à la “STOP clause” (selon éligibilité et contrat). Ne codez pas “au pif” : documentez votre politique interne (marketing vs transactionnel), faites valider par le juridique, puis appliquez-la de façon reproductible via des templates.

Dernier point : testez et mesurez. En staging, simulez : numéros invalides, timeouts, réponses 429 (rate limiting), erreurs 5xx, et indisponibilité DNS. En prod, surveillez : taux d’échec, distribution des latences d’appel API (p95), volume par heure, et ratio “segments SMS / message” (indicateur direct de dérive d’encodage). Si vous avez déjà une démarche d’optimisation globale boutique (profiling PHP/Symfony), réutilisez vos pratiques existantes : https://www.expertise-prestashop.fr/2026/08/25/optimisation-code-source-audit-performance-php-symfony-avec-profilage/.

Checklist de mise en production (sans folklore)

Avant d’ouvrir le robinet, verrouillez le fonctionnel : quels événements déclenchent un SMS (expédition, paiement accepté, relance panier…), à quel public (transactionnel vs marketing), et avec quelle politique de fallback (API REST puis Email-to-SMS, ou l’inverse). Écrivez ces règles en configuration versionnée, pas “dans la tête de quelqu’un”. Et forcez un format unique de message par événement, avec un jeu de variables strict (id commande, lien tracking, support).

Checklist “messages” (simple et efficace) :

  • Le numéro est normalisé en E.164 avant toute tentative d’envoi (et rejeté sinon).
  • Le template est déterministe (pas de concaténations hasardeuses selon les langues / modules).
  • Le contenu est testé en GSM-7 et en UCS-2 (au moins sur quelques cas réalistes), avec une limite de segments acceptable.
  • Le message n’expose pas de données sensibles (pas de mot de passe, pas de PII inutile).

Ensuite, verrouillez la techno : secrets en variables d’environnement, droits OVHcloud minimaux, appels asynchrones (cron/worker), timeouts agressifs, retries bornés, idempotence persistée, et logs structurés. Si vous déployez via CI/CD, ajoutez un test d’intégration “smoke” en staging (envoi vers un numéro de test contrôlé) et un “dry-run” qui valide la signature/auth sans envoyer. Pour éviter de dégrader la boutique lors des pics, appuyez-vous sur vos constats de perf (profiling, temps de réponse, saturation PHP-FPM) et gardez l’envoi SMS hors parcours client (voir aussi la démarche de mesure sur la performance boutique : https://www.expertise-prestashop.fr/2026/08/26/audit-performance-prestashop-methode-reproductible-et-preuves-terrain/).

Enfin, verrouillez l’exploitation : dashboard (taux d’erreur, latence, backlog), alertes (échec > X% sur 15 min), et runbook de diagnostic (où regarder : logs applicatifs, logs webserver, statut OVHcloud, DNS, quotas). Un cadrage de seuils “raisonnable” (à adapter) :

Indicateur Seuil d’alerte (exemple) Action
Taux d’échec (toutes causes) > 2% / 15 min qualifier erreurs (4xx vs 5xx vs timeout)
Latence API p95 > 1.5s réduire concurrence, vérifier réseau/DNS
Backlog jobs pending > 5 min de retard scaler worker / analyser blocage
Ratio segments/message +20% vs baseline suspecter UCS-2 (accents/emoji)

Si vous avez un incident, traitez-le comme un incident e-commerce classique : mesure, corrélation, preuve. Le SMS n’est pas “un petit plus”, c’est un canal critique dès qu’il est utilisé pour la livraison, la sécurité ou la relation client.


À lire aussi