Webhooks Data Center
Les webhooks permettent à des applications externes de recevoir des notifications en temps réel lorsque certains événements se produisent dans le Babel Licensing Service. Utilisez-les pour connecter vos systèmes existants, automatiser des flux de travail et maintenir les données synchronisées.

Webhooks
Accéder aux webhooks
Les webhooks sont accessibles depuis le menu de navigation principal du Babel Licensing Service. Cliquez sur l’élément de menu « Webhooks » dans la barre latérale gauche pour ouvrir l’interface de gestion des webhooks.
Gérer les webhooks
Afficher les webhooks
La page des webhooks affiche un tableau de tous les abonnements webhook configurés, avec leurs détails :
- Name : nom descriptif du webhook
- URL : point de terminaison auquel les notifications d’événement sont envoyées. L’URL n’est affichée sous forme de lien cliquable que si elle utilise http ou https.
- Event : type d’événement auquel le webhook est abonné
- Owner User : utilisateur qui a créé le webhook
- Sent At : horodatage de la dernière remise d’événement
- Next Retry : moment de la prochaine tentative de remise (le cas échéant)
- Status : état actuel du webhook (OK, Error, etc.)
Ajouter un webhook
Ouvrir le formulaire de nouveau webhook
Cliquez sur le bouton « + ADD » (Ajouter) dans l’angle supérieur droit de la page des webhooks.
Renseigner les informations obligatoires
- Name : saisissez un nom descriptif pour le webhook
- URL : indiquez l’URL du point de terminaison auquel les notifications doivent être envoyées
- Event : sélectionnez le ou les types d’événement auxquels vous voulez vous abonner
- Secret : générez ou saisissez une clé secrète pour la vérification des requêtes
Enregistrer le webhook
Cliquez sur « Save » (Enregistrer) pour créer l’abonnement webhook.
Modifier un webhook
Trouver le webhook
Trouvez le webhook dans la liste.
Ouvrir l’éditeur
Cliquez sur l’icône de modification (crayon) de la ligne.
Modifier les détails
Modifiez les détails du webhook.
Enregistrer vos modifications
Cliquez sur « Save » pour mettre à jour l’abonnement webhook.
Supprimer un webhook
Trouver l’abonnement webhook
Trouvez l’abonnement webhook dans la liste.
Le supprimer
Cliquez sur l’icône de suppression (corbeille) de la ligne.
Confirmer la suppression
Confirmez la suppression lorsque le système vous le demande.
Tester un webhook
Trouver l’abonnement webhook
Trouvez l’abonnement webhook dans la liste.
Envoyer un événement de test
Cliquez sur l’icône d’actualisation pour envoyer un événement de test.
Consulter le résultat de la remise
Consultez le résultat de la remise dans les détails des événements du webhook.
Le système traite l’événement de test avec le même mécanisme de remise que les événements réels, y compris les mêmes en-têtes et la même vérification de signature, ce qui vous permet de valider la façon dont votre point de terminaison traite les charges utiles des webhooks.
Détails des événements d’un webhook
Lorsqu’un webhook est déclenché, la vue développée affiche les détails de la remise :
- Timestamp : moment où l’événement s’est produit
- Event Type : type d’événement (par exemple license.created)
- Status : état de la remise (OK, Failed)
- Response : réponse reçue de votre point de terminaison
- Error : messages d’erreur éventuels (si la remise a échoué)
- Retry Count : nombre de tentatives de remise
- Next Retry : moment de la prochaine tentative (le cas échéant)
Événements pris en charge
Le Babel Licensing Service prend en charge les événements webhook suivants :
Licences
- license.created Déclenché lorsqu’une nouvelle licence est créée.
- license.updated Déclenché lorsqu’une licence existante est mise à jour.
- license.deleted Déclenché lorsqu’une licence est supprimée.
- license.expiring Déclenché lorsqu’une licence est sur le point d’expirer.
- license.expired Déclenché lorsqu’une licence a expiré.
- license.revoked Déclenché lorsqu’une licence est révoquée.
- license.supportexpiring Déclenché lorsque la maintenance d’une licence est sur le point d’expirer.
- license.supportexpired Déclenché lorsque la maintenance d’une licence a expiré.
- license.activated Déclenché lorsqu’une licence est activée.
- license.deactivated Déclenché lorsqu’une licence est désactivée.
- license.requested Déclenché lorsqu’une licence est demandée.
- license.released Déclenché lorsqu’une licence est libérée.
Commandes
- order.created Déclenché lorsqu’une nouvelle commande est créée.
- order.updated Déclenché lorsqu’une commande existante est mise à jour.
- order.deleted Déclenché lorsqu’une commande est supprimée.
Rapports
report.created Déclenché lorsqu’un nouveau rapport est créé.
Référence des charges utiles des webhooks
Cette section décrit en détail la structure et le contenu des charges utiles des événements webhook pour les différents types d’événement.
Charge utile d’un événement de licence
Lors du traitement d’un événement de licence (comme license.created), la charge utile contient les champs suivants :
{
"id": 101,
"licenseId": "LIC-0001",
"userKey": "XJK-SHJD-GE5E",
"licensee": "Acme Corp",
"licensingMode": 1,
"issueDate": "2025-03-16T00:00:00Z",
"supportExpireDate": "2026-03-16T00:00:00Z",
"expireDate": "2025-12-31T23:59:59Z",
"customerId": 501,
"orderId": 302,
"templateId": 10,
"revoked": false,
"trace": false,
"eventType": "license.created",
"timestamp": "2025-03-16T12:00:00Z"
}| Champ | Type | Description |
|---|---|---|
id | Entier | Identifiant unique de la licence dans la base de données. Sert de référence pour l’API et pour le suivi interne. |
licenseId | Chaîne | Identifiant de licence lisible (par exemple « LIC-0001 »), utilisé dans les communications avec les clients et dans la documentation. |
userKey | Chaîne | Clé d’activation que les utilisateurs finaux saisissent pour activer le logiciel sous licence. |
licensee | Chaîne | Nom de la personne ou de l’organisation à laquelle la licence est émise. |
licensingMode | Entier | Mode de licence appliqué (par exemple « 0: File », « 1: Activation », « 2: Floating »). |
issueDate | Date et heure ISO 8601 | Date et heure de l’émission initiale de la licence. |
supportExpireDate | Date et heure ISO 8601 | Date et heure de fin de la maintenance (assistance technique) de cette licence. |
expireDate | Date et heure ISO 8601 | Date et heure auxquelles la licence elle-même expire et n’est plus valide. |
customerId | Entier | Référence au client propriétaire de cette licence. Correspond à un enregistrement client du système. |
orderId | Entier | Référence à la commande par laquelle cette licence a été achetée. |
templateId | Entier | Identifiant du modèle de licence utilisé pour générer cette licence, qui détermine ses fonctionnalités et ses limites. |
revoked | Booléen | Indique si la licence a été invalidée par un administrateur (true) ou si elle reste active (false). |
trace | Booléen | Indique si le traçage est activé pour la licence. |
eventType | Chaîne | Identifie le type d’événement précis qui a déclenché ce webhook (par exemple « license.created », « license.updated »). |
timestamp | Date et heure ISO 8601 | Moment exact où l’événement s’est produit et où le webhook a été envoyé. |
Charge utile d’un événement de commande
Pour les événements liés aux commandes (comme order.created), la charge utile du webhook contient les champs suivants :
{
"id": 202,
"orderNumber": "ORD-12345",
"customerId": 501,
"createdAt": "2025-03-16T12:00:00Z",
"status": "completed",
"eventType": "order.created",
"timestamp": "2025-03-16T12:05:00Z"
}| Champ | Type | Description |
|---|---|---|
id | Entier | Identifiant unique de la commande dans la base de données. Utilisez cet identifiant dans les appels d’API qui demandent les détails de la commande. |
orderNumber | Chaîne | Numéro de référence de commande lisible, utilisé dans les communications avec les clients et dans les documents comptables. |
customerId | Entier | Identifiant unique du client qui a passé la commande. Renvoie à un enregistrement client. |
createdAt | Date et heure ISO 8601 | Date et heure de la création initiale de la commande dans le système. |
status | Chaîne | État de traitement actuel de la commande. Valeurs possibles : « pending », « processing », « completed », « cancelled », « refunded ». |
eventType | Chaîne | Identifie l’événement de commande qui a déclenché ce webhook (par exemple « order.created », « order.updated », « order.deleted »). |
timestamp | Date et heure ISO 8601 | Moment exact où l’événement s’est produit et où le webhook a été envoyé. |
Charge utile d’un événement de rapport
Pour les événements liés aux rapports (comme report.created), la charge utile du webhook contient les champs suivants :
{
"id": 303,
"name": "Monthly Report",
"date": "2025-03-15T00:00:00Z",
"eventType": "report.created",
"timestamp": "2025-03-16T12:10:00Z"
}| Champ | Type | Description |
|---|---|---|
id | Entier | Identifiant unique du rapport dans la base de données. Utilisez cet identifiant pour récupérer le rapport complet par l’API. |
name | Chaîne | Titre descriptif du rapport, tel qu’il est défini dans le système. |
date | Date et heure ISO 8601 | Date associée au contenu du rapport (en général la date de fin de la période couverte). |
eventType | Chaîne | Identifie l’événement de rapport qui a déclenché ce webhook (actuellement uniquement « report.created »). |
timestamp | Date et heure ISO 8601 | Moment exact où l’événement s’est produit et où le webhook a été envoyé. |
Remise des webhooks et nouvelles tentatives
Le Babel Licensing Service traite les webhooks dans un service d’arrière-plan qui s’exécute en continu :
- Le service recherche de nouveaux événements webhook toutes les 30 secondes
- Les webhooks sont traités par lots de 50 événements au maximum
- Le système traite à la fois les événements en attente (nouveaux) et les événements précédemment en échec pour lesquels une nouvelle tentative est planifiée
- Chaque remise de webhook comporte des en-têtes standard :
User-Agent: identifie le Babel Licensing ServiceX-Babel-Webhook-Id: identifiant unique de la remise du webhookX-Babel-Event: type de l’événement remisX-Babel-Timestamp: moment où l’événement a été envoyéX-Babel-Signature: signature HMAC-SHA256 (si un secret est configuré)
Mécanisme de nouvelle tentative
Lorsque la remise d’un webhook échoue :
- Le système planifie automatiquement une nouvelle tentative 5 minutes plus tard
- Chaque webhook peut être configuré avec un nombre maximal de nouvelles tentatives
- Les événements en échec restent dans le système jusqu’à ce qu’ils soient remis ou que le nombre maximal de nouvelles tentatives soit atteint
- L’interface des webhooks indique l’heure de la prochaine tentative planifiée pour les remises en échec
- Chaque remise en échec conserve le message d’erreur ou le code d’état HTTP, pour le dépannage
État des webhooks
Les webhooks du système peuvent avoir les états suivants :
- OK : l’événement a été remis
- Failed : la remise de l’événement a échoué et le nombre maximal de nouvelles tentatives a été dépassé
- Pending : l’événement attend d’être traité
- Scheduled : la remise de l’événement a échoué et une nouvelle tentative est planifiée
Sécuriser les webhooks
Toutes les requêtes de webhook comportent une signature dans l’en-tête X-Babel-Signature. Cette signature est générée avec HMAC-SHA256, à partir de la clé secrète de votre webhook et du corps de la requête.
Pour vérifier le webhook :
Récupérer la signature
Récupérez la signature dans l’en-tête X-Babel-Signature.
Calculer la signature attendue
Calculez une signature HMAC-SHA256 à partir de votre clé secrète et du corps brut de la requête.
Comparer les signatures
Comparez la signature calculée à celle de l’en-tête.
Ne traiter le webhook que si elles correspondent
Ne traitez le webhook que si les signatures correspondent.
Exemple de code de vérification (C#) :
private bool VerifyWebhookSignature(string payload, string signatureHeader, string secret)
{
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
var computedSignature = Convert.ToBase64String(computedHash);
return signatureHeader == computedSignature;
}Implémenter un récepteur de webhooks
Voici un exemple complet d’implémentation, dans ASP.NET Core, d’un récepteur de webhooks qui valide correctement les signatures :
// WebhookValidator.cs
using System;
using System.Security.Cryptography;
using System.Text;
namespace YourProject.Utilities
{
public static class WebhookValidator
{
/// <summary>
/// Validates the webhook payload against the provided signature using HMAC-SHA256.
/// </summary>
/// <param name="payload">The raw JSON payload.</param>
/// <param name="secret">The shared secret.</param>
/// <param name="signature">The signature from the incoming request header.</param>
/// <returns>True if the signature is valid; otherwise, false.</returns>
public static bool ValidateSignature(string payload, string secret, string signature)
{
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
var computedSignature = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
return string.Equals(computedSignature, signature, StringComparison.OrdinalIgnoreCase);
}
}
}
// WebhookController.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.IO;
using System.Threading.Tasks;
using YourProject.Utilities;
namespace YourProject.Controllers
{
[ApiController]
[Route("api/webhook")]
public class WebhookController : ControllerBase
{
private readonly ILogger<WebhookController> _logger;
// Ideally, the secret comes from configuration
private readonly string _webhookSecret = "your-webhook-secret";
public WebhookController(ILogger<WebhookController> logger)
{
_logger = logger;
}
[HttpPost]
public async Task<IActionResult> ReceiveWebhook()
{
// Read the payload from the request body
var payload = await new StreamReader(Request.Body).ReadToEndAsync();
// Retrieve the signature from the request headers
if (!Request.Headers.TryGetValue("X-Babel-Signature", out var incomingSignature))
{
_logger.LogWarning("Missing X-Babel-Signature header");
return Unauthorized("Signature header missing");
}
// Validate the signature
if (!WebhookValidator.ValidateSignature(payload, _webhookSecret, incomingSignature))
{
_logger.LogWarning("Invalid webhook signature");
return Unauthorized("Invalid signature");
}
// Process the webhook payload
_logger.LogInformation("Webhook payload validated and processed");
// TODO: Deserialize and process the payload as needed
return Ok();
}
}
}Bonnes pratiques pour la réception des webhooks
Lorsque vous implémentez un récepteur de webhooks :
- Validez toujours les signatures : utilisez le code de validation de signature fourni pour vérifier l’authenticité de chaque webhook
- Stockez le secret de votre webhook de manière sécurisée : ne le codez pas en dur comme dans l’exemple ; utilisez un système de configuration sécurisé
- Répondez rapidement : renvoyez une réponse 200 OK dès que vous avez validé la signature
- Traitez de manière asynchrone : après la validation et l’envoi de la réponse, traitez le webhook dans un thread d’arrière-plan ou une file d’attente
- Mettez en œuvre l’idempotence : utilisez l’identifiant de l’événement pour ne pas traiter deux fois un webhook remis plusieurs fois
- Journalisez tous les événements webhook : conservez une trace de tous les webhooks reçus, pour le débogage et l’audit
Traiter les événements webhook
Gérer les différents types d’événement
Votre récepteur de webhooks doit être conçu pour gérer chaque type d’événement de manière appropriée. Voici un exemple de traitement de différents événements webhook après la validation de la signature :
// Example of webhook event processing
private async Task ProcessWebhookEvent(string payload, string eventType)
{
switch (eventType)
{
case "license.created":
await ProcessNewLicense(payload);
break;
case "license.expired":
await ProcessExpiredLicense(payload);
break;
case "order.created":
await ProcessNewOrder(payload);
break;
// Handle other event types
default:
_logger.LogWarning($"Unhandled webhook event type: {eventType}");
break;
}
}
// Example deserialization and processing
private async Task ProcessNewLicense(string payload)
{
try
{
// Deserialize the payload
var licenseEvent = JsonSerializer.Deserialize<LicenseCreatedEvent>(payload);
// Process the license
_logger.LogInformation($"Processing new license: {licenseEvent.LicenseId}");
// Example: Store in your database, notify users, etc.
await _licenseService.SyncLicenseAsync(licenseEvent.Id);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing license.created webhook");
}
}Dépannage
Problèmes courants
- Le webhook ne reçoit pas d’événements : vérifiez l’état du webhook dans le tableau de bord et assurez-vous que le type d’événement fait partie de ceux auxquels vous êtes abonné
- Échecs d’authentification : vérifiez que votre code de validation de signature est correct et que vous utilisez le même secret que celui configuré dans le webhook
- Délais d’attente dépassés : assurez-vous que votre point de terminaison répond dans un délai raisonnable (le système attend une réponse avant de considérer la remise comme réussie)
- URL non valide : vérifiez que l’URL de votre webhook est accessible depuis Internet et renvoie des codes d’état HTTP 2xx
- En-têtes personnalisés non appliqués : vérifiez le format de vos en-têtes personnalisés dans la configuration du webhook
- Webhook marqué comme en échec : consultez le message d’erreur dans les détails du webhook pour connaître le code d’état HTTP ou l’exception en cause
Consulter l’historique d’un webhook
Pour chaque webhook, vous pouvez consulter l’historique complet des remises :
- Cliquez sur un webhook dans la liste principale pour développer ses détails
- La section d’historique affiche toutes les tentatives de remise, avec les horodatages, les types d’événement, l’état et les éventuels messages d’erreur
- Utilisez ces informations pour diagnostiquer les problèmes de remise ou vérifier que les remises ont réussi