Vérifier la signature des webhooks
July 30, 2026
Vérifiez l'authenticité des webhooks FlowAlp Pay : contrôle de signature HMAC-SHA256 en PHP, schéma ApiSignature et test via SignatureCheck.
Un endpoint webhook est une porte d'entrée dans votre système de commandes : chaque événement entrant doit prouver qu'il vient réellement de FlowAlp Pay. Deux mécanismes se complètent : l'en-tête de signature du webhook lui-même et la validation côté serveur via la Merchant API.
Fonctionnement de la signature webhook
Chaque webhook porte l'en-tête HTTP X-Webhook-Signature. Sa valeur est un HMAC-SHA256 calculé sur le corps brut de la requête avec votre clé de signature, encodé en hexadécimal minuscule. Trois détails comptent :
- Données signées : le corps brut et non modifié de la requête — ne resérialisez jamais le JSON parsé avant le hachage.
- Encodage de la clé : la clé de signature s'utilise comme simple chaîne UTF-8 ; elle n'est pas décodée depuis Base64.
- Encodage de la signature : le résultat est en hex minuscule — pas en Base64.
La clé de signature appartient à votre configuration webhook dans le dashboard sur https://pay.flowalp.com. Si vos réglages webhook n'affichent pas de clé de signature pour votre compte, ne devinez ni noms d'en-têtes ni clés : appuyez-vous sur la validation côté API décrite ci-dessous et confirmez la disponibilité de la signature pour votre compte auprès du support FlowAlp avant la mise en production.
<?php
// Reject any webhook whose signature does not match
$rawBody = file_get_contents('php://input');
$received = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$signingKey = getenv('FLOWALP_WEBHOOK_SIGNING_KEY');
// Lowercase hex HMAC-SHA256 of the raw body; the key is a plain UTF-8 string
$expected = hash_hmac('sha256', $rawBody, $signingKey);
if (!hash_equals($expected, $received)) {
http_response_code(401); // non-2xx: the delivery counts as failed
exit('invalid signature');
}
http_response_code(200);
// Queue the event for asynchronous, idempotent processingUtilisez hash_equals() (ou la comparaison à temps constant de votre langage) contre les attaques par timing, et répondez aux livraisons non signées ou invalides par un statut non-2xx comme 401 — sans jamais les traiter.
Ne pas confondre avec ApiSignature
La Merchant API connaît un second HMAC, indépendant : le mode d'authentification ApiSignature pour les requêtes API sortantes. Distinguez bien les deux :
| Aspect | Signature webhook | ApiSignature |
|---|---|---|
| Ce qui est signé | Corps POST brut du webhook entrant | Paramètres de requête triés alphabétiquement et URL-encodés (tous sauf instance) |
| Clé | Clé de signature des webhooks | Votre API Secret |
| Encodage | Hexadécimal minuscule | Base64 |
| Transport | En-tête X-Webhook-Signature, entrant | Paramètre ApiSignature, sortant |
<?php
function flowalpApiSignature(array $params, string $apiSecret): string
{
ksort($params);
$query = http_build_query($params, '', '&');
return base64_encode(hash_hmac('sha256', $query, $apiSecret, true));
}Les règles exactes d'encodage des paramètres pour ApiSignature sont documentées dans Authentification de la Merchant API.
Valider les identifiants avec SignatureCheck
La ressource SignatureCheck vérifie le nom d'instance, l'API Secret et — en mode signature — votre implémentation HMAC, sans rien créer. Appelez-la lors du setup et depuis vos health checks :
https://api.pay.flowalp.com/v1.16/SignatureCheck/v1.14 · v1.15 · v1.16<?php
use FlowAlpPay\FlowAlpPay;
use FlowAlpPay\Models\Request\SignatureCheck;
$client = new FlowAlpPay(
getenv('FLOWALP_TENANT'),
getenv('FLOWALP_API_SECRET'),
FlowAlpPay::DEFAULT_COMMUNICATION_HANDLER,
'pay.flowalp.com',
'1.16'
);
try {
$client->getOne(new SignatureCheck());
// Credentials are valid
} catch (\FlowAlpPay\FlowAlpPayException $e) {
// Wrong instance name or API secret
}Détails et réponses d'erreur sur la page de référence SignatureCheck ; la configuration du client est traitée dans le guide du SDK PHP.
Défense en profondeur
- Rejetez les webhooks non signés ou invalides avec une réponse non-2xx et alertez en cas d'échecs répétés.
- Traitez les événements vérifiés de façon idempotente — déduplication sur ID de transaction plus statut.
- Pour les changements d'état à enjeu financier, récupérez en plus la transaction via l'API avant d'exécuter.
- Conservez le résultat de la vérification à côté du payload brut pour les audits.
Étape suivante : repassez en revue les payloads webhook que votre handler doit gérer, puis suivez la checklist de mise en production.