WEBHOOKS

Webhooks

Recevez les événements en temps réel de Superroute — commandes, changements de statut, mises à jour de suivi. Avec charges utiles signées, nouvelles tentatives automatiques et débogueur intégré.

Guide d'Intégration des Webhooks
Centre des Développeurs Accueil

Guide d'Intégration des Webhooks

Qu'est-ce qu'un webhook ?

Un webhook est une requête HTTP POST que Superroute envoie à une URL que vous configurez chaque fois qu'un événement se produit — création de commande, livraison terminée, événement de suivi enregistré. Vous construisez un point de réception, nous y livrons l'événement.

Comment fonctionne la livraison

Les événements sont mis en file d'attente et envoyés de façon asynchrone. Chaque requête porte une signature HMAC-SHA256 pour vérifier son origine. Les livraisons échouées (réponse non 2xx ou timeout) sont réessayées avec backoff exponentiel jusqu'à 5 fois.

Modèle de sécurité

Vous configurez un secret partagé sur la page de paramètres. Chaque webhook sortant est signé avec ce secret. Votre récepteur recalcule la signature et compare — si elles correspondent, la charge utile est authentique et non altérée.

Catalogue d'Événements

Huit types d'événements sortants sont disponibles. Chacun a son propre champ URL sur la page de paramètres — abonnez-vous à n'importe quel sous-ensemble.

commande.créée

Se déclenche à la création d'une commande de livraison locale (Delivery / Pickup / P2P), quel que soit le canal : formulaire web, API REST/GraphQL, synchronisation plateforme e-commerce, règles automatiques, lignes d'import, etc. Exclut les commandes label-service et les autres types non-livraison. Ignoré dans le flux batch lorsque order_create_async_postback_url est également configuré pour le même destinataire. Configurez via order_create_webhook_url.

Exemples de Charge Utile
commande.status_change

Se déclenche à chaque transition de statut — récupéré, en transit, livré, exception, annulé. Configurez via order_status_change_webhook_url.

Exemples de Charge Utile
suivi.event

Se déclenche à chaque événement du cycle de vie d'un colis (informations soumises, début de livraison, livraison réussie, non livré, etc.). Configurez via tracking_event_webhook_url. Les événements « livré » et « ramassé » transportent aussi la preuve de livraison : proof_files et proof_files_detail (file_id, type, url, full_url, URL de téléchargement signée). Les photos téléversées après l’événement arrivent via pod.files_updated. Chaque fichier porte aussi le contexte de son événement : tracking_event_id, tracking_event_status_id, tracking_event_key, service_type (1 = delivery / 2 = pickup) et service_status (1 = success / 2 = failed) ; ils valent null pour les anciens fichiers sans événement enregistré.

Exemples de Charge Utile
commande.create_async

Se déclenche une fois après le traitement d'un import par lot. La charge contient le tableau des résultats par ligne. Configurez via order_create_async_postback_url.

Exemples de Charge Utile
Fichiers POD mis à jour

Déclenché quand une photo de livraison ou une signature est ajoutée, remplacée ou supprimée (action : added / updated / removed) — un envoi par fichier, plus besoin d’interroger les pièces jointes. Activé via pod_files_webhook_url. Chaque fichier porte aussi le contexte de son événement : tracking_event_id, tracking_event_status_id, tracking_event_key, service_type (1 = delivery / 2 = pickup) et service_status (1 = success / 2 = failed) ; ils valent null pour les anciens fichiers sans événement enregistré.

Exemples de Charge Utile
Commande supprimée

Déclenché quand une commande est supprimée définitivement, afin que votre système puisse refléter la suppression. Activé via order_deleted_webhook_url.

Exemples de Charge Utile
Échec d'annulation de commande

Déclenché quand une tentative d'annulation est refusée (par exemple la commande est déjà en cours de livraison), afin que vos équipes puissent surveiller les annulations échouées sans interroger l'API. Activé via order_cancel_failed_webhook_url.

Exemples de Charge Utile
Siège du tableau des tournées modifié

