Guide des webhooks

Installation API de base webhooks sortants (X-Webhook-Signature) pour les événements de licence et de plateforme.

Pour utiliser les webhooks de paiement Pay Payer les webhooks du marchand. Pour la signature de redirection miroir, voir SDK miroir.

Aperçu

Les webhooks vous permettent de recevoir des notifications en temps réel lorsque des événements se produisent dans votre compte LicenseChain via le API de base (POST /v1/webhooks). Utilisation des événements marchands payants Payer les webhooks du marchand; Les redirections miroir utilisent le SDK miroir flux de signature.

Ce que vous apprendrez

Installation et configuration

  • Création et gestion de webhooks
  • Configuration des points de terminaison du webhook
  • Configuration des abonnements aux événements
  • Sécurité et signatures des webhooks

Mise en œuvre

  • Réception d'événements webhook
  • Vérifier les signatures des webhooks
  • Gérer les échecs des webhooks
  • Test des points de terminaison du webhook

Création de webhooks

1. Créez un point de terminaison Webhook

Tout d'abord, créez un point de terminaison HTTP dans votre application qui peut recevoir les requêtes POST de LicenseChain.

// Express.js Example
app.post('/webhooks/licensechain', async (req, res) => {'{'}
  const signature = req.headers['x-webhook-signature'];
  const timestamp = req.headers['x-webhook-timestamp'];
  const payload = JSON.stringify(req.body);
  
  // Verify signature (see Security section)
  if (!verifySignature(payload, signature, timestamp, webhookSecret)) {'{'}
    return res.status(401).send('Invalid signature');
  {'}'}
  
  // Process webhook event
  const event = req.body;
  console.log('Received event:', event.type, event.data);
  
  res.status(200).send('OK');
{'}'});

2. Enregistrez votre webhook

Utilisez l'API LicenseChain pour enregistrer votre point de terminaison webhook. Vous devrez fournir l'URL et spécifier les événements que vous souhaitez recevoir.

POST /v1/webhooks
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{'{'}
  "url": "https://your-app.com/webhooks/licensechain",
  "events": ["license.created", "license.updated", "license.revoked"],
  "secret": "optional-custom-secret"
{'}'}

Note: Si vous ne fournissez pas de secret, LicenseChain en générera automatiquement un pour vous. Assurez-vous de stocker ce secret en toute sécurité, car vous en aurez besoin pour vérifier les signatures des webhooks.

3. Événements disponibles

LicenseChain prend en charge les événements webhook suivants :

licence.créée Déclenché lorsqu'une nouvelle licence est créée
licence.mise à jour Déclenché lorsqu'une licence est mise à jour
licence.révoquée Déclenché lorsqu'une licence est révoquée ou suspendue
licence.expirée Déclenché à l'expiration d'une licence
utilisateur.enregistré Déclenché lorsqu'un nouvel utilisateur s'inscrit
application.créée Déclenché lorsqu'une nouvelle application est créée

Vérification de sécurité et de signature

Signatures de webhooks

Toutes les demandes de webhook incluent une signature dans le X-Webhook-Signature en-tête. La signature est HMAC-SHA256 du corps brut de la requête utilisant votre secret webhook. Vérifiez toujours en utilisant comparaison à temps constant (par ex. crypto.timingSafeEqual) pour empêcher les attaques temporelles. La valeur de l'en-tête peut être hexadécimale brute ou sha256= suivi de hex ; dépouiller le sha256= préfixe avant de comparer les tampons hexadécimaux afin que les longueurs correspondent.

// Node.js Example (constant-time, supports sha256= prefix)
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {'{'}
  if (!payload || !signature || !secret) return false;
  const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');
  const received = String(signature).startsWith('sha256=') ? String(signature).slice(7) : String(signature);
  const a = Buffer.from(expected, 'hex');
  const b = Buffer.from(received, 'hex');
  if (a.length !== b.length) return false;
  return crypto.timingSafeEqual(a, b);
{'}'}

// In your webhook handler (use raw body for payload)
const signature = req.headers['x-webhook-signature'];
const payload = req.rawBody || JSON.stringify(req.body);
if (!verifySignature(payload, signature, webhookSecret)) {'{'}
  return res.status(401).send('Invalid signature');
{'}'}

