Aller au contenu principal

Webhooks

AWDPay envoie des notifications HTTP POST en temps réel à votre callbackUrl chaque fois qu'un statut de dépôt change.

Types d'Événements

ÉvénementDéclencheur
deposit.pendingTransaction initiée
deposit.completedPaiement réussi
deposit.failedPaiement échoué
deposit.expiredTransaction expirée

Charge Utile Webhook

{
"event": "deposit.completed",
"reference": "DEP_TEST_1763646304918_1D05265E",
"status": "completed",
"amount": 10000.0,
"currency": "XOF",
"fees": 104.0,
"gatewayName": "wave-senegal",
"customerEmail": "customer@example.com",
"customerPhone": "+221701234567",
"customerName": "Awa Diop",
"createdAt": "2025-11-20T14:45:04",
"completedAt": "2025-11-20T14:47:32",
"metadata": {
"order_id": "ORDER_123",
"description": "Abonnement premium"
},
"signature": "f8a9b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8"
}

Exigences de l'Endpoint

Votre endpoint webhook doit :

  1. Répondre avec HTTP 200 dans les 10 secondes
  2. Valider la signature (voir ci-dessous)
  3. Être idempotent : gérer les notifications en double avec élégance

Exemple : Node.js/Express

const express = require('express');
const crypto = require('crypto');
const app = express();

app.post('/webhooks/deposit', express.json(), (req, res) => {
const payload = req.body;
const receivedSignature = payload.signature;

// Valider la signature
const expectedSignature = crypto
.createHmac('sha256', process.env.AWDPAY_WEBHOOK_SECRET)
.update(JSON.stringify({
reference: payload.reference,
status: payload.status,
amount: payload.amount
}))
.digest('hex');

if (receivedSignature !== expectedSignature) {
return res.status(401).send('Signature invalide');
}

// Traiter l'événement
console.log(`Dépôt ${payload.reference} est ${payload.status}`);

// Mettre à jour votre base de données
updateOrderStatus(payload.metadata.order_id, payload.status);

// Répondre immédiatement
res.status(200).send('OK');
});

app.listen(3000);

Exemple : Python/Flask

import hmac
import hashlib
from flask import Flask, request

app = Flask(__name__)

@app.route('/webhooks/deposit', methods=['POST'])
def webhook():
payload = request.json
received_signature = payload.get('signature')

# Valider la signature
signature_data = f"{payload['reference']}{payload['status']}{payload['amount']}"
expected_signature = hmac.new(
WEBHOOK_SECRET.encode(),
signature_data.encode(),
hashlib.sha256
).hexdigest()

if received_signature != expected_signature:
return 'Signature invalide', 401

# Traiter l'événement
print(f"Dépôt {payload['reference']} est {payload['status']}")
update_order_status(payload['metadata']['order_id'], payload['status'])

return 'OK', 200

if __name__ == '__main__':
app.run(port=3000)

Vérification de Signature

AWDPay signe chaque webhook avec HMAC-SHA256 en utilisant votre secret webhook (disponible dans le Tableau de Bord).

Algorithme de Signature

signature = HMAC_SHA256(
webhook_secret,
reference + status + amount
)
Sécurité

Vérifiez toujours les signatures avant de traiter les webhooks pour prévenir les requêtes falsifiées.

Politique de Nouvelle Tentative

  • Les webhooks échoués (réponse non-200 ou timeout) sont réessayés avec backoff exponentiel :
    • 1ère tentative : 5 minutes
    • 2ème tentative : 30 minutes
    • 3ème tentative : 2 heures
    • 4ème tentative : 6 heures
  • Après 4 tentatives échouées, les notifications s'arrêtent. Consultez Tableau de Bord → Webhooks pour les journaux.

Test en Sandbox

Utilisez des outils comme ngrok ou localhost.run pour exposer votre serveur local :

ngrok http 3000
# Utilisez l'URL générée (ex. https://abc123.ngrok.io/webhooks/deposit) comme callbackUrl
Astuce de Test

En sandbox, déclenchez manuellement les renvois de webhook depuis le Tableau de Bord à des fins de test.

Prochaines Étapes