Passer au contenu principal

Vue d'ensemble des Webhooks

Comment fonctionnent les webhooks DZBuild — quels événements se déclenchent, livraison + retries, modèle de sécurité, quotas.

Écrit par Support

Les webhooks sont des notifications push temps réel de DZBuild vers votre serveur quand quelque chose se passe sur votre boutique. Utilisez-les au lieu du polling — moins de charge, latence plus basse, et les livraisons webhook ne comptent pas dans votre quota mensuel de requêtes.

ℹ️ Info — Il existe deux systèmes de webhooks DZBuild distincts

Choisissez le bon avant de construire.

Addon Webhooks marchand

Webhooks API v1 (cette section)

Configuration

/dashboard/webhooks — sans code

POST /v1/webhooks — via l'API uniquement

Qui peut l'utiliser

Plan Unlimited et au-delà

Les boutiques avec un plan Enterprise actif, via une clé API du marchand (les jetons d'application installée sont refusés)

Endpoints par boutique

1 en Unlimited, 3 en Enterprise

Aucune limite n'est appliquée

Signature

X-DZ-Signature: t=<ts>,v1=hex(hmac_sha256(secret, ts + "." + rawBody)) sur le body brut : vous pouvez la vérifier. Envoie aussi un en-tête X-DZ-Token: <secret> pour les outils no-code qui ne savent faire que de l'auth par en-tête.

Même format : X-DZ-Signature: t=<ts>,v1=hex(hmac_sha256(secret, ts + "." + rawBody)) sur le body brut, avec le secret renvoyé une seule fois par POST /v1/webhooks. Vous pouvez la vérifier. Les webhooks enregistrés avant la signature par webhook gardent une ancienne signature invérifiable : voir Signature.

Commandes couvertes

order.created depuis toutes les sources (boutique, landing page, création manuelle au dashboard, API) plus 6 événements de statut, dont order.processing

Les commandes créées ou mises à jour via l'API, plus les confirmations et annulations faites avec les boutons des notifications Telegram de nouvelle commande, commandes de la boutique et des landing pages comprises

Livré depuis

Les plages IP Cloudflare

Les adresses de sortie propres à DZBuild — demandez la liste actuelle au support

Extras

Interface de journal des livraisons, régénération du secret, validation HTTPS de la cible, désactivation automatique après 10 échecs consécutifs

Validation HTTPS de la cible

Si tout ce dont vous avez besoin, ce sont des notifications de commande fiables, l'addon est le meilleur produit. Utilisez les webhooks API v1 quand votre intégration parle déjà à l'API REST.

Pourquoi des webhooks

Comparez :

Polling — votre code appelle GET /v1/orders?since=... chaque minute. 1440 appels/jour, 1440 round-trips, votre quota brûle uniformément, et la latence « commande créée → votre code le sait » est de 60 s.

Webhooks — vous enregistrez https://yourapp/webhooks une fois. Chaque commande créée via POST /v1/orders met une livraison en file, et la file se vide en continu : la latence est donc généralement inférieure à une minute. Zéro polling, zéro gâchis de quota.

⚠️ Attention — Les webhooks API v1 ignorent les commandes passées sur la boutique et les changements faits au dashboard

order.created se déclenche uniquement pour les commandes créées via POST /v1/orders. Les commandes passées sur la boutique, sur une landing page ou créées manuellement au dashboard ne déclenchent rien ici. Les changements de statut faits au dashboard ne déclenchent rien non plus ; seuls les changements faits via l'API et les boutons de confirmation et d'annulation des notifications Telegram de nouvelle commande en déclenchent. Voir le Catalogue d'événements.

Le polling n'est meilleur que quand : - Votre endpoint n'est pas joignable depuis Internet (pollez depuis votre réseau interne). - Vous n'avez pas de serveur (pollez depuis une lambda planifiée / cron).

Comment fonctionne la livraison

Une écriture API v1 a lieu
        │
        ▼
Une livraison est mise en file pour chaque webhook abonné à cet événement
        │
        ▼
La file se vide en continu — généralement en moins d'une minute
        │
        ▼
Body signé  ─────►  POST votre URL (5 s connexion, 10 s au total)
                              │
                              ├─ 2xx : marque livré, fini
                              ├─ 5xx, 408, 429, timeout, échec DNS ou TLS : re-tenté avec backoff
                              ├─ tout autre 4xx, ou un 3xx : file morte immédiatement, pas de retry
                              └─ 5 tentatives échouées : file morte, plus de retry

Comportement des retries

  • Les réponses 5xx, 408 et 429 et les échecs réseau (timeout, DNS, TLS) sont réessayés 1 min, 5 min, 30 min puis 2 h après l'échec. Après le 5e échec, la livraison passe en file morte et n'est plus envoyée.

  • Tout autre 4xx, et tout 3xx, n'est tenté qu'une fois : la livraison passe aussitôt en file morte et n'est jamais réessayée. Les redirections ne sont pas suivies : un 301/302 compte comme un échec.

Il n'y a pas de désactivation automatique. Le failure_count du webhook s'incrémente une fois par tentative échouée et retombe à 0 au premier succès ; status reste active.

Conséquences pratiques :

  • Répondez 2xx vite. Si vous ne pouvez pas traiter une payload, répondez quand même 2xx et jetez-la ; un 5xx vous coûte quatre livraisons de plus du même body sur environ 2 h 30.

  • Ne comptez pas sur les retries pour un endpoint lent. Cinq échecs en 2 h 30 environ et la livraison est abandonnée. Persistez le body dans votre propre file et acquittez immédiatement.

  • Réconciliez par polling. Comme une livraison est abandonnée après cinq échecs, lancez un balayage périodique GET /v1/orders?since=... comme filet de sécurité. since filtre sur la date de création de la commande : le balayage retrouve les commandes dont vous avez manqué le order.created ; pour un changement de statut manqué, relisez les commandes que vous suivez encore et comparez leur status.

Ce qui compte comme un « succès »

  • HTTP 200, 201, 202, 204 (n'importe quel 2xx) — succès.

  • HTTP 4xx autre que 408 et 429 (400, 401, 403, 404, 422, etc.) : pas de retry, la livraison passe directement en file morte. Corrigez votre endpoint et re-testez via POST /v1/webhooks/{id}/test.

  • HTTP 3xx : pas de retry, file morte immédiate. Nous ne suivons pas les redirections ; pointez le webhook sur l'URL finale.

  • Timeout, échec DNS, échec TLS : re-tentés comme un 5xx. Les certificats TLS sont vérifiés strictement : un certificat auto-signé échoue à chaque tentative.

  • HTTP 5xx, 408 et 429 : re-tentés selon le calendrier ci-dessus, 5 tentatives au total.

Modèle de sécurité

Ce qu'on envoie

Content-Type:    application/json
User-Agent:      dzbuild-webhook/1
X-DZ-Timestamp:  <unix seconds>
X-DZ-Signature:  t=<unix seconds>,v1=<hex hmac-sha256>
X-DZ-Delivery-Id: <numeric delivery id>

Signature

X-DZ-Signature est calculée avec le secret que POST /v1/webhooks vous a renvoyé à l'enregistrement du webhook :

X-DZ-Signature: t=<unix seconds>,v1=<hex hmac-sha256>expected = hex( hmac_sha256( WEBHOOK_SECRET, t + "." + raw_body ) )if (!constant_time_equal(expected, v1)) reject 401
if (abs(now - t) > 300)                 reject 401   # fenêtre rejeu ±5 min

Pour vérifier une livraison :

  1. Découpez l'en-tête sur , et lisez les valeurs t et v1.

  2. Calculez le HMAC-SHA256 de t + "." + raw_body avec le secret du webhook, raw_body étant exactement les octets reçus, puis encodez-le en hex.

  3. Comparez le résultat à v1 à temps constant.

  4. Rejetez la livraison si t s'écarte de plus de 300 secondes de votre horloge.

Chaque tentative est signée au moment de l'envoi : un retry porte donc un nouveau t et un nouveau v1 sur le même body. Le code en quatre langages est sur Vérifier les signatures.

⚠️ Attention — Webhooks enregistrés avant la signature par webhook

Un webhook créé avant que DZBuild ne signe avec le secret propre à chaque webhook garde l'ancienne signature : une valeur hex nue sans partie t=, calculée avec une clé que DZBuild ne communique pas. Vous ne pouvez pas la vérifier. Supprimez ce webhook et enregistrez-le de nouveau : le nouvel enregistrement renvoie un secret qui signe chaque livraison.

Ce que vous devez faire

  1. Vérifiez la signature avant d'agir. Rejetez toute livraison dont le v1 ne correspond pas, avant de parser le JSON ou de toucher à une commande.

  2. Servez du HTTPS. POST /v1/webhooks refuse toute url qui ne commence pas par https://, et les certificats sont vérifiés strictement.

  3. Vérifiez que le timestamp est dans 5 min de l'horloge serveur — protection anti-rejeu à moindre coût.

  4. Utilisez les bytes raw du body pour le HMAC. Ne re-sérialisez pas le JSON.

  5. Soyez idempotent. La même livraison peut arriver plusieurs fois : après un 5xx, un 408, un 429 ou un timeout, elle est renvoyée avec le même body. Dédupliquez uniquement sur le delivery_id du body signé.

Ce qu'on ne fait pas

  • Pas d'auth sortant en mTLS. Si votre endpoint le requiert, mettez un reverse proxy qui strip/ajoute mTLS devant.

  • On n'envoie pas les livraisons API v1 depuis les plages IP Cloudflare : n'autoriser que celles-ci bloque donc toutes les livraisons. S'il vous faut une allow-list IP, demandez au support les adresses de sortie actuelles — elles peuvent changer. (L'addon Webhooks marchand, lui, part bien des plages Cloudflare.)

Enveloppe de payload

Chaque body webhook a la même forme externe :

{
  "event":       "order.confirmed",
  "store_id":    13,
  "occurred_at": "2026-04-30T21:18:21+00:00",
  "data":        { "order_id": 6894, "old_status": "pending", "new_status": "confirmed" },
  "delivery_id": "9f2c41ab77e05d18"
}

Champ

Notes

event

Type d'événement (liste complète dans Catalogue d'événements).

