Aller au contenu principal

Webhooks

Selgeo envoie des notifications HTTP POST en temps réel à votre serveur lorsque des événements se produisent dans votre compte. Utilisez les webhooks pour automatiser des workflows comme l'attribution d'accès quand un partenaire est approuvé, la synchronisation des commissions avec votre système comptable, ou l'alerte de votre équipe en cas de fraude.

Toutes les payloads webhook utilisent l'API version v1.

Enregistrement des points de terminaison

Enregistrez les points de terminaison webhook depuis la page Paramètres > Webhooks dans le tableau de bord marchand.

  1. Cliquez sur Ajouter un point de terminaison.
  2. Entrez l'URL où vous voulez recevoir les événements. Les points de terminaison en mode live doivent utiliser HTTPS. Les points de terminaison en mode test peuvent utiliser HTTP pour le développement local.
  3. Sélectionnez les événements auxquels vous souhaitez vous abonner.
  4. Cliquez sur Créer. Votre secret de signature (whsec_...) est affiché une fois — copiez-le et stockez-le en sécurité.

Vous pouvez enregistrer jusqu'à 10 points de terminaison par mode (test et live séparément).

Pings de test

Après avoir créé un point de terminaison, utilisez le bouton Envoyer un ping de test pour vérifier la connectivité. Le ping envoie un événement webhook.test à votre URL et signale le code de statut HTTP.

Rotation des secrets

Si votre secret de signature est compromis, utilisez l'action Faire pivoter le secret sur le point de terminaison. Cela génère immédiatement un nouveau secret — l'ancien cesse de fonctionner. Mettez à jour votre code de vérification avant de faire pivoter.

Vérification de signature

Chaque requête webhook inclut un en-tête X-Selgeo-Signature au format :

t=<unix_timestamp>,v1=<hmac_hex>

Le HMAC est calculé comme HMAC-SHA256(signing_secret_bytes, "<timestamp>.<raw_json_body>"). Le secret de signature a un préfixe whsec_ suivi de 64 caractères hexadécimaux. Supprimez le préfixe et décodez en hexadécimal pour obtenir la clé de 32 octets.

Vérifiez toujours la signature avant de traiter la payload. Cela protège contre les requêtes falsifiées.

Exemples de vérification

import crypto from 'node:crypto';

function verifyWebhookSignature(signingSecret, signatureHeader, rawBody) {
if (!signatureHeader) {
return false;
}

// Supprimer le préfixe whsec_ et décoder en hex pour obtenir les octets de clé bruts
const rawSecret = signingSecret.replace(/^whsec_/, '');
const secretBytes = Buffer.from(rawSecret, 'hex');

// Analyser l'en-tête : t=<ts>,v1=<hmac>
const parts = Object.fromEntries(
signatureHeader.split(',').map((part) => {
return part.split('=', 2);
})
);

const timestamp = parts.t;
const receivedHmac = parts.v1;

if (!timestamp || !receivedHmac) {
return false;
}

// Rejeter les horodatages de plus de 5 minutes ou dans le futur (avec tolérance de 30s)
const age = Math.floor(Date.now() / 1000) - parseInt(timestamp, 10);
if (age > 300 || age < -30) {
return false;
}

// Calculer le HMAC attendu
const expectedHmac = crypto
.createHmac('sha256', secretBytes)
.update(`${timestamp}.${rawBody}`)
.digest('hex');

// Comparaison en temps constant (les buffers doivent avoir la même longueur)
const receivedBuf = Buffer.from(receivedHmac, 'hex');
const expectedBuf = Buffer.from(expectedHmac, 'hex');
if (receivedBuf.length !== expectedBuf.length) {
return false;
}
return crypto.timingSafeEqual(receivedBuf, expectedBuf);
}

// Utilisation dans un handler Express
app.post('/webhooks/selgeo', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-selgeo-signature'];
const rawBody = req.body.toString();

if (!verifyWebhookSignature('whsec_YOUR_SIGNING_SECRET', signature, rawBody)) {
return res.status(401).send('Invalid signature');
}

const event = JSON.parse(rawBody);
console.log('Événement reçu :', event.event_name);

// Traiter l'événement...

res.status(200).send('OK');
});
astuce

Utilisez toujours la chaîne brute du corps de la requête pour la vérification de signature, pas une version re-sérialisée du JSON analysé. La re-sérialisation peut changer l'ordre des clés ou les espaces, ce qui invalide le HMAC.

Catalogue d'événements

Chaque payload webhook inclut ces champs d'enveloppe :

