Traitez chaque webhook une seule fois dans votre système métier
Les événements de retour utilisent les abonnements de la Plateforme développeur et leur secret de signature. Les rappels de confirmation d’adresse peuvent utiliser un secret propre à chaque demande. Ne confondez pas ces deux secrets. Abonnez-vous aux types d’événements exacts disponibles dans la Console développeur ; ne supposez pas que les abonnements acceptent les caractères génériques.
Vérifier avant de décoder
Alkax envoie X-Alkax-Event-Id, X-Alkax-Timestamp (secondes Unix) et X-Alkax-Signature (v1= suivi d’un HMAC-SHA256 en hexadécimal minuscule). L’entrée signée est l’horodatage en UTF-8, un point, puis les octets exacts du corps brut de la requête. Utilisez la chaîne du secret de signature comme clé HMAC. Ne la décodez pas en base64 et ne resérialisez pas le JSON au préalable. Rejetez les horodatages trop anciens selon une fenêtre de cinq minutes, ceux situés dans le futur au-delà de cette fenêtre, les signatures mal formées et les identifiants d’événement incohérents entre enveloppe et en-tête. Synchronisez les horloges. Utilisez une comparaison en temps constant.
Exposez votre récepteur via un point de terminaison HTTPS public. Alkax n’envoie rien aux adresses de boucle locale, privées, locales au lien ou résolues par DNS vers une destination privée, et ne suit pas les redirections. Gardez les secrets de signature hors du code source, des journaux et de la configuration publique.
Pièges des frameworks : Express doit capturer express.raw() avant le middleware JSON ; ASP.NET doit mettre en mémoire tampon/lire le corps intact avant la conversion en modèle ; Flask doit utiliser request.get_data() avant le décodage ; les proxys ne doivent pas réécrire les octets du corps. Transmettez les trois en-têtes Alkax. Ne vérifiez jamais une signature sur un corps remis en forme.
Acceptation durable et doublons
Vérifiez d’abord. Dans une seule transaction de base de données, insérez l’identité unique composée de l’environnement et de l’événement avec une empreinte du corps brut, puis enregistrez l’action métier ou placez le travail dans une file durable. Validez la transaction avant de renvoyer 2xx. Un arrêt après validation mais avant la réponse provoque un doublon : renvoyez 2xx sans répéter l’action uniquement si l’empreinte est identique. La même identité d’événement avec une empreinte différente constitue un défaut d’intégrité et ne doit produire aucun effet. Récupérez l’état de référence actuel avec la clé de votre environnement avant toute décision dépendant de l’ordre. L’ordre de livraison n’est pas garanti. Conservez les données de déduplication au moins pendant toute la durée de rejeu que vous prenez en charge.
N’appelez pas un service externe de remboursement dans une boucle de nouvelles tentatives sans protection. Utilisez votre propre mécanisme d’outbox transactionnelle et votre contrat d’idempotence. L’événement Alkax return.received indique une réception physique, pas une autorisation de remboursement.
Politique de livraison
Les deux expéditeurs modernes de webhooks utilisent un délai d’expiration de dix secondes et au maximum huit tentatives automatiques. Les abonnements de projet utilisent des délais de 2, 4, 8, 16, 32, 64 et 128 minutes. Les rappels par confirmation utilisent environ 1, 2, 4, 8, 16, 32 et 64 minutes, avec une variation aléatoire. Ces calendriers appartiennent à des expéditeurs différents. Les réponses d’échec 4xx sont définitives, sauf 408, 425 et 429 ; les erreurs 5xx et de transport entraînent une nouvelle tentative. Renvoyez 503 en cas d’échec temporaire du stockage et 2xx pour les doublons acceptés durablement. Ne renvoyez pas 200 avant la réussite du stockage. Des signatures systématiquement incorrectes nécessitent de corriger le secret ou le traitement du corps avant le rejeu, plutôt que de multiplier les tentatives à l’aveugle.
Dans la Console développeur, examinez l’historique des livraisons de l’abonnement, corrigez la cause et sélectionnez Replay (Rejouer). Le rejeu conserve l’identifiant d’événement et le corps, mais utilise un nouvel horodatage pour la signature. La déduplication doit donc reposer sur l’identifiant d’événement, pas sur la signature ni sur l’horodatage.
Conservez les secrets d’abonnement dans un gestionnaire de secrets. Le renouvellement d’un identifiant ne renouvelle pas les secrets de webhook. Pour remplacer le secret d’un abonnement, créez l’abonnement de remplacement, acceptez les deux secrets pendant la transition, retirez l’ancien abonnement et réconciliez les livraisons en attente.
Traitement du contenu
Une enveloppe de retour contient eventId, type, occurredAt et data. Les données contiennent les identifiants du retour et de l’expédition d’origine, le numéro de suivi, les états d’autorisation et de logistique, le motif/type et l’heure de l’événement. Considérez merchantReference comme une donnée fournie par le commerçant et potentiellement sensible. Ne journalisez pas l’enveloppe complète. Cet événement public d’intégration ne contient ni liens d’accès destinataire, ni adresses précises, ni images de preuve.
Alkax -> signed HTTPS webhook -> verify raw bytes -> durable inbox/work -> 2xx
|
+-> transient failure -> safe retry
Contrats de confirmation et récupération
L’API HTTP de confirmation, les rappels historiques par confirmation, les rappels versionnés par confirmation et les abonnements génériques de projet utilisent des schémas distincts :
| Canal | Champs et état |
|---|---|
| Réponse HTTP de confirmation authentifiée | Champs camelCase, état textuel ; instantané privé et deliveryInstructions ; champs à usage unique à null lors des lectures ordinaires |
Rappel par confirmation v1 par défaut | Champs de premier niveau eventId, type, occurredAt, request ; champs imbriqués PascalCase et état numérique |
Rappel par confirmation v2 activé explicitement | Champs de premier niveau schemaVersion, eventId, type, occurredAt, request ; uniquement identifiant, référence, état textuel et expiration de la demande en camelCase |
| Abonnement de projet | Champs de premier niveau eventId, type, occurredAt, data ; données de confirmation limitées à id, status numérique et expiresAt |
Le préfixe v1= de l’en-tête de signature désigne le mécanisme HMAC ; il ne sélectionne pas le schéma JSON. Choisissez le champ facultatif callbackSchemaVersion à la création d’une nouvelle confirmation. Les octets de l’événement en attente et le schéma sélectionné restent inchangés lors du rejeu. Le rejeu manuel par confirmation conserve le nombre total de tentatives ; il ne garantit pas huit nouvelles tentatives.
Pour récupérer après la perte d’une réponse, générez et chiffrez durablement un callbackSigningSecret facultatif avant de créer la confirmation. Il doit contenir exactement 64 caractères hexadécimaux minuscules générés à partir de 32 octets aléatoires, avec un callbackUrl configuré. HMAC utilise le texte UTF-8 du secret. Alkax ne renvoie jamais un secret fourni par l’appelant. S’il est omis, Alkax génère un webhookSigningSecret et le renvoie uniquement dans la réponse de création initiale. Aucun point de terminaison ne permet de renouveler ou de fournir à nouveau le secret.
Une création répétée à l’identique renvoie la demande d’origine avec recipientUrl et les champs de secret à usage unique à null, même après l’échéance du lien initial. Conservez exactement le corps et la clé, et utilisez une nouvelle référence opaque pour une nouvelle tentative. Vérifiez la concordance des identifiants d’événement entre en-tête et corps, rattachez l’événement à la tentative locale actuelle, conservez l’environnement et l’identifiant d’événement avec une empreinte du corps, puis réconciliez par un GET canonique authentifié. L’expiration du lien n’invalide pas les instantanés finalisés ; l’application consommatrice gère l’expiration du consentement et de l’accès aux informations privées.
Les réponses de test et d’historique des livraisons du projet exposent uniquement les métadonnées de livraison explicitement autorisées. Les corps bruts, extraits de réponse du récepteur et messages d’échec en texte libre sont exclus pour tous les rôles du projet. Les anciens événements de confirmation de projet non sûrs sont retirés avant envoi et leur rejeu manuel est refusé ; les secrets historiques conservés nécessitent toujours une procédure de correction opérationnelle ciblée. Cela ne renouvelle pas les liens d’accès ou secrets précédemment exposés.
Les notifications de confirmation Sandbox sont enregistrées dans un récepteur de test plutôt qu’envoyées aux boîtes des destinataires réels ; toutes les opérations de confirmation sont limitées au projet et à l’environnement. Déployez la version compatible du fournisseur avant d’utiliser ces ajouts. Consultez le contrat de rappel récupérable pour le corps d’exemple exact et les conditions de mise en production restantes. L’interface privée hébergée VolXpr, le parcours d’autorisation durable et les travaux complets sur la concurrence du cycle de vie restent distincts.