store_id

Votre store id — utile si vous avez plusieurs webhooks sur le même handler.

occurred_at

Quand l'événement a eu lieu chez nous, ISO 8601 + TZ.

data

Payload propre à l'événement. Voir Catalogue pour la forme.

delivery_id

Chaîne de 16 caractères hex, unique par livraison (un webhook × un événement). Elle est identique octet pour octet à chaque retry — c'est ce qui la rend utilisable pour la déduplication.

L'en-tête X-DZ-Delivery-Id est une valeur différente : un id numérique de livraison, par exemple 4127. Il est stable d'un retry à l'autre, mais la signature ne le couvre pas : quiconque atteint votre URL peut y mettre n'importe quelle valeur. Dédupliquez uniquement sur le delivery_id du body signé.

Quota

Les livraisons webhook ne sont aujourd'hui ni comptabilisées ni plafonnées. Une valeur webhooks_per_month est remontée par GET /v1/usage et GET /v1/quotas, mais rien ne l'incrémente et rien ne l'applique. Les tentatives de livraison ne consomment pas non plus votre quota API requests_per_month.

Ce n'est pas un permis d'être lent : un endpoint qui répond 5xx reçoit le même body jusqu'à quatre fois de plus sur environ 2 h 30 (voir Comportement des retries).

La suite

Avez-vous trouvé la réponse à votre question ?