ChampTypeDescription
event_idstringID unique pour cet événement (nanoid, 21 chars)
delivery_idstringID unique pour cette tentative de livraison
event_namestringType d'événement (voir tableau ci-dessous)
occurred_atstringHorodatage ISO 8601
merchant_idstringVotre ID de compte marchand
mode"test" | "live"Si cet événement s'est produit en mode test ou live
api_version"v1"Version de l'API

Événements partenaires

ÉvénementDescription
participant.createdUn nouveau partenaire a postulé ou a été ajouté à un programme
participant.approvedUn partenaire a été approuvé (manuellement ou via approbation automatique)
participant.rejectedUne candidature partenaire a été rejetée
participant.suspendedUn partenaire actif a été suspendu
participant.reinstatedUn partenaire suspendu a été réintégré
participant.erasedLes données d'un partenaire ont été effacées (RGPD)
participant.data_exportedLes données d'un partenaire ont été exportées (RGPD)

Événements d'attribution

ÉvénementDescription
attribution.createdUn clic a été attribué à un partenaire
attribution.convertedUn clic attribué a abouti à une conversion
attribution.expiredUne fenêtre d'attribution a expiré sans conversion
attribution.duplicate_detectedUne attribution en double a été détectée

Événements de conversion

ÉvénementDescription
conversion.createdUne nouvelle conversion a été enregistrée
conversion.fraud_detectedUne fraude a été détectée (auto-référencement ou conversion en double)

Événements de commission

ÉvénementDescription
commission.createdUne nouvelle commission a été calculée
commission.approvedUne commission a été approuvée pour paiement
commission.rejectedUne commission a été rejetée
commission.paidUne commission a été incluse dans un paiement (bientôt disponible)
commission.refundedUne commission a été annulée suite à un remboursement

Événements de paiement (bientôt disponible)

Les événements de paiement seront disponibles lors du lancement de la fonctionnalité de traitement des paiements.

ÉvénementDescription
payout.createdUn lot de paiements a été créé
payout.initiatedUn virement de paiement a été initié
payout.paidUn paiement a été transféré avec succès
payout.failedUn transfert de paiement a échoué
payout.retriedUn paiement échoué a été réessayé
payout.cancelledUn paiement a été annulé

Événements de suivi

ÉvénementDescription
tracking_identifier.createdUn nouveau lien de suivi a été créé pour un partenaire

Événements de code promo

ÉvénementDescription
promo_code.createdUn code promo a été créé
promo_code.stripe_syncedUn code promo a été synchronisé avec Stripe
promo_code.deactivatedUn code promo a été désactivé

Événements d'invitation au programme

ÉvénementDescription
program_invite.createdUne invitation a été créée
program_invite.acceptedUne invitation a été acceptée par un partenaire
program_invite.revokedUne invitation a été révoquée
program_invite.expiredUne invitation a expiré

Politique de réessai

Si votre point de terminaison retourne un code de statut non-2xx ou si la requête expire (30 secondes), Selgeo réessaie avec un backoff exponentiel :

TentativeDélai après échec
1ère tentative1 minute
2ème tentative2 minutes
3ème tentative4 minutes
4ème tentative15 minutes

Après 5 tentatives au total (1 initiale + 4 réessais), la livraison passe à l'état dead-letter. Les livraisons dead-letter sont visibles dans le tableau de bord marchand sous le journal de livraison du point de terminaison mais ne sont pas réessayées automatiquement.

Meilleures pratiques

  • Retourner 200 rapidement. Accusez réception avec un code de statut 200 dès que vous recevez le webhook. Traitez l'événement de manière asynchrone dans une tâche en arrière-plan. Selgeo expire après 30 secondes.
  • Gérer les doublons. Utilisez le champ event_id pour dédupliquer. Le même événement peut être livré plus d'une fois dans de rares cas (ex. expiration réseau juste après que votre serveur l'ait traité).
  • Vérifier les signatures. Vérifiez toujours l'en-tête X-Selgeo-Signature. Ne traitez jamais les payloads non vérifiées.
  • Vérifier l'horodatage. Rejetez les signatures avec des horodatages de plus de 5 minutes ou trop loin dans le futur pour prévenir les attaques par rejeu.
  • Utiliser HTTPS en production. Les points de terminaison en mode live nécessitent HTTPS. Les points de terminaison en mode test permettent HTTP pour la commodité du développement local.
  • Surveiller les livraisons dead-letter. Vérifiez périodiquement le journal de livraison dans le tableau de bord. Les événements dead-letter peuvent indiquer une panne du point de terminaison ou un bug dans votre handler.