> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lygosapp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Recevez des notifications en temps réel sur les transactions

Les webhooks permettent de recevoir des notifications en temps réel sur les transactions initiées par vos clients, sans avoir à interroger régulièrement l'API. Lygos envoie automatiquement une requête HTTP POST à votre URL configurée à chaque événement sélectionné.

## Configuration des Webhooks

### Configuration dans le Dashboard

Vous pouvez configurer vos webhooks directement depuis votre dashboard Lygos dans la section **Configurations**.

### URL du Webhook

L'URL du webhook doit être :

* **Sécurisée** : Utilisez HTTPS avec un certificat SSL valide
* **Accessible publiquement** : L'URL doit être accessible depuis Internet
* **Valide** : Format d'URL correct (ex: `https://my-webhook-url.com/lygos`)

<Warning>
  Les webhooks avec des URLs non sécurisées (HTTP) ou avec des certificats SSL
  invalides seront rejetés pour des raisons de sécurité.
</Warning>

### Description du Webhook

Vous pouvez ajouter une description optionnelle pour vous souvenir de l'usage de chaque webhook (ex: "Webhook pour tag et lien de paiement").

## Sécurité et Authentification

### Authentification HMAC-SHA256

Lygos utilise l'algorithme HMAC avec SHA256 pour signer tous les webhooks envoyés. Cette signature permet de vérifier que les requêtes proviennent bien de Lygos et n'ont pas été modifiées en transit.

### Clé Secrète

Lors de la création d'un webhook, vous recevrez par email une **clé secrète** unique que vous devrez conserver précieusement. Cette clé est utilisée pour vérifier l'authenticité des webhooks.

<Warning>
  Gardez votre clé secrète confidentielle. Ne la partagez jamais et ne la
  commitez pas dans votre dépôt de code.
</Warning>

Vous pouvez régénérer votre clé secrète à tout moment depuis le dashboard. La régénération invalide immédiatement l'ancienne clé.

### Headers des Webhooks

Chaque webhook envoyé par Lygos contient les headers suivants :

* **`X-Signature`** : Signature HMAC-SHA256 calculée à partir du body et du timestamp
* **`X-Timestamp`** : Timestamp Unix (en millisecondes) de la requête
* **`Content-Type`** : `application/json`

Exemple de headers reçus :

```http theme={null}
X-Signature: a1b2c3d4e5f6789...
X-Timestamp: 1234567890244
Content-Type: application/json
```

### Vérification de la Signature

Pour vérifier l'authenticité d'un webhook :

1. Récupérez les headers `X-Signature` et `X-Timestamp`
2. Concaténez le body de la requête (en string) avec le timestamp
3. Calculez le HMAC-SHA256 de cette chaîne en utilisant votre clé secrète
4. Comparez le résultat avec la valeur de `X-Signature`
5. Si les valeurs correspondent, le webhook est authentique

### Exemples de Code

#### Node.js / JavaScript

```javascript theme={null}
const crypto = require("crypto");

function verifyWebhookSignature(body, signature, timestamp, secretKey) {
  // Concaténer le body (string) avec le timestamp
  const payload = JSON.stringify(body) + timestamp;

  // Calculer le HMAC-SHA256
  const expectedSignature = crypto
    .createHmac("sha256", secretKey)
    .update(payload)
    .digest("hex");

  // Comparer les signatures (comparaison sécurisée)
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Utilisation
const body = req.body;
const signature = req.headers["x-signature"];
const timestamp = req.headers["x-timestamp"];
const secretKey = process.env.WEBHOOK_SECRET_KEY;

if (verifyWebhookSignature(body, signature, timestamp, secretKey)) {
  // Webhook authentique, traiter la requête
  console.log("Webhook authentifié");
} else {
  // Signature invalide, rejeter la requête
  res.status(401).send("Signature invalide");
}
```

#### Python

```python theme={null}
import hmac
import hashlib
import json

def verify_webhook_signature(body, signature, timestamp, secret_key):
    # Concaténer le body (string) avec le timestamp
    payload = json.dumps(body, separators=(',', ':')) + str(timestamp)

    # Calculer le HMAC-SHA256
    expected_signature = hmac.new(
        secret_key.encode('utf-8'),
        payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

    # Comparer les signatures (comparaison sécurisée)
    return hmac.compare_digest(signature, expected_signature)

# Utilisation
body = request.json
signature = request.headers.get('X-Signature')
timestamp = request.headers.get('X-Timestamp')
secret_key = os.environ.get('WEBHOOK_SECRET_KEY')

if verify_webhook_signature(body, signature, timestamp, secret_key):
    # Webhook authentique, traiter la requête
    print('Webhook authentifié')
else:
    # Signature invalide, rejeter la requête
    return 'Signature invalide', 401
```

