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 |
|
|
Qui peut l'utiliser | Plan Unlimited et au-delà | Toute boutique avec une clé API inscrite au pilote |
Endpoints par boutique | 1 en Unlimited, 3 en Enterprise | Aucune limite n'est appliquée |
Signature |
| Signée avec une clé qui ne vous est pas remise — les marchands ne peuvent pas la vérifier aujourd'hui. Voir Signature. |
Commandes couvertes |
| Uniquement les commandes créées ou mises à jour via l'API |
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 | — |
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 ne voient que le trafic API
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. Idem pour les changements de statut — 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 → remis en file, re-tenté chaque minute
├─ 4xx ou 3xx → une tentative, pas de retry
└─ pas de réponse (timeout / DNS / TLS) → une tentative, pas de retry
Comportement des retries
⚠️ Attention — Les retries en v1 ne se comportent pas comme un backoff normal
Lisez ceci avant de concevoir quoi que ce soit autour des retries.
HTTP 5xx — la livraison est re-POSTée une fois par minute, indéfiniment, jusqu'à ce que votre endpoint réponde 2xx ou que vous supprimiez le webhook. L'intervalle n'augmente jamais et la livraison n'est jamais abandonnée : ne concevez rien autour d'une échelle de backoff — il n'y en a pas.
Timeout, échec DNS, échec TLS — tentés exactement une fois, puis abandonnés. Pas de retry, et la livraison n'est plus jamais reprise.
HTTP 4xx et 3xx — une tentative, jamais de retry. Les redirections ne sont pas suivies : un
301/302compte 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 — répondre 5xx vous abonne à un POST toutes les 60 secondes, pour toujours.
Ne comptez pas sur un retry pour couvrir un endpoint lent. Un timeout est une livraison définitivement perdue. Persistez le body dans votre propre file et acquittez immédiatement.
Réconciliez par polling. Comme les échecs sont abandonnés en silence, lancez un balayage périodique
GET /v1/orders?since=...comme filet de sécurité.
Ce qui compte comme un « succès »
HTTP 200, 201, 202, 204 (n'importe quel 2xx) — succès.
HTTP 4xx (400, 401, 403, 404, 422 …) — pas de retry. Corrigez votre endpoint et re-testez via
POST /v1/webhooks/{id}/test.HTTP 3xx — pas de retry. Nous ne suivons pas les redirections ; pointez le webhook sur l'URL finale.
Timeout, échec DNS, échec TLS — pas de retry non plus. Les certificats TLS sont vérifiés strictement : un certificat auto-signé échoue ici.
HTTP 5xx — re-tenté, mais voir l'avertissement sur la boucle ci-dessus.
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: <hex hmac-sha256> X-DZ-Delivery-Id: <numeric delivery id>
Signature
⚠️ Attention — Les signatures API v1 ne sont pas encore vérifiables par les marchands
X-DZ-Signature n'est pas dérivée du secret propre au webhook renvoyé par POST /v1/webhooks, et ce secret ne sert jamais à signer — tout code de vérification écrit contre lui rejette donc 100 % des livraisons authentiques.
Traitez X-DZ-Signature comme une valeur opaque en attendant la signature par webhook. S'il vous faut une signature réellement vérifiable, utilisez l'addon Webhooks marchand sur /dashboard/webhooks, qui signe chaque endpoint avec le secret propre à cet endpoint.
Ce que vous devez faire
Relisez avant d'agir. Puisque la signature n'est pas vérifiable, traitez la payload comme une notification et non comme une donnée authentifiée — récupérez l'enregistrement avec
GET /v1/orders/{id}en utilisant votre clé API avant d'expédier, de facturer ou d'exécuter quoi que ce soit.Rendez l'URL indevinable. Un long segment de chemin aléatoire, ou un token partagé en query string, est votre authentification pratique aujourd'hui.
Vérifiez que le timestamp est dans 5 min de l'horloge serveur — protection anti-rejeu à moindre coût.
Utilisez les bytes raw du body si vous hachez quoi que ce soit — ne re-sérialisez pas le JSON.
Soyez idempotent — le même événement logique PEUT être livré plusieurs fois (remises en file après un 5xx). Dédupliquez via
delivery_idou les ids de l'événement.
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 |
| Type d'événement (liste complète dans Catalogue d'événements). |
| Votre store id — utile si vous avez plusieurs webhooks sur le même handler. |
| Quand l'événement a eu lieu chez nous, ISO 8601 + TZ. |
| Payload propre à l'événement. Voir Catalogue pour la forme. |
| 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 lui aussi stable d'un retry à l'autre, mais il n'est pas égal au delivery_id du body. Dédupliquez sur l'un ou l'autre de façon cohérente — ne mélangez pas.
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 est re-POSTé toutes les 60 secondes indéfiniment (voir Comportement des retries).
La suite
Enregistrement —
POST /v1/webhooksavec body, réponse, exemples.Catalogue d'événements — chaque event avec sample data.
Vérifier les signatures — code en 4 langages.