Plateforme

Webhooks

Être notifié du résultat d'une transaction et vérifier la signature.

Quand une transaction atteint un statut final, nous envoyons une requête POST à votre callback_url, ou à l'URL de webhook de votre application.

POST
{
  "event": "payin.succeeded",
  "livemode": true,
  "data": {
    "reference": "PAYHBN2MJVPY32K7MSZXXN9",
    "type": "payin",
    "status": "succeeded",
    "livemode": true,
    "currency": "XAF",
    "amount": 5000,
    "fee": 150,
    "customer_fee": 0,
    "counterparty_amount": 5000,
    "merchant_amount": 4850,
    "method": "mobile_money",
    "operator": "mtn-cm",
    "phone_number": "237650000000",
    "checkout_url": null,
    "merchant_reference": "order-42",
    "failure": null,
    "created_at": "2026-10-04T10:12:00+00:00",
    "completed_at": "2026-10-04T10:13:07+00:00"
  }
}

Événements : payin.succeeded, payin.failed, payin.expired, payout.succeeded, payout.failed.

Vérifier la signature

Chaque notification porte l'en-tête Loov-Signature: t=…,v1=…. La signature est le HMAC-SHA256 de {t}.{corps brut} avec le secret de signature de votre application. Rejetez toute notification dont la signature ne correspond pas ou datant de plus de cinq minutes.

$payload = file_get_contents('php://input');
preg_match('/^t=(\d+),v1=([0-9a-f]{64})$/', $_SERVER['HTTP_LOOV_SIGNATURE'] ?? '', $m);

$expected = hash_hmac('sha256', ($m[1] ?? '') . '.' . $payload, getenv('LOOV_WEBHOOK_SECRET'));

if (! $m || ! hash_equals($expected, $m[2]) || abs(time() - (int) $m[1]) > 300) {
    http_response_code(400);
    exit;
}

$event = json_decode($payload, true);
// ... mettez à jour la commande $event['data']['merchant_reference']
http_response_code(200);

Bonnes pratiques

  • Répondez avec un code 2xx en moins de 10 secondes ; traitez le reste en arrière-plan.
  • En cas d'échec, nous réessayons jusqu'à 8 fois, d'une minute à plusieurs heures d'intervalle.
  • Une même notification peut arriver deux fois : rendez votre traitement idempotent grâce à la référence.
  • L'URL doit être en HTTPS et publique. Vous pouvez renvoyer une notification depuis le détail de la transaction.