Déclenché lorsqu'un siège du tableau des tournées change de titulaire ou que le tableau change d'état — le champ action indique ce qui s'est passé (claimed, standby, pooled, promoted, withdrawn, vetoed, replaced, assigned, awarded, lost, displaced, settled, board_opened, board_closed, board_cancelled). Niveau entreprise uniquement. Abonnement via route_board_webhook_url.

Exemples de Charge Utile

Événements consignes prestataires

Un canal webhook distinct pour les prestataires de livraison tiers intégrés aux consignes intelligentes. Les événements sont livrés au point de terminaison configuré pour votre compte prestataire, et chaque point de terminaison peut s'abonner à n'importe quel sous-ensemble de types d'événements.

partner_locker.delivery.doors_opened

Portes Ouvertes — Se déclenche à l'instant où les portes des casiers s'ouvrent pour une tentative de dépôt — que le livreur ait saisi le code d'accès sur l'écran de la consigne ou utilisé l'API d'ouverture à distance — y compris les réouvertures après réaffectation. Le bloc opening liste chaque casier ouvert avec son grid_id, le numéro de porte matériel compartment_number et le pickup_locker_number (numéro d'affichage séquentiel compté de haut en bas par colonne, puis de gauche à droite). Chaque compartiment porte aussi pickup_locker_code — l'étiquette « {shelf_code}-{pickup_locker_number} » vers laquelle le destinataire est dirigé ; null lorsque le compartiment n'a pas de numéro de retrait. La charge utile comporte également pickup_code — le code de retrait du destinataire, attribué dès l'ouverture des portes ; il reste le même code après la confirmation du dépôt par le livreur et ne devient utilisable pour le retrait qu'une fois le dépôt confirmé.

Exemples de Charge Utile
partner_locker.delivery.delivered

Déposé dans la consigne — Déclenché quand un dépôt est confirmé et que les colis sont dans la consigne. La charge utile inclut le code de retrait du destinataire. Chaque compartiment porte aussi pickup_locker_code — l'étiquette « {shelf_code}-{pickup_locker_number} » vers laquelle le destinataire est dirigé ; null lorsque le compartiment n'a pas de numéro de retrait. Pour les portes ouvertes via l'API d'ouverture à distance, la plateforme règle le dépôt dès que la consigne signale toutes les portes ouvertes comme refermées ; l'événement est alors émis sans appel confirm. confirmed_by indique la voie de règlement : courier_terminal, partner_api, door_close, timeout_door_closed ou console.

Exemples de Charge Utile
partner_locker.pickup.completed

Retiré — Déclenché quand le destinataire a récupéré les colis déposés.

Exemples de Charge Utile
partner_locker.delivery.failed

Échec de livraison — Déclenché quand une livraison échoue ; les codes d'échec par colis sont inclus.

Exemples de Charge Utile
partner_locker.delivery.expired

Expiré — Déclenché quand un code de livraison inutilisé ou un dépôt non retiré dépasse sa date d'expiration.

Exemples de Charge Utile
partner_locker.delivery.cancelled

Annulé — Déclenché quand une livraison est annulée avant son achèvement.

Exemples de Charge Utile
partner_locker.delivery.correction_reopened

Réouverture de correction — Déclenché quand les casiers occupés sont rouverts pendant la fenêtre de correction pour corriger un mauvais placement — depuis l'écran de la consigne ou via l'API. Le bloc correction liste les casiers rouverts. Chaque compartiment porte aussi pickup_locker_code — l'étiquette « {shelf_code}-{pickup_locker_number} » vers laquelle le destinataire est dirigé ; null lorsque le compartiment n'a pas de numéro de retrait.

Exemples de Charge Utile
partner_locker.delivery.code_rotated

partner_locker_delivery.event_type_code_rotated — Se déclenche lorsque le partenaire renouvelle le code de dépôt ou le code de retrait d'une livraison. Le bloc rotation indique quel code a été remplacé, quand, et si la notification au destinataire a été renvoyée — le nouveau code ne transite jamais par un webhook ; il n'est révélé que dans la réponse directe de l'API de renouvellement.

Exemples de Charge Utile

Signature et Vérification: Les webhooks des consignes prestataires utilisent leur propre schéma de signature : X-Webhook-Signature vaut base64(HMAC-SHA256(secret, horodatage + "\n" + id de livraison + "\n" + corps brut)), où l'horodatage et l'id de livraison proviennent des en-têtes X-Webhook-Timestamp et X-Webhook-Delivery-Id. Vérifiez aussi X-Webhook-Content-Digest (SHA-256 du corps) et rejetez les horodatages périmés. X-Webhook-Id reste stable entre les tentatives — utilisez-le pour l'idempotence.

Comment Configurer: Les points de terminaison se gèrent dans Livraison tierce → Consigne prestataire → Paramètres, un point de terminaison par prestataire, avec une liste d'événements sélectionnable. Les livraisons échouées sont retentées avec un backoff exponentiel jusqu'à 7 fois avant mise en file morte ; les événements en file morte peuvent être renvoyés manuellement depuis la page des événements.

Événements sandbox (casiers simulés): Les livraisons créées sur des casiers simulés émettent les mêmes événements webhook qu'en production, signés avec le même secret, afin de développer avec un trafic réaliste. Les événements sandbox sont marqués de trois façons : la charge utile contient "livemode": false, l'event_id commence par PLE-MOCK- et la requête porte l'en-tête X-Webhook-Test: 1. Si une URL sandbox est configurée sur le point de terminaison, les événements sandbox y sont envoyés au lieu de l'URL de production ; sinon ils reviennent vers l'URL de production, toujours marqués. L'interrupteur « Livrer les événements sandbox » arrête complètement la livraison sandbox.

Événements de livraison tierce

Webhooks de livraison de colis envoyés aux prestataires de livraison tiers (transporteurs). Ils couvrent le cycle de vie des affectations de livraison, de sorte qu'un transporteur n'a plus besoin d'interroger la plateforme à la recherche de nouvelles missions. Cette catégorie est distincte des événements de consigne intelligente ci-dessous : chaque prestataire configure par catégorie un point de terminaison, un secret de signature et un abonnement aux événements indépendants — dans son propre portail prestataire ou via l'opérateur de la plateforme.

delivery.assignment.created

Affectation créée — Se déclenche quand une commande est affectée au prestataire — par une règle automatique ou manuellement. La charge utile contient le numéro d'affectation, les identifiants de la commande et les numéros de suivi des colis.

Exemples de Charge Utile
delivery.assignment.handed_over

Colis remis — Se déclenche quand l'entrepôt a physiquement remis au prestataire tous les colis de l'affectation.

Exemples de Charge Utile
delivery.assignment.cancelled

Affectation annulée — Se déclenche quand la plateforme retire une affectation au prestataire. Le champ reason distingue cancelled (l'affectation a été annulée chez le transporteur), fallback_to_self_delivery (la plateforme a repris la commande en livraison propre) et reassigned (la commande a été transférée à un autre prestataire).

Exemples de Charge Utile
delivery.assignment.partial_delivered

Livraison partielle — Se déclenche lorsqu'une partie d'un envoi a été livrée alors que d'autres colis sont encore en cours. Le tableau packages indique le résultat de chaque colis et legs liste les commandes externes enregistrées chez le transporteur — une par colis lorsque le transporteur n'accepte pas les envois multicolis.

Exemples de Charge Utile

Signature et Vérification: Les webhooks de livraison tierce utilisent le même schéma de signature que les webhooks des consignes prestataires : X-Webhook-Signature vaut base64(HMAC-SHA256(secret, timestamp + "\n" + delivery id + "\n" + raw body)), le timestamp et le delivery id provenant des en-têtes X-Webhook-Timestamp et X-Webhook-Delivery-Id. Vérifiez aussi X-Webhook-Content-Digest (SHA-256 du corps) et rejetez les horodatages périmés. X-Webhook-Id reste stable entre les tentatives — utilisez-le pour l'idempotence.

Comment Configurer: Les prestataires configurent eux-mêmes ce point de terminaison dans le portail prestataire (Paramètres des webhooks), ou l'opérateur de la plateforme le fait dans Livraison tierce → Prestataires → Webhooks. Un point de terminaison par prestataire avec une liste d'événements sélectionnable. Le secret de signature peut être généré automatiquement ou défini avec une valeur personnalisée, et il est consultable sur la page des paramètres. Les livraisons échouées sont retentées avec un backoff exponentiel jusqu'à 7 fois avant mise en file morte ; les événements en file morte peuvent être renvoyés manuellement. Un événement de test (mock) signé peut être envoyé à tout moment depuis la page des paramètres — les requêtes de test portent l'en-tête X-Webhook-Test: 1 et contiennent "test": true dans les données du payload.

Événements du cycle de vie des commandes

Événements fins et optionnels à côté du webhook classique order.status_change (inchangé) : qui a été affecté, si le chauffeur a accepté, quand le colis a été récupéré, est en route, livré ou en échec, ainsi que les changements de service des chauffeurs et leurs positions à fréquence limitée. Rien n'est envoyé tant que vous n'avez pas configuré les URL ci-dessous.

order.assigned

Un chauffeur a été affecté à la commande (manuellement, par la planification des tournées ou par l'affectation automatique). data.source = auto_assign lorsque c'est l'orchestrateur qui l'a fait.

Exemples de Charge Utile
order.unassigned

La commande a perdu son chauffeur (transfert, retrait, refus, délai dépassé). data.previous_driver_id indique qui l'avait.

Exemples de Charge Utile
order.accepted

Le chauffeur a accepté dans l'app une commande affectée automatiquement (service des chauffeurs avec acceptation obligatoire).

Exemples de Charge Utile
order.rejected

Le chauffeur a refusé une commande affectée ; data.reason contient le motif facultatif en texte libre.

Exemples de Charge Utile
order.pickup_started

Le chauffeur a commencé le ramassage (statut Ramassage commencé / En cours de ramassage).

Exemples de Charge Utile
order.picked_up

Le colis a été récupéré (statut Déjà collecté).

Exemples de Charge Utile
order.on_the_way

Le colis est en route vers le destinataire (statut Livraison commencée / En cours de livraison).

Exemples de Charge Utile
order.completed

La livraison a réussi (statut Réussie).

Exemples de Charge Utile
order.failed

La tentative de livraison a échoué (Relivrer plus tard, À replanifier, Refusé par le destinataire).

Exemples de Charge Utile
order.cancelled

La commande a été annulée.

Exemples de Charge Utile
order.ready

Le personnel (ou un chauffeur, si autorisé) a marqué la commande comme prête pour le ramassage (Options de dispatch → prêt pour ramassage).

Exemples de Charge Utile
driver.on_duty_changed

Un chauffeur a pris ou quitté son service dans l'app (option service des chauffeurs).

Exemples de Charge Utile
driver.location_update

Une position du chauffeur provenant de l'app ou du traceur, limitée par chauffeur via driver_location_min_interval_sec (60 s par défaut). Envoyée uniquement à driver_location_webhook_url.

Exemples de Charge Utile

Comment Configurer: Paramètres → Webhooks (ou GET/PUT /api/v1/webhook-settings, GraphQL webhookSettingsUpdate) : order_lifecycle_webhook_url reçoit tous les événements order.* ainsi que driver.on_duty_changed ; order_lifecycle_events les restreint à une liste séparée par des virgules ; driver_location_webhook_url et driver_location_min_interval_sec contrôlent driver.location_update. Plusieurs URL peuvent être séparées par des virgules. Les envois apparaissent dans le journal de livraison des webhooks avec reference_type order / driver.

Signature et Vérification: Signé exactement comme tout autre webhook sortant de votre compte : en-tête Signature historique plus X-Webhook-Id / X-Webhook-Timestamp / X-Webhook-Signature-V2 avec votre webhook_sign_secret. Les nouvelles tentatives réutilisent le même event_id : dédupliquez sur cette valeur.

Événements des commandes en appareil

Événements facultatifs pour les colis traités par vos casiers intelligents, bornes et boîtes de dépôt intelligentes : un colis déposé dans une machine, retiré, sorti par le personnel ou ayant dépassé son délai de retrait, ainsi que les problèmes ouverts ou résolus à son sujet. Purement additif : aucun webhook existant ne change, et rien n'est envoyé tant que vous n'avez pas configuré device_order_webhook_url.

device_order.stored

Un colis a été déposé dans la machine et attend la personne suivante (destinataire, coursier ou opérateur, voir data.device_order.next_actor). due_at est la date limite de retrait.

Exemples de Charge Utile
device_order.collected

Le colis a été retiré par la personne qu'il attendait : le destinataire, le coursier ou le personnel qui vide une boîte de dépôt intelligente.

Exemples de Charge Utile
device_order.removed

Le personnel a sorti le colis de la machine. removal_reason en indique la raison : overdue_return, handover, relay, anomaly ou recovery.

Exemples de Charge Utile
device_order.overdue

Le colis a dépassé son due_at sans être retiré. Il est toujours dans la machine et son code fonctionne encore ; overdue_at est renseigné et next_actor devient operator.

Exemples de Charge Utile
device_order.exception_opened

Un problème a été ouvert sur ce traitement (par exemple door_left_open, deposit_unverified, item_missing, overdue). data.exception contient id, type, severity et status.

Exemples de Charge Utile
device_order.exception_resolved

Une personne a clos un problème sur ce traitement. data.exception.status vaut resolved ou dismissed et resolution_action indique ce qui a été fait.

Exemples de Charge Utile

Exemples de Charge Utile: data.device_order : id, kind, status, next_actor, device_type, device_id, device_name, grid_code, reference_number, order_id, external_order_id, due_at, overdue_at, stored_at, ended_at, removal_reason (heures au format ISO 8601, null tant qu'elles ne sont pas atteintes). Les événements de problème ajoutent data.exception : id, type, severity, status, resolution_action. Le code de retrait n'est jamais inclus. event_id vaut DOE-<id de l'événement du registre> et reste identique lors des nouvelles tentatives.

Comment Configurer: Paramètres → Webhooks (ou GET/PUT /api/v1/webhook-settings) : device_order_webhook_url reçoit chaque événement device_order.* ; device_order_events le restreint à une liste séparée par des virgules. Plusieurs URL peuvent être séparées par des virgules. Les livraisons apparaissent dans le journal de livraison des webhooks avec reference_type device_order.

Signature et Vérification: Signé exactement comme tout autre webhook sortant de votre compte : en-tête Signature historique plus X-Webhook-Id / X-Webhook-Timestamp / X-Webhook-Signature-V2 avec votre webhook_sign_secret. Les nouvelles tentatives réutilisent le même event_id : dédupliquez sur cette valeur.

Les colis qu'un transporteur partenaire livre dans vos casiers sous son propre compte ne sont pas envoyés sur ce canal ; le partenaire les reçoit via ses webhooks de casiers fournisseur.

Comment Configurer

Vous pouvez configurer les webhooks à deux niveaux : au niveau de l'entreprise (couvre tout) ou par client (remplacement pour ce sous-compte B2B spécifique).

1. Accéder aux paramètres

Connectez-vous et allez dans Paramètres → API & Webhooks. Les remplacements par client sont sur la page de détail du client.

2. Définir le secret de signature

Choisissez une chaîne d'au moins 16 caractères, idéalement 32+ octets aléatoires. Votre récepteur utilise ce secret pour vérifier les signatures.

3. Définir les URLs d'événements souhaitées

Remplissez uniquement les URLs des événements qui vous intéressent. Laissez les autres vides.

webhook_sign_secretVous configurez un secret partagé sur la page de paramètres. Chaque webhook sortant est signé avec ce secret. Votre récepteur recalcule la signature et compare — si elles correspondent, la charge utile est authentique et non altérée.
order_create_webhook_urlSe déclenche à la création d'une commande de livraison locale (Delivery / Pickup / P2P), quel que soit le canal : formulaire web, API REST/GraphQL, synchronisation plateforme e-commerce, règles automatiques, lignes d'import, etc. Exclut les commandes label-service et les autres types non-livraison. Ignoré dans le flux batch lorsque order_create_async_postback_url est également configuré pour le même destinataire. Configurez via order_create_webhook_url.
order_status_change_webhook_urlSe déclenche à chaque transition de statut — récupéré, en transit, livré, exception, annulé. Configurez via order_status_change_webhook_url.
tracking_event_webhook_urlSe déclenche à chaque événement du cycle de vie d'un colis (informations soumises, début de livraison, livraison réussie, non livré, etc.). Configurez via tracking_event_webhook_url. Les événements « livré » et « ramassé » transportent aussi la preuve de livraison : proof_files et proof_files_detail (file_id, type, url, full_url, URL de téléchargement signée). Les photos téléversées après l’événement arrivent via pod.files_updated. Chaque fichier porte aussi le contexte de son événement : tracking_event_id, tracking_event_status_id, tracking_event_key, service_type (1 = delivery / 2 = pickup) et service_status (1 = success / 2 = failed) ; ils valent null pour les anciens fichiers sans événement enregistré.
order_create_async_postback_urlSe déclenche une fois après le traitement d'un import par lot. La charge contient le tableau des résultats par ligne. Configurez via order_create_async_postback_url.
pod_files_webhook_urlDéclenché quand une photo de livraison ou une signature est ajoutée, remplacée ou supprimée (action : added / updated / removed) — un envoi par fichier, plus besoin d’interroger les pièces jointes. Activé via pod_files_webhook_url. Chaque fichier porte aussi le contexte de son événement : tracking_event_id, tracking_event_status_id, tracking_event_key, service_type (1 = delivery / 2 = pickup) et service_status (1 = success / 2 = failed) ; ils valent null pour les anciens fichiers sans événement enregistré.
order_deleted_webhook_urlDéclenché quand une commande est supprimée définitivement, afin que votre système puisse refléter la suppression. Activé via order_deleted_webhook_url.
order_cancel_failed_webhook_urlDéclenché quand une tentative d'annulation est refusée (par exemple la commande est déjà en cours de livraison), afin que vos équipes puissent surveiller les annulations échouées sans interroger l'API. Activé via order_cancel_failed_webhook_url.
route_board_webhook_urlDéclenché lorsqu'un siège du tableau des tournées change de titulaire ou que le tableau change d'état — le champ action indique ce qui s'est passé (claimed, standby, pooled, promoted, withdrawn, vetoed, replaced, assigned, awarded, lost, displaced, settled, board_opened, board_closed, board_cancelled). Niveau entreprise uniquement. Abonnement via route_board_webhook_url.
device_order_webhook_urlÉvénements facultatifs pour les colis traités par vos casiers intelligents, bornes et boîtes de dépôt intelligentes : un colis déposé dans une machine, retiré, sorti par le personnel ou ayant dépassé son délai de retrait, ainsi que les problèmes ouverts ou résolus à son sujet. Purement additif : aucun webhook existant ne change, et rien n'est envoyé tant que vous n'avez pas configuré device_order_webhook_url.
Guide des nouveautés d’intégration

Toutes les nouveautés de l’API et des webhooks — annulation idempotente, flux de réconciliation, signatures v2, nouveaux événements — avec des exemples prêts à copier. Le tout entièrement rétrocompatible.

Signature et Vérification

Chaque webhook sortant porte une signature HMAC-SHA256 encodée en hexadécimal dans l'en-tête. Votre récepteur doit recalculer la signature sur le corps brut avec le secret partagé et rejeter la requête si elle ne correspond pas.

Algorithme
HMAC-SHA256 (hex)
Nom de l'en-tête
Signature
Étapes de vérification
  1. Lisez le corps brut avant tout parsing ou middleware.
  2. Calculez hash_hmac('sha256', rawBody, sharedSecret) et encodez en hexadécimal.
  3. Comparez avec l'en-tête Signature en temps constant (hash_equals en PHP, crypto.timingSafeEqual en Node).
  4. Renvoyez 2xx seulement si les signatures correspondent. Sinon 401.
<?php $rawBody = file_get_contents('php://input'); $received = $_SERVER['HTTP_SIGNATURE'] ?? ''; $expected = hash_hmac('sha256', $rawBody, $sharedSecret); if (!hash_equals($expected, $received)) { http_response_code(401); exit('Bad signature'); } $payload = json_decode($rawBody, true); // ... handle event ... http_response_code(200); echo 'ok';
const crypto = require('crypto'); const express = require('express'); const app = express(); app.use('/webhooks/superroute', express.raw({ type: 'application/json' }), (req, res) => { const received = req.header('Signature') || ''; const expected = crypto.createHmac('sha256', sharedSecret) .update(req.body).digest('hex'); if (!crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected))) { return res.status(401).send('Bad signature'); } const payload = JSON.parse(req.body.toString()); // ... handle event ... res.status(200).send('ok'); });
import hmac, hashlib from flask import Flask, request, abort app = Flask(__name__) @app.route('/webhooks/superroute', methods=['POST']) def webhook(): received = request.headers.get('Signature', '') expected = hmac.new(shared_secret.encode(), request.data, hashlib.sha256).hexdigest() if not hmac.compare_digest(received, expected): abort(401) payload = request.get_json() # ... handle event ... return 'ok', 200
func handleWebhook(w http.ResponseWriter, r *http.Request) { body, _ := io.ReadAll(r.Body) received := r.Header.Get("Signature") mac := hmac.New(sha256.New, []byte(sharedSecret)) mac.Write(body) expected := hex.EncodeToString(mac.Sum(nil)) if !hmac.Equal([]byte(received), []byte(expected)) { w.WriteHeader(401); return } // ... handle event ... w.WriteHeader(200) w.Write([]byte("ok")) }
require 'openssl' require 'rack/utils' post '/webhooks/superroute' do raw = request.body.read received = request.env['HTTP_SIGNATURE'] || '' expected = OpenSSL::HMAC.hexdigest('sha256', shared_secret, raw) halt 401 unless Rack::Utils.secure_compare(received, expected) payload = JSON.parse(raw) # ... handle event ... status 200 'ok' end

Nouvelles Tentatives et Fiabilité

Votre endpoint devrait répondre rapidement avec 2xx. Sinon, ou en cas de timeout ou inaccessibilité, la livraison est retentée.

Tentatives max
5 (initiale + 4 retries)
Timeout par tentative
3 secondes
Recul
Exponentiel — environ 10s, 100s, 1000s, 10000s
Concevez pour l'idempotence. Comme une livraison peut être retentée, votre récepteur peut voir le même événement plusieurs fois. Utilisez l'ID commande/numéro de suivi comme clé de déduplication — stockez les IDs traités au moins 24 heures.
Réponse recommandée. Accusez réception rapidement (HTTP 200) puis traitez de façon asynchrone. Évitez le travail lent de façon synchrone dans le handler — vous atteindrez le timeout de 3 secondes.

Vérificateur de Signature

Collez une charge utile reçue, la valeur de l'en-tête Signature et votre secret — l'outil recalcule la signature dans votre navigateur (rien ne quitte cette page) et indique si elles correspondent.

Envoyer un Webhook de Test

Déclenchez un vrai webhook signé depuis notre serveur vers une URL que vous fournissez. Utile pour tester l'accessibilité du récepteur, l'analyse de la charge utile et la logique de vérification de signature.

Livraisons Récentes de Webhook

Consultez les tentatives de livraison de webhook les plus récentes sur votre compte — événements de production et tests depuis cette page. Collez votre Bearer token pour charger.

Heure Événement URL Statut HTTP Tentative Temps (ms) Test ? Actions
Aucune livraison de webhook trouvée pour l'instant.

Bonnes Pratiques