---
title: "Comprendre un envoi de webhook"
description: "Le contrat technique d'un envoi de webhook Ciklik : requête, contenu, champ changed, formats, délais, tentatives et cas PrestaShop."
url: https://www.ciklik.academy/fr/webhooks/comprendre-un-envoi-de-webhook/
lang: fr
lastUpdated: 2026-10-23
---

# Comprendre un envoi de webhook

> Box et PrestaShop
>
> Cette page vaut pour les boutiques box comme pour les boutiques PrestaShop.

> Pour les développeurs
>
> Le contrat technique complet d’un envoi Ciklik : la requête, son contenu, comment identifier l’événement, quand elle est rejouée. De quoi écrire votre URL de réception sans lire une autre page.

## Le contrat en bref

| Point                         | Valeur                                                                                                                                                                                                                       |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Méthode                       | `POST`                                                                                                                                                                                                                       |
| En-têtes envoyés              | `Host`, `User-Agent: GuzzleHttp/7`, `Content-Type: application/json`, `Content-Length`. Rien d’autre : ni `Accept`, ni signature, ni identifiant d’événement, ni identifiant de site                                         |
| Corps                         | JSON compact, champs de l’objet à la racine, plus une clé `changed`. Pas d’enveloppe, pas de métadonnée                                                                                                                      |
| Identification de l’événement | uniquement par l’URL appelée. Déclarez une URL distincte par clé                                                                                                                                                             |
| Délais                        | 10 secondes pour établir la connexion, 30 secondes pour votre réponse                                                                                                                                                        |
| Tentatives                    | 5 tentatives au total, et seulement si la connexion échoue (DNS, refus, délai dépassé, certificat invalide, redirections en boucle) : 30 secondes d’attente avant les 2e, 3e et 4e tentatives, puis la 5e enchaînée aussitôt |
| Codes de réponse              | tous acceptés sans distinction. Un 500 de votre côté n’est jamais rejoué                                                                                                                                                     |
| Doublon garanti               | si vous répondez en plus de 30 secondes, l’envoi est considéré comme perdu et rejoué jusqu’à quatre fois, alors qu’il vous est déjà parvenu                                                                                  |
| Redirection                   | interdite. Sur 301, 302 ou 303, la requête est rejouée en GET, le contenu est perdu, et Ciklik enregistre un 200 trompeur                                                                                                    |
| Certificat TLS                | valide et émis par une autorité reconnue. Un certificat auto-signé fait échouer l’envoi sans laisser de trace                                                                                                                |
| Ordre                         | non garanti. Un `updated_*` peut vous parvenir avant le `created_*` du même objet                                                                                                                                            |
| Fraîcheur                     | le contenu est relu au moment de l’envoi, il peut être plus récent que l’événement. Seul `changed` décrit l’instant de l’événement                                                                                           |
| Contrat machine               | [`/openapi/ciklik-webhooks.yaml`](https://www.ciklik.academy/openapi/ciklik-webhooks.yaml)                                                                                                                                   |

## Les 18 clés d’événement

| Clé                           | Objet                 | Délai | Détail                                                                                                                   |
| ----------------------------- | --------------------- | ----- | ------------------------------------------------------------------------------------------------------------------------ |
| `created_subscription`        | Abonnement            | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-abonnements/#created_subscription)                            |
| `updated_subscription`        | Abonnement            | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-abonnements/#updated_subscription)                            |
| `deleted_subscription`        | Abonnement            | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-abonnements/#deleted_subscription)                            |
| `updated_change_choices`      | Abonnement            | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-abonnements/#updated_change_choices)                          |
| `created_shippingbox`         | Expédition            | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-expeditions/#created_shippingbox)                             |
| `updated_shippingbox`         | Expédition            | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-expeditions/#updated_shippingbox)                             |
| `deleted_shippingbox`         | Expédition            | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-expeditions/#deleted_shippingbox)                             |
| `created_checkoutorder`       | Commande              | 10 s  | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-commandes-transactions-factures/#created_checkoutorder)       |
| `updated_checkoutorder`       | Commande              | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-commandes-transactions-factures/#updated_checkoutorder)       |
| `created_checkouttransaction` | Transaction           | 10 s  | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-commandes-transactions-factures/#created_checkouttransaction) |
| `updated_checkouttransaction` | Transaction           | 10 s  | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-commandes-transactions-factures/#updated_checkouttransaction) |
| `created_checkoutinvoice`     | Facture               | 15 s  | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-commandes-transactions-factures/#created_checkoutinvoice)     |
| `created_user`                | Client                | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-clients-adresses-optins/#created_user)                        |
| `updated_user`                | Client                | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-clients-adresses-optins/#updated_user)                        |
| `created_address`             | Adresse               | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-clients-adresses-optins/#created_address)                     |
| `updated_address`             | Adresse               | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-clients-adresses-optins/#updated_address)                     |
| `created_optin`               | Inscription marketing | 10 s  | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-clients-adresses-optins/#created_optin)                       |
| `updated_optin`               | Inscription marketing | 0 s   | [Détail](https://www.ciklik.academy/fr/webhooks/evenements-clients-adresses-optins/#updated_optin)                       |

`updated_change_choices` n’appartient pas aux 17 clés de l’API : ajoutez-la dans le champ **Webhooks** de l’onglet **Avancé** de votre site, voir [Configurer les webhooks par l’API](https://www.ciklik.academy/fr/webhooks/configurer-les-webhooks-par-lapi/).

## Ce que Ciklik n’envoie pas

- **Pas de signature ni de secret partagé.** L’URL de réception est le seul secret du dispositif.
- **Pas de nom d’événement dans le contenu.** Rien ne dit qu’il s’agit d’un `created_subscription` plutôt que d’un `updated_user`.
- **Pas d’identifiant d’envoi ni d’horodatage d’événement**, donc aucune clé d’idempotence fournie.
- **Aucun accusé de réception attendu.** Le code de réponse renvoyé n’est pas analysé.

> L’événement n’est pas dans le corps
>
> Votre seul moyen d’identifier l’événement est l’URL déclarée. Utilisez une URL distincte par clé, par exemple `/webhooks/ciklik/created-subscription`, plutôt qu’une URL unique recevant tout.

## Le contenu de l’envoi

Le corps est constitué des champs de l’objet concerné, à la racine, plus une clé `changed`. L’objet dépend de la clé d’événement : il est décrit champ par champ sur la page de référence correspondante (tableau ci-dessus). Voici le plus simple du catalogue, un `created_optin`, quatre champs et `changed` :

```json
{
    "email": "claire.martin@example.com",
    "tenant_id": 1,
    "valid": true,
    "list_id": "9f2c4e7a1b",
    "changed": []
}
```

## Le champ changed

`changed` prend trois formes selon le type d’événement.

**Création :**

Un tableau JSON vide, pas un objet vide :

```json
{
    "changed": []
}
```

**Modification :**

Un objet `{colonne: nouvelle valeur}`, fragment réel de `updated_subscription.json` :

```json
{
    "changed": {
        "next_billing": "2026-11-10 08:15:42",
        "end_date": "2026-11-09 21:59:59",
        "updated_at": "2026-09-10T08:15:42.000000Z"
    }
}
```

**Suppression :**

```json
{
    "changed": {
        "deleted": true
    }
}
```

Cinq règles à connaître avant d’exploiter `changed` :

- Ce sont des **valeurs brutes de la base**, pas les valeurs telles que l’API les renvoie ailleurs : dates au format `Y-m-d H:i:s` en UTC sans fuseau, colonnes JSON sous forme de chaîne encodée, décimaux en chaîne.
- `updated_at` figure dans `changed` sur presque toutes les modifications ; il n’est absent que si deux écritures tombent dans la même seconde.
- Les noms de colonnes internes peuvent différer des noms de champs exposés ailleurs dans le contenu.
- Un envoi peut contenir des champs que vous n’avez pas modifiés vous-même, parce qu’un traitement interne a touché le même enregistrement au même moment.
- Ne faites jamais dépendre une décision métier de la seule présence d’une clé dans `changed` : vérifiez aussi sa valeur.

## Formats de données

| Type                            | Format                                                                                                                                                                                                 | Exemple                       |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- |
| Dates                           | ISO 8601 UTC avec microsecondes et suffixe `Z` ; `T00:00:00.000000Z` pour une date sans heure                                                                                                          | `2026-09-10T08:15:42.000000Z` |
| Montants de commande            | chaîne, **virgule** décimale (`total_tax_paid`, `total_discount_inc`, `total_paid`, `total_shipping_paid`)                                                                                             | `"31,81"`                     |
| Autres montants                 | chaîne, **point** décimal, virgule comme séparateur de milliers à partir de 1 000 (`revenue`, `customerRevenue`, `shipping`)                                                                           | `"31.81"`, `"1,250.00"`       |
| Prix de ligne                   | nombre flottant (`items[].price`)                                                                                                                                                                      | `29.9`                        |
| Compteurs de l’objet expédition | chaîne, alors que la valeur est numérique (`subscriptions_count`, `shipped_count`, `orderable_id` à la racine de l’expédition ; le `shipped_count` d’une formule ou d’un transporteur reste un entier) | `"3"`                         |

> Attention à l’interprétation
>
> Plusieurs formats de montant coexistent dans une même commande. Normalisez chaque valeur côté récepteur, et n’additionnez jamais deux champs sans les convertir au même format.

## Objets à structure libre

Quatre endroits du contenu ne sont pas un contrat de champs et ne doivent pas être exploités au-delà de ce qui suit :

- **`items[].orderable`** : reflet interne du produit ou de la formule, non contractuel. N’exploitez que `id`, `name`, `price` et `ref`.
- **`transporter.relayOptions`** : contenu variable selon le transporteur, non contractuel, à ignorer.
- **`invoice.customer`** : instantané des coordonnées client à l’émission de la facture, structure libre.
- **`invoice.company`** : instantané des coordonnées de votre société à l’émission de la facture, structure libre.

## Délais, ordre et doublons

Le délai dépend de la clé : 0, 10 ou 15 secondes (tableau des 18 clés). Ce n’est pas une garantie de fraîcheur, c’est l’inverse : le contenu est relu au moment où l’envoi part, pas au moment de l’événement. Entre les deux, l’objet a pu être modifié à nouveau. Seul `changed` décrit fidèlement l’instant de l’événement ; le reste du corps reflète l’état le plus récent connu au moment de l’envoi.

Aucun ordre n’est garanti : délais différents selon la clé et plusieurs envois pouvant être traités en parallèle, si bien qu’un `updated_*` peut arriver avant le `created_*` du même objet. Les doublons sont fréquents et normaux : écritures successives sur un même objet, cascades entre abonnement, expéditions et commandes, ou réponse trop lente qui déclenche un nouvel envoi alors que le premier est bien arrivé. Traitez ces cas comme la norme, voir [Bonnes pratiques et dépannage](https://www.ciklik.academy/fr/webhooks/bonnes-pratiques-et-depannage/) pour la parade.

## Cycle de vie d’un envoi

Étape par étape :

```
événement dans votre boutique (création, modification ou suppression)
  -> résolution de l'URL déclarée (mise en cache 60 s)
  -> mise en file, délai de 0, 10 ou 15 s selon la clé
  -> POST vers votre URL de réception
       connexion : 10 s max, lecture de votre réponse : 30 s max
  -> échec de connexion (DNS, refus, délai, certificat) ?
       oui -> nouvelle tentative, jusqu'à 5 au total : 30 s avant les 2e, 3e et 4e, puis la 5e enchaînée aussitôt
       non -> code de réponse journalisé tel quel, aucune nouvelle tentative
  -> ligne journalisée dans la trace conservée 20 jours (sauf échec de connexion)
```

## Si votre boutique est PrestaShop

- Le mécanisme et le contenu des envois sont exactement les mêmes que pour une boutique Ciklik classique.
- Les champs `external_fingerprint` (abonnements) et `prestashop_order_id` (commandes) sont renseignés ; sur une boutique Ciklik classique, ils valent `null`.
- Le passage d’une commande en demande de rétractation n’est **jamais** notifié, quelle que soit la boutique : ce statut transitoire est inconnu de PrestaShop.
- Le module PrestaShop dispose de son propre canal de synchronisation, distinct de ces webhooks marchands. Ne les confondez pas.
- Un jeton d’API est créé automatiquement pour les sites PrestaShop, voir [Configurer les webhooks par l’API](https://www.ciklik.academy/fr/webhooks/configurer-les-webhooks-par-lapi/).

Voir aussi la rubrique [PrestaShop](https://www.ciklik.academy/fr/prestashop/).

## Contrat lisible par une machine

Le fichier [`/openapi/ciklik-webhooks.yaml`](https://www.ciklik.academy/openapi/ciklik-webhooks.yaml) décrit les 18 clés, les trois opérations de configuration et un exemple réel par clé. Chargez-le dans un client d’API, générez-en des types, ou donnez-le à un assistant de code pour qu’il écrive votre endpoint de réception.

## Voir aussi

[Activer et tester un webhook](https://www.ciklik.academy/fr/webhooks/activer-et-tester-un-webhook/)

[Configurer les webhooks par l'API](https://www.ciklik.academy/fr/webhooks/configurer-les-webhooks-par-lapi/)

[Bonnes pratiques et dépannage](https://www.ciklik.academy/fr/webhooks/bonnes-pratiques-et-depannage/)

[Webhooks](https://www.ciklik.academy/fr/webhooks/)
