Webhooks

Événements

VALIDIF pousse chaque changement d'état vers vos endpoints, avec signature HMAC et rejeux.

Format d'un événement

POST vers votre endpoint

{
  "id": "evt_58f1a0c7",
  "type": "payment_intent.captured",
  "created_at": "2026-09-08T10:12:31Z",
  "request_id": "req_8f21c0d4",
  "data": {
    "id": "pi_3f81b2c9",
    "reference": "pay_98231_af12",
    "amount": 250000,
    "currency": "XOF",
    "state": "captured",
    "card": { "last4": "4242", "brand": "visa" }
  }
}
ChampTypeDescription
idstringIdentifiant unique de l'événement, pour la déduplication.
typestringType d'événement (voir la liste ci-dessous).
created_atISO 8601Horodatage d'émission.
dataobjectRessource concernée, données sensibles masquées.

Types d'événements

ChampTypeDescription
payment_intent.createdpay-inIntention de paiement créée.
payment_intent.authorizedpay-inFonds autorisés.
payment_intent.capturedpay-inEncaissement confirmé.
payment_intent.canceledpay-inPaiement annulé avant capture.
payment_intent.failedpay-inPaiement refusé ou en échec.
payout.succeededpayoutPayout exécuté.
payout.failedpayoutPayout rejeté.
payout.reversedpayoutPayout annulé après exécution.

Vérifier la signature

Calculez un HMAC SHA-256 sur timestamp.raw_body avec le secret de signature de l'endpoint, puis comparez en temps constant. Répondez 2xx en moins de 20 secondes.

Vérification

# En-têtes reçus
# Validif-Signature: t=1789012351,v1=6f3c…
# Validif-Event-Id: evt_58f1a0c7

signed_payload="$timestamp.$raw_body"
expected=$(printf "%s" "$signed_payload" \
  | openssl dgst -sha256 -hmac "$WEBHOOK_SIGNING_SECRET" -hex \
  | awk '{print $2}')
# Comparez "expected" et v1 en temps constant avant tout traitement.

Rejeux

En cas de réponse non-2xx ou de timeout, la livraison est réessayée 6 fois : 30 s, 2 min, 10 min, 1 h, 6 h, 24 h. Vos handlers doivent être idempotents et se baser sur id.

Masquage des payloads

Avant tout stockage ou envoi d'email de notification, VALIDIF masque les champs sensibles et toute suite de chiffres ressemblant à un PAN. Aucun PAN complet ni CVV n'est conservé.

Tester en Sandbox

Envoyez un événement de test à l'endpoint d'ingestion Sandbox avec votre clé secrète. Le payload masqué apparaît ensuite dans « Webhooks reçus » de votre espace marchand et est envoyé à votre adresse de notification.

Envoi de test

curl -X POST \
  https://project--8092c64b-b750-48fe-a1c2-0de276fdae20-dev.lovable.app/api/public/sandbox-webhook \
  -H "Authorization: Bearer vl_sec_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "payment_intent.captured",
    "data": { "reference": "pay_98231_af12", "amount": 250000, "currency": "XOF" }
  }'