En-têtes de demande

LicenseChain inclut les en-têtes suivants avec chaque demande de webhook :

X-Webhook-Signature Signature HMAC-SHA256 du corps de la demande
X-Webhook-Timestamp Horodatage Unix de l'envoi du webhook
Content-Type Toujours application/json

Structure des événements Webhook

Tous les événements webhook suivent une structure cohérente :

{'{'}
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "type": "license.created",
  "data": {'{'}
    "id": "license-id",
    "licenseKey": "ABC123...",
    "userId": "user-id",
    "productId": "product-id",
    "status": "active",
    "expiresAt": "2024-12-31T23:59:59Z",
    "createdAt": "2024-01-01T00:00:00Z"
  {'}'},
  "timestamp": "2024-01-01T00:00:00Z",
  "signature": "hmac-sha256-signature"
{'}'}

Gestion des webhooks

Répertorier tous les webhooks

GET /v1/webhooks?page=1&limit=10
Authorization: Bearer YOUR_API_KEY

Obtenir les détails du webhook

GET /v1/webhooks/:id
Authorization: Bearer YOUR_API_KEY

Mettre à jour le webhook

PUT /v1/webhooks/:id
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{'{'}
  "url": "https://new-url.com/webhooks",
  "events": ["license.created", "license.updated"]
{'}'}

Supprimer le webhook

DELETE /v1/webhooks/:id
Authorization: Bearer YOUR_API_KEY

Test des webhooks

Envoyer un webhook de test

Vous pouvez tester votre point de terminaison webhook sans attendre qu'un événement réel se produise :

POST /v1/webhooks/:id/test
Authorization: Bearer YOUR_API_KEY

Cela enverra un événement de test à l'URL de votre webhook avec un exemple de charge utile. Utilisez-le pour vérifier que votre point de terminaison fonctionne correctement.

Afficher les journaux des webhooks

Vérifiez l'état de livraison et la réponse pour chaque événement webhook :

GET /v1/webhooks/:id/logs?page=1&limit=10
Authorization: Bearer YOUR_API_KEY

Les journaux incluent le code d'état HTTP, le corps de la réponse et si la livraison a réussi.

Meilleures pratiques

✅ Vérifiez toujours les signatures

Ne traitez jamais les événements de webhook sans vérifier la signature. Cela garantit que la demande provient de LicenseChain et n'a pas été falsifiée.

✅ Répondez rapidement

Votre point de terminaison webhook devrait répondre dans les 5 secondes. Pour les opérations de longue durée, reconnaissez immédiatement le webhook et traitez-le de manière asynchrone.

✅ Gérer l'idempotence

Utilisez l'ID d'événement pour éviter de traiter le même événement plusieurs fois. Stockez les ID d’événement traités et vérifiez avant le traitement.

✅ Utilisez HTTPS

Utilisez toujours HTTPS pour vos points de terminaison de webhook afin de garantir que les données sont chiffrées pendant le transit.

✅ Surveiller les journaux Webhook

Vérifiez régulièrement les journaux des webhooks pour identifier et résoudre les problèmes de livraison. Configurez des alertes pour les livraisons échouées.

Dépannage

Webhook ne reçoit pas d'événements

  • • Vérifiez que l'URL de votre webhook est accessible depuis Internet.
  • • Vérifiez que votre point de terminaison renvoie un code d'état 2xx.
  • • Assurez-vous que les événements auxquels vous êtes abonné se produisent réellement
  • • Examiner les journaux de webhooks pour détecter les erreurs de livraison.

Échec de la vérification de la signature

  • • Assurez-vous que vous utilisez le bon secret de webhook.
  • • Vérifiez que vous signez le corps exact de la requête (sous forme de chaîne JSON).
  • • Vérifiez que vous utilisez l'algorithme HMAC-SHA256.
  • • Assurez-vous que les en-têtes sont lus correctement (sensible à la casse).

Erreurs de délai d'attente

  • • Optimisez votre gestionnaire de webhook pour répondre rapidement
  • • Déplacer les traitements lourds vers les tâches en arrière-plan
  • • Renvoyer immédiatement 200 OK et traiter de manière asynchrone

Prochaines étapes