Corrigez les erreurs de vérification de la signature du webhook
Découvrez comment corriger une erreur courante lors de l'écoute d'événements de webhook.
Lorsque vous traitez des événements de webhook, nous vous recommandons de sécuriser votre endpoint en vérifiant que l’événement provient bien de Stripe. Pour ce faire, utilisez l’en-tête Stripe-Signature et appelez la fonction constructEvent() avec trois paramètres :
requestBody: la chaîne du corps de la requête envoyée par Stripe.signature: l’en-tête Stripe-Signature dans la requête envoyée par Stripe.endpointSecret: la clé secrète associée à votre endpoint.
Cette fonction peut ressembler à ceci :
Si vous obtenez l’erreur suivante, Échec de vérification de signature webhook, au moins l’un des trois paramètres que vous avez transmis à la fonction constructEvent() est incorrect.
Webhook signature verification failed. Err: No signatures found matching the expected signature for payload.
Vérifier la clé secrète de l’endpoint
L’erreur la plus courante est l’utilisation de la mauvaise clé secrète endpoint. Si vous utilisez un endpoint webhook créé dans le Dashboard, ouvrez l’endpoint dans le Dashboard et cliquez sur le lien Révéler la clé secrète près du haut de la page pour afficher la clé secrète. Si vous utilisez la CLI de Stripe, la clé secrète est imprimée dans le Terminal lorsque vous exécutez la commande Stripe listen.
Dans les deux cas, la clé secrète commence par un préfixe whsec_, mais la clé secrète elle-même est différente. Ne vérifiez pas les signatures sur les événements transférés par la CLI en utilisant la clé secrète d’un endpoint géré par le Dashboard, ou l’inverse. Enfin, imprimez l’endpointSecret utilisé dans votre code, et assurez-vous qu’il correspond à celui que vous avez trouvé ci-dessus.
Vérifier le corps de la requête
Le corps de la requête doit être la chaîne de caractères que Stripe envoie en encodage UTF-8 sans aucune modification. Lorsque vous l’imprimez en tant que chaîne, il ressemble à ceci :
{ "id": "evt_xxx", "object": "event", "data": { ... } }
Récupérer le corps de la requête brute
Certains cadres peuvent modifier le corps de la requête en ajoutant ou en supprimant des espaces, en réorganisant les paires clé-valeur, en convertissant la chaîne en JSON ou en changeant l’encodage. Dans tous ces cas, la vérification de la signature échoue.
Voici une liste non exhaustive de structures qui peuvent analyser ou modifier les données à l’aide de configurations courantes, ainsi que quelques conseils pour obtenir le corps de la requête brute.
| Cadre | Méthode de recherche |
|---|---|
| Bibliothèque stripe-node avec Express | Suivez notre guide de démarrage rapide de l’intégration. |
| Bibliothèque stripe-node avec Body Parser | Essayez les solutions répertoriées dans ce problème GitHub. |
| Bibliothèque stripe-node avec App Router de Next.js | Jetez un coup d’œil à cet exemple. |
| Bibliothèque stripe-node avec Pages Router de Next.js | Essayez de désactiver bodyParser et d’utiliser buffer(request), comme dans cet exemple. |
Si vous utilisez la bibliothèque stripe-node avec Express, assurez-vous que app. est placée après l’acheminement du webhook. Dans Express, l’ordre de configuration du middleware est important. Si express. est appliqué avant que l’acheminement de votre webhook, il analyse le corps de la requête avant la vérification de la signature, ce qui entraîne l’échec de la vérification. Par exemple :
// Webhook route in its original request form app.post('/webhook', ...); // Parse the request body in JSON for other routes app.use(express.json()); // Put other routes here app.post('/another-route', ...);
Plateforme API AWS avec la fonction Lambda
Pour récupérer le corps de la requête brute pour la passerelle API AWS avec la fonction Lambda, configurez dans la passerelle API un modèle de mappage du corps de type de contenu application/json comme suit :
{ "method": "$context.httpMethod", "body": $input.json('$'), "rawBody": "$util.escapeJavaScript($input.body).replaceAll("\\'", "'")", "headers": { #foreach($param in $input.params().header.keySet()) "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end #end } }
Ensuite, dans la fonction Lambda, accédez au corps brut avec la propriété de l’événement rawBody et aux en-têtes avec la propriété de l’événement headers.
Vérifier la signature
Imprimez le paramètre signature et confirmez qu’il ressemble à ceci :
t=xxx,v1=yyy,v0=zzz
Si ce n’est pas le cas, vérifiez si vous avez un problème dans votre code lorsque vous essayez d’extraire la signature de l’en-tête.