Aller au contenu principal

Vérification de signature

Chaque requête webhook inclut un header de signature que vous devez vérifier pour vous assurer que la requête provient bien d’Ikawaari.

Fonctionnement​

Chaque endpoint webhook possède un secret de signature unique (commence par whsec_). Ikawaari utilise ce secret pour générer une signature HMAC-SHA256 incluse dans le header Ikawaari-Signature.

Le secret est affiché une seule fois à la création ou après une rotation. Si vous ne l’avez plus, faites tourner le secret et mettez à jour votre backend marchand. Ce secret est différent de votre clé API Ikawaari.

La vérification doit utiliser le corps brut exact reçu par votre serveur. Ne parsez pas puis ne re-sérialisez pas le JSON avant de calculer la signature: les espaces, l’ordre ou l’encodage peuvent changer et provoquer un rejet valide.

Étapes de vérification​

1. Extraire la signature​

Ikawaari-Signature: t=1708300800,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

2. Préparer le payload signé​

{timestamp}.{raw_body}

3. Calculer la signature attendue​

import Ikawaari from '@ikawaari/sdk';

const client = new Ikawaari({ apiKey: process.env.IKAWAARI_API_KEY });

const event = client.webhooks.constructEvent(
rawBody,
request.headers['ikawaari-signature'],
process.env.IKAWAARI_WEBHOOK_SECRET
);

Avec Express, exposez le corps brut sur cette route:

app.post('/webhooks/ikawaari', express.raw({ type: 'application/json' }), (req, res) => {
const event = client.webhooks.constructEvent(
req.body.toString('utf8'),
req.headers['ikawaari-signature'],
process.env.IKAWAARI_WEBHOOK_SECRET
);

res.sendStatus(200);
});

Sans SDK:

const crypto = require('crypto');

function verifyWebhookSignature(payload, header, secret) {
const [tPart, vPart] = header.split(',');
const timestamp = tPart.split('=')[1];
const signature = vPart.split('=')[1];

const signedPayload = `${timestamp}.${payload}`;
const expected = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');

// Comparaison sûre vis-à-vis du timing
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}

4. Rejeter les événements trop anciens​

Vérifiez que l’horodatage se trouve dans une fenêtre de 5 minutes par rapport à l’heure courante afin de prévenir les attaques par rejeu.

attention

Vérifiez toujours les signatures webhook en production. Ne faites jamais confiance à un payload webhook sans vérification.