## Types d'Événements Disponibles

Vous pouvez sélectionner les types d'événements pour lesquels vous souhaitez recevoir des notifications :

### Marketplace

* **`marketplace_deposit_completed`** - Dépôt marketplace réussi
* **`marketplace_deposit_failed`** - Dépôt marketplace échoué
* **`marketplace_deposit_submitted`** - Dépôt marketplace soumis

### Lien de Paiement

* **`payment_link_deposit_completed`** - Dépôt de lien de paiement réussi
* **`payment_link_deposit_failed`** - Dépôt de lien de paiement échoué
* **`payment_link_deposit_submitted`** - Dépôt de lien de paiement soumis

### Passerelle de Paiement

* **`gateway_deposit_completed`** - Dépôt passerelle réussi
* **`gateway_deposit_failed`** - Dépôt passerelle échoué
* **`gateway_deposit_submitted`** - Dépôt passerelle soumis

## Structure du Payload

Chaque webhook reçu contient les informations suivantes dans le body de la requête :

```json theme={null}
{
  "operationId": "uuid",
  "status": "string",
  "amount": "number",
  "buyer": {
    "name": "string",
    "email": "string",
    "phoneNumber": "string",
    "country": "string",
    "operator": "string"
  }
}
```

### Champs du Payload

* **`operationId`** (UUID) : Identifiant unique de l'opération (format UUID)
* **`status`** (string) : Statut de la transaction (voir [Statuts possibles](#statuts-possibles))
* **`amount`** (number) : Montant de la transaction
* **`buyer`** (object, optionnel) : Informations sur l'acheteur
  * **`name`** (string) : Nom de l'acheteur
  * **`email`** (string) : Email de l'acheteur
  * **`phoneNumber`** (string) : Numéro de téléphone de l'acheteur
  * **`country`** (string) : Pays de l'acheteur (ex: "CMR")
  * **`operator`** (string) : Opérateur Mobile Money utilisé (ex: "MTN\_MOMO\_CMR")

<Info>
  Le champ `buyer` peut être absent pour certaines transactions. Assurez-vous de
  gérer ce cas dans votre code.
</Info>

## Statuts Possibles

Les statuts suivants peuvent être renvoyés dans le webhook :

* **`INITIATED`** - Transaction initiée, en attente de traitement
* **`DEPOSIT_PENDING`** - Dépôt en cours de traitement
* **`DEPOSIT_COMPLETED`** - Dépôt complété avec succès
* **`DEPOSIT_FAILED`** - Dépôt échoué
* **`DEPOSIT_REJECTED`** - Dépôt rejeté
* **`PAYOUT_PAID`** - Paiement sortant effectué
* **`MANUAL_PAYOUT`** - Paiement sortant manuel

## Exemples de Payloads

### Exemple 1 : Transaction réussie avec buyer

```json theme={null}
{
  "operationId": "550e8400-e29b-41d4-a716-446655440000",
  "status": "DEPOSIT_COMPLETED",
  "amount": 10000,
  "buyer": {
    "name": "Jean Dupont",
    "email": "jean.dupont@example.com",
    "phoneNumber": "237657843901",
    "country": "CMR",
    "operator": "MTN_MOMO_CMR"
  }
}
```

### Exemple 2 : Transaction en attente sans buyer

```json theme={null}
{
  "operationId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "status": "DEPOSIT_PENDING",
  "amount": 5000
}
```

### Exemple 3 : Paiement sortant

```json theme={null}
{
  "operationId": "6ba7b812-9dad-11d1-80b4-00c04fd430c8",
  "status": "PAYOUT_PAID",
  "amount": 15000
}
```

## Bonnes Pratiques

1. **Validation** : Validez toujours les données reçues dans le webhook
2. **Idempotence** : Utilisez `operationId` pour éviter de traiter deux fois le même événement
3. **Sécurité** : Vérifiez toujours la signature des webhooks en utilisant votre clé secrète (voir [Sécurité et Authentification](#sécurité-et-authentification))
4. **Variables d'environnement** : Stockez votre clé secrète dans des variables d'environnement, ne la commitez jamais dans votre code
5. **Vérification du timestamp** : Vérifiez que le timestamp n'est pas trop ancien pour éviter les attaques de replay (recommandé)
6. **Gestion d'erreurs** : Répondez avec un code HTTP 200 même en cas d'erreur de traitement pour éviter les tentatives de retry
7. **Logging** : Enregistrez tous les webhooks reçus pour le débogage et l'audit
