Webhooks

Production
Webhooks
Notifications événementielles pour suivre vos transactions en temps réel.

Vue d'ensemble

Neka Paie vous notifie sur l'URL notify_url de chaque transaction (ou l'URL configurée par défaut sur votre compte) à chaque changement d'état terminal :

  • SUCCESS — paiement confirmé
  • FAILED — paiement rejeté/refusé
  • EXPIRED — délai client dépassé
  • REVERSED — remboursement effectué

Les requêtes intermédiaires (PENDING) ne déclenchent pas de webhook.

Format du payload

JSON{
  "event": "transaction.status_changed",
  "transaction_id": "550e8400-e29b-41d4-a716-446655440000",
  "merchant_order_id": "order_2026_0001",
  "type": "CASHIN",
  "status": "SUCCESS",
  "amount": 50000,
  "currency": "XOF",
  "country_code": "ML",
  "provider_tx_id": "OM_2026042900012345",
  "timestamp": "2026-04-29T14:32:18+00:00"
}
En-têtes envoyés
Content-Typeapplication/json
X-NekaPay-SignatureHMAC-SHA256 du body
X-NekaPay-TimestampTimestamp Unix d'envoi
User-AgentNekaPay-Webhook/1.0

Vérification de la signature

Pour garantir l'authenticité, recalculer la signature côté serveur avec votre API Secret :

PHP$timestamp = $_SERVER['HTTP_X_NEKAPAY_TIMESTAMP'];
$signature = $_SERVER['HTTP_X_NEKAPAY_SIGNATURE'];
$body = file_get_contents('php://input');

// Anti-replay : refuser si timestamp > 5 min
if (abs(time() - (int)$timestamp) > 300) {
    http_response_code(401);
    exit;
}

$expected = hash_hmac('sha256', $timestamp . $body, $apiSecret);
if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit;
}

// Signature valide, traiter l'événement
$payload = json_decode($body, true);
processTransaction($payload);

http_response_code(200);

Politique de retry

Si votre endpoint ne répond pas avec un statut 2xx, Neka Paie réessaie selon la séquence :

TentativeDélai après l'échec précédentDélai cumulé
1ère0
2ème1 min1 min
3ème5 min6 min
4ème15 min21 min
5ème1 h1 h 21 min
6ème6 h7 h 21 min
7ème (dernière)24 h~31 h

Après 6 échecs successifs, l'envoi est abandonné. Vous pouvez consulter le statut via GET /payments/{id} en fallback.

Bonnes pratiques côté handler

  • Répondre rapidement (≤ 3 secondes). Mettre en queue le traitement métier.
  • Idempotence. Le même transaction_id peut être notifié plusieurs fois (retry, doublons).
  • Vérifier toujours la signature. Ne jamais faire confiance au payload brut.
  • Renvoyer 2xx dès que le webhook est accepté, même si le traitement asynchrone n'est pas fini.
  • Logger les requêtes pour debug.
  • Whitelist d'IPs Neka Paie côté firewall si possible.