# Webhook

Les webhooks permettent à vos systèmes de recevoir des notifications en temps réel lorsqu'un événement se produit dans The Wallet Crew. Vous enregistrez un point de terminaison HTTPS, sélectionnez des événements, et The Wallet Crew envoie un `POST` requête chaque fois que l'un de ces événements se produit.

C'est le moyen le plus simple de garder votre CRM, vos outils d'analyse ou vos systèmes opérationnels synchronisés sans interroger en continu des API.

<details>

<summary><strong>Exemples concrets</strong></summary>

* Envoyez un événement « carte installée » à votre CRM pour mesurer l'adoption par campagne.
* Déclenchez un parcours d'accueil client lorsqu'un profil client est inséré ou mis à jour.
* Enregistrez les événements du cycle de vie des cartes (`Pass:Created`, `Pass:Updated`) vers votre entrepôt de données.
* Suivez l'utilisation des QR en magasin en écoutant les événements de redirection (`Redirect:Redirected`).

</details>

{% hint style="info" %}
Si vous appliquez également des restrictions réseau, vous pouvez mettre sur liste blanche les adresses IP sortantes de The Wallet Crew. Ne vous fiez pas uniquement aux IP. Validez toujours `x-neostore-signature`.

Voir [Infrastructure](https://docs.thewalletcrew.io/fr/developper/architecture/infrastructure).
{% endhint %}

## Créer et gérer un webhook

Vous gérez les webhooks depuis le point de terminaison API `POST /api/{tenantId}/webhooks`. Un webhook définit trois choses : où envoyer les requêtes, quels événements envoyer et si le webhook est activé.

### Créer un webhook (API)

Lors de la création d'un webhook, envoyez :

* `endpoint`: l'URL HTTPS qui recevra `POST` les requêtes.
* `events`: les événements auxquels vous souhaitez vous abonner.
* `enabled`: si la livraison est active.

Vous pouvez vous abonner à plusieurs événements dans un même webhook. Vous pouvez aussi utiliser `*` pour vous abonner à tous les sous-événements d'une catégorie.

Exemple : abonnez-vous à tous les événements client et à `Pass:Created`.

```json
{
  "events": ["Customer:*", "Pass:Created"]
}
```

{% hint style="warning" %}
Considérez `signatureSecret` comme un mot de passe. Stockez-le en sécurité. Utilisez-le uniquement côté serveur.
{% endhint %}

```bash
curl -X 'POST' \
  'https://app.neostore.cloud/api/{tenantId}/webhooks' \
  -H 'X-API-KEY: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "description": "Synchroniser les événements The Wallet Crew avec notre CRM",
  "events": [
    "Customer:*",
    "Pass:Created"
  ],
  "endpoint": "https://your-endpoint-url.com/webhook",
  "enabled": true
}'
```

Si la création réussit, l'API renvoie l'objet webhook, incluant `id` et `signatureSecret`.

```json
{
  "id": "UniqueWebhookID",
  "signatureSecret": "GeneratedSignatureSecret",
  "description": "Synchroniser les événements The Wallet Crew avec notre CRM",
  "events": ["Customer:*", "Pass:Created"],
  "endpoint": "https://your-endpoint-url.com/webhook",
  "enabled": true
}
```

### Mettre à jour, lister et supprimer

Vous pouvez gérer les webhooks en utilisant `GET`, `PATCH`, et `DELETE` sur la même ressource.

Pour la spécification complète de l'API, voir le [référence API](https://app.gitbook.com/s/WLc8AHXW4tdrAXUBfrYF/develop/api-reference).

<div data-with-frame="true"><figure><img src="https://3097111101-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWLc8AHXW4tdrAXUBfrYF%2Fuploads%2Fgit-blob-fe3004196dd6482c17306a982a89f8ee2caba07d%2Fwebhook_2.png?alt=media" alt="Webhook configuration screen showing event subscriptions and endpoint URL."><figcaption><p>Configurez quels événements sont envoyés à quel point de terminaison.</p></figcaption></figure></div>

## Ce que The Wallet Crew envoie (en-têtes et charge utile)

Chaque envoi de webhook est une `POST` requête HTTP avec des en-têtes et un corps JSON. Le corps dépend du type d'événement. Chaque payload inclut les champs de métadonnées de l'événement préfixés par `__`.

### En-têtes HTTP

* `x-neostore-signature`: signature HMAC SHA-256 du corps de la requête, générée en utilisant votre `signatureSecret`.
* `x-neostore-eventname`: nom de l'événement qui a déclenché le webhook (exemple : `Customer:Upserted`).
* `x-neostore-tenantid`: identifiant du tenant dans The Wallet Crew.

### Exemple de payload

```json
{
  "passId": "ExamplePassID",
  "passType": "user",
  "identifiers": {
    "shopifyId": "ExampleShopifyID"
  },
  "metadata": null,
  "__id": "UniqueEventID",
  "__creationDate": "2025-02-17T12:27:31.6316643Z",
  "__eventName": "Pass:Created"
}
```

### Comment traiter les événements de manière fiable

Utilisation `__id` comme clé d'idempotence. Si votre point de terminaison reçoit deux fois la même charge utile, vous pouvez ignorer en toute sécurité le doublon.

Gardez votre handler rapide. Un schéma courant consiste à valider la signature, mettre l'événement en file interne, puis retourner `2xx`.

## Vérifier l'authenticité du webhook (signature)

Validez chaque requête webhook en utilisant `x-neostore-signature`. Cela garantit que le corps de la requête a été envoyé par The Wallet Crew et n'a pas été modifié en transit.

Pour la valider, calculez un HMAC SHA-256 du corps brut de la requête en utilisant votre `signatureSecret`, puis comparez-le à la valeur de l'en-tête.

{% hint style="warning" %}
La validation de la signature doit utiliser les octets bruts exacts du corps que vous avez reçus. Ne re-sérialisez pas le JSON avant le hachage.
{% endhint %}

## Événements courants

La liste des événements évolue. Utilisez la référence API comme source de vérité pour les noms d'événements et la forme des payloads : [référence API](https://app.gitbook.com/s/WLc8AHXW4tdrAXUBfrYF/develop/api-reference).

Ci-dessous figurent les événements les plus courants avec lesquels les équipes s'intègrent.

<details>

<summary><strong>Événements client</strong></summary>

`Customer:Upserted` est envoyé lorsqu'un client est créé ou mis à jour.

```json
{
  "__id": "string",
  "__creationDate": "YYYY-MM-DDTHH:mm:ssZ",
  "__eventName": "Customer:Upserted",
  "flowName": "string",
  "identifiers": {},
  "attributes": {}
}
```

</details>

<details>

<summary><strong>Événements du cycle de vie des cartes</strong></summary>

Événements typiques du cycle de vie des cartes :

* `Pass:Created`
* `Pass:Installed`
* `Pass:Uninstalled`
* `Pass:Updated`
* `Pass:UpdateSent`

Exemple : `Pass:Installed` inclut des champs d'appareil.

```json
{
  "__id": "string",
  "__creationDate": "YYYY-MM-DDTHH:mm:ssZ",
  "__eventName": "Pass:Installed",
  "passId": "string",
  "passType": "string",
  "identifiers": {},
  "metadata": {},
  "device": "string",
  "deviceIdentifier": "string"
}
```

</details>

<details>

<summary><strong>Événements de redirection</strong></summary>

`Redirect:Redirected` est envoyé lorsqu'un utilisateur ouvre une URL minifiée (redirection).

```json
{
  "__id": "string",
  "__creationDate": "YYYY-MM-DDTHH:mm:ssZ",
  "__eventName": "Redirect:Redirected",
  "redirectId": "string",
  "newUri": "string"
}
```

</details>

## FAQ

<details>

<summary><strong>Puis-je m'abonner à tous les événements ?</strong></summary>

Oui. Utilisez le `*` joker dans le `events` tableau, par exemple `Customer:*`, pour vous abonner à tous les sous-événements client.

Utilisez cela avec précaution. Vous pouvez recevoir plus d'événements que nécessaire.

</details>

<details>

<summary><strong>Mon point de terminaison doit-il être public ?</strong></summary>

Oui. Le point de terminaison doit être joignable par The Wallet Crew via HTTPS.

Si vous restreignez le trafic entrant, mettez sur liste blanche les IP sortantes de The Wallet Crew et validez toujours la signature.

</details>

<details>

<summary><strong>Où trouver le schéma exact de la payload pour un événement ?</strong></summary>

Utilisez la référence API. C'est la source de vérité pour les noms d'événements et la forme des payloads.

Commencez ici : [référence API](https://app.gitbook.com/s/WLc8AHXW4tdrAXUBfrYF/develop/api-reference).

</details>
