Aller au contenu principal

Webhook : changement de palier (tier/changed)

Enkore envoie un webhook à chaque fois qu'un consommateur change de palier (promotion, rétrogradation, affectation initiale, ou réévaluation périodique). Ce document explique comment configurer un endpoint pour recevoir cet événement et réagir en conséquence.


Déclencheurs

Le webhook tier/changed est émis dans quatre situations :

Raison (reason)Description
promotionLe consommateur monte d'un palier (ex : passe de Silver à Gold)
demotionLe consommateur descend d'un palier (ex : passe de Gold à Silver)
initialLe consommateur est affecté à son premier palier
evaluationRéévaluation périodique sans changement de direction particulier

Format du payload

Enkore envoie une requête POST en application/json vers l'URL configurée dans le back-office.

Exemple de payload — promotion

{
"event": "tier/changed",
"customerId": 42,
"reason": "promotion",
"pointsInPeriod": 1250,
"from": {
"name": "Silver",
"slug": "silver",
"rank": 1,
"minPoints": 500
},
"to": {
"name": "Gold",
"slug": "gold",
"rank": 2,
"minPoints": 1000
}
}

Exemple de payload — affectation initiale

Lors de la première affectation d'un consommateur à un palier, le champ from est null.

{
"event": "tier/changed",
"customerId": 42,
"reason": "initial",
"pointsInPeriod": 0,
"from": null,
"to": {
"name": "Bronze",
"slug": "bronze",
"rank": 0,
"minPoints": 0
}
}

Description des champs

ChampTypeDescription
eventstringToujours "tier/changed"
customerIdnumberIdentifiant externe du consommateur (correspond à l'ID dans votre plateforme e-commerce)
reasonstringRaison du changement : promotion, demotion, initial, ou evaluation
pointsInPeriodnumberNombre de points cumulés sur la période d'évaluation
fromobject | nullPalier de départ. null si c'est la première affectation
from.namestringNom du palier de départ
from.slugstringSlug du palier de départ
from.ranknumberRang du palier de départ (0 = palier le plus bas)
from.minPointsnumberPoints minimum requis pour ce palier
toobjectPalier d'arrivée
to.namestringNom du nouveau palier
to.slugstringSlug du nouveau palier
to.ranknumberRang du nouveau palier
to.minPointsnumberPoints minimum requis pour ce palier

Headers envoyés par Enkore

Enkore ajoute les headers suivants à chaque requête webhook :

HeaderDescription
Content-Typeapplication/json
User-AgentEnkore.io/1.0
X-Enkore-EventType de l'événement, ex : tier/changed
X-Enkore-DeliveryUUID unique identifiant cet envoi (utile pour la déduplication)
X-Enkore-TimestampTimestamp Unix (secondes) au moment de l'envoi
X-Enkore-SignatureSignature HMAC-SHA256 du payload (voir section Sécurité)

Comportement de livraison

  • L'envoi est asynchrone : le webhook est déclenché après la mise à jour du palier, via une file de traitement (BullMQ).
  • Enkore attend une réponse dans un délai de 10 secondes. Au-delà, la requête est annulée.
  • En cas d'erreur réseau, de timeout ou de réponse HTTP non-2xx, une nouvelle tentative automatique est effectuée par BullMQ selon sa politique de retry.
  • Votre endpoint doit retourner un code HTTP 2xx rapidement pour confirmer la réception.

Sécurité

Signature HMAC

Enkore signe chaque payload avec votre API key (clé API de votre store, visible dans le back-office). La signature est transmise dans le header X-Enkore-Signature au format :

X-Enkore-Signature: t=<timestamp>,v1=<hmac_hex>
  • t : timestamp Unix en secondes (identique au header X-Enkore-Timestamp)
  • v1 : HMAC-SHA256 calculé sur la chaîne <timestamp>.<body_json>, encodé en hexadécimal

Déduplication

Le header X-Enkore-Delivery contient un UUID unique par envoi. En cas de retry BullMQ, un nouvel UUID est généré. Vous pouvez stocker ces UUIDs pour détecter et ignorer d'éventuels doublons côté réception.

Bonnes pratiques

  • Vérifiez toujours la signature HMAC avant de traiter le payload
  • Utilisez timingSafeEqual (Node.js) ou hash_equals (PHP) pour la comparaison, afin d'éviter les attaques par timing
  • Votre endpoint doit être accessible uniquement en HTTPS
  • Rejetez les requêtes dont le timestamp dépasse 5 minutes