Webhooks
Les webhooks sont un outil puissant pour recevoir des messages envoyés de notre plateforme à votre serveur. Ces messages contiennent des informations sur le résultat de vos transactions ou sur les changements de statut qui se produisent ultérieurement (c'est-à-dire des captures, des remboursements). Cela inclut l'identifiant payment.id
concerné, le montant, le statut et toutes les données client pertinentes.
Aperçu
Les webhooks envoient des notifications pour les opérations réussies et échouées. Ainsi, les webhooks vous permettent d'automatiser votre flux de traitement des transactions en mettant à jour vos systèmes de gestion de commandes.
Notre API vous permet de recevoir le statut d'une transaction à tout moment. Cependant, envoyer des appels API régulièrement vous oblige à construire une application qui suit toutes vos transactions et leur statut actuel.
Notre solution webhook vous libère de cet effort. Notre système garde une trace de toutes vos transactions et vous notifie chaque fois qu'une mise à jour de statut se produit.
Notre solution webhook vous libère de cet effort. Notre système garde une trace de toutes vos transactions et vous notifie chaque fois qu'une mise à jour de statut se produit.
Assurez-vous :
- De comprendre la signification de tous les statuts renvoyés par notre plateforme dans les webhooks.
- De mettre sur liste blanche notre plage d'IP comme décrit dans notre documentation sur le pare-feu. Cela garantira le bon fonctionnement de la fonctionnalité des webhooks.
Bonnes pratiques
Pour utiliser les webhooks de la manière la plus efficace, suivez ces directives :
- Obtenez une compréhension générale des statuts des transactions et des statuts pour lesquels notre plateforme envoie des webhooks.
- Les webhooks sont des événements asynchrones. Par conséquent, ils ne sont pas adaptés pour gérer des événements en temps réel pour le processus de paiement (c'est-à-dire pour adapter le parcours de paiement de vos clients selon le résultat de la transaction). Pour des mises à jour en temps réel, nous recommandons :
- D'envoyer une demande GetHostedCheckoutStatus (pour les transactions Hosted Checkout Page) / GetPaymentDetails (pour les transactions Server-to-server).
- D'utiliser l'attribut returnUrl comme une page intermédiaire générique, sans distinction de statut. Une fois que votre système a reçu le statut de la transaction, adaptez le returnUrl en conséquence ou redirigez vos clients vers une autre Url dans votre boutique en ligne.
- Si, pour une raison quelconque, votre système ne traite pas correctement un webhook, nous recommandons d'inclure un mécanisme de secours dans votre logique métier. Cela pourrait être d'envoyer de manière proactive une demande GetHostedCheckout/GetPaymentDetails à notre plateforme.
Configuration
Pour utiliser les Webhooks, vous devez
- a. Les configurer dans le Merchant Portal
- b. Définir le point de terminaison des Webhooks
- c. Construire un mécanisme de Webhooks
a. Configurer la clé / le secret des Webhooks
Pour configurer la clé / le secret des webhooks dans le Merchant Portal, suivez ces étapes :
- Connectez-vous au Merchant Portal. Allez à Développeur > Webhooks.
- Si vous n'avez rien configuré pour le moment, l'écran affiche "No keys generated" / "You don’t have endpoints configured at the moment."
- Cliquez sur "Generate webhooks keys". L'écran affiche maintenant à la fois le "Webhooks ID" et la "Secret Webhook Key" associée dans le tableau. La clé de webhooks résultante est utilisée pour valider les messages comme transfert de données légitime entre notre plateforme et votre serveur. Si vous utilisez un nos SDKs, ce processus se passe automatiquement. Si vous choisissez de construire votre propre application, assurez-vous de l'inclure.
Si vous avez déjà configuré une paire Webhooks ID/Secret Webhook Key, en cliquant sur "Generate webhooks keys" une nouvelle paire sera créée et l'existante sera immédiatement révoquée.
b. Définir le point de terminaison des Webhooks
Vous pouvez définir le point de terminaison de vos Webhooks de deux manières :
- Dans le Merchant Portal comme une valeur codée en dur.
- Individuellement pour chaque requête CreateHostedCheckout/CreatePayments.
Dans le Merchant Portal comme une valeur codée en dur
- Connectez-vous au Merchant Portal. Allez à Développeur > Webhooks.
- Cliquez sur "Add webhook endpoint" et entrez l'URL de votre point de terminaison recevant les webhooks sur votre serveur dans la boîte de dialogue. Cliquez sur "Confirm". Vous pouvez ajouter jusqu'à cinq URL en répétant l'opération.
Individuellement pour chaque requête CreateHostedCheckout/CreatePayments.
Au lieu de coder en dur l'URL des webhooks dans le Merchant Portal, vous pouvez l'ajouter individuellement à vos requêtes CreateHostedCheckout/CreatePayment. De cette façon, vous pouvez définir la destination du webhook pour chaque transaction/payment.id. Nous vous recommandons fortement de le faire si vous traitez des transactions via différentes boutiques en ligne.
Pour ce faire, ajoutez la propriété feedbacks.webhookUrls à vos requêtes CreateHostedCheckout/CreatePayment. Définissez jusqu'à cinq URL individuelles sous forme de tableau de chaînes de caractères dans cette propriété. Notez que l'envoi de toute valeur dans la propriété feedbacks.webhookUrls remplacera les valeurs que vous avez configurées dans votre compte.
La propriété feedbacks.webhookUrl est obsolète. Nous vous recommandons vivement d'utiliser feedbacks.webhookUrls à la place.
c. Construire un mécanisme de Webhooks
Pour traiter les webhooks entrants dans votre système, vous devez créer une application sur un API endpoint HTTPS sur votre serveur. Elle doit être capable de :
- Traduire le JSON en objets et effectuer la vérification de signature. Nos SDKs serveur vous aident à y parvenir.
- Répondre à l'action POST avec un code de statut 2XX pour tous les événements livrés.
- Valider la signature sur le message.
Messages
Un webhook est une requête POST de notre plateforme vers un API endpoint HTTPS sur votre serveur. Elle contient des informations sur le statut actuel d'une transaction. Notre plateforme envoie des webhooks pour les mises à jour de statut après :
- Des événements en ligne qui échappent à votre contrôle (résultats d'autorisation d'un fournisseur tiers) : le résultat n'est pas visible pour vous, car votre client n'est pas sur votre site à ce moment-là.
- Des événements hors ligne (c'est-à-dire capture d'une autorisation, remboursement d'une commande) : un changement qui se produit ultérieurement après que la transaction initiale a eu lieu.
Consultez tous les événements qui déclenchent un message webhook :
Événement | Description |
---|---|
payment.created | La transaction ou l'opération (c'est-à-dire un remboursement) a été créée.. Il s'agit de l'état initial une fois qu'un nouveau paiement est créé. |
payment.redirected | Le consommateur a été redirigé vers un tiers pour compléter l'authentification/le paiement. |
payment.authorization_requested | Nous avons demandé une autorisation à un système asynchrone et attendons sa réponse. |
payment.pending_approval | Des transactions attendent votre approbation. |
payment.pending_completion | Des transactions attendent que vous les complétiez. |
payment.pending_capture | Des transactions attendent que vous les capturiez. |
payment.capture_requested | La transaction est en attente de capture. (Pour les cartes, cela signifie que la transaction a été autorisée.) |
payment.captured | La transaction a été capturée et nous avons reçu une confirmation en ligne. |
payment.rejected | La transaction a été rejetée. |
payment.rejected_capture | Nous ou l'un de nos acquéreurs/fournisseurs en aval avons rejeté la requête de capture. Pour chaque réponse 4xx et 5xx, un errorId et un tableau d'erreurs sont renvoyés fournissant des informations détaillées sur l'erreur. |
payment.cancelled | Vous avez annulé la transaction. Applicable uniquement pour les transactions atteignant statusOutput.statusCode=6. |
payment.refunded | La transaction a été remboursée. |
refund.refund_requested | La transaction est en attente de remboursement. |
payment.cancelled | Vos clients ont annulé la transaction sur la Hosted Checkout Page. Applicable uniquement pour les transactions atteignant statusOutput.statusCode=1. |
paymentlink.created | Le lien de paiement a été créé. |
paymentlink.clicked | Le lien de paiement a été cliqué/visité. |
paymentlink.paid | Un paiement a été traité avec succès avec le lien de paiement. |
paymentlink.cancelled | Le lien de paiement a été annulé. |
paymentlink.expired | La date d'expiration du lien de paiement a été atteinte. |
Un événement webhook contient un objet JSON complet avec toutes les informations pertinentes dont vous avez besoin pour mettre à jour votre base de données.
Vous recevrez ces trois messages webhooks séparément (pour CREATED, AUTHORIZATION_REQUESTED et CAPTURED) dès que la mise à jour de statut respective (comme défini dans la propriété status) se produit sur notre plateforme :
CREATED
[
{
"apiVersion":"v1",
"created":"2020-12-09T11:20:40.3744722+01:00",
"id":"34b8a607-1fce-4003-b3ae-a4d29e92b232",
"merchantId":"TESTCIMCREDITCARDS",
"payment":{
"paymentOutput":{
"amountOfMoney":{
"amount":1000,
"currencyCode":"EUR"
},
"references":{
"merchantReference":"BDD_20201209112039463_UNNERD0105E2_SS_00"
},
"cardPaymentMethodSpecificOutput":{
"paymentProductId":1,
"card":{
"cardNumber":"************4675",
"expiryDate":"1221"
},
"fraudResults":{
"fraudServiceResult":"no-advice"
},
"threeDSecureResults":{
"eci":"9"
}
},
"paymentMethod":"card"
},
"status":"CREATED",
"statusOutput":{
"isCancellable":false,
"statusCategory":"CREATED",
"statusCode":0,
"isAuthorized":false,
"isRefundable":false
},
"id":"***3092546156***"
},
"type":"payment.created"
}
]
AUTHORIZATION_REQUESTED
[
{
"apiVersion":"v1",
"created":"2020-12-09T11:20:40.346554+01:00",
"id":"03643daf-ba3e-4511-9c8c-e45988037c40",
"merchantId":"TESTCIMCREDITCARDS",
"payment":{
"paymentOutput":{
"amountOfMoney":{
"amount":1000,
"currencyCode":"EUR"
},
"references":{
"merchantReference":"BDD_20201209112039463_UNNERD0105E2_SS_00"
},
"cardPaymentMethodSpecificOutput":{
"paymentProductId":1,
"card":{
"cardNumber":"************4675",
"expiryDate":"1221"
},
"fraudResults":{
"fraudServiceResult":"challenged"
},
"threeDSecureResults":{
"version":"2.2.0",
"flow":"challenge",
"cavv":"AAABBEg0VhI0VniQEjRWAAAAAAA=",
"eci":"9",
"schemeEci":"5",
"authenticationStatus":"Y",
"acsTransactionId":"3E1D57DF-8DB1-4614-91D5-B11962519703",
"dsTransactionId":"3E1D57DF-8DB1-4614-91D5-B11962519703",
"xid":"MzE5NTA3Njg2Ng==",
"challengeIndicator":"no-preference",
"liability":"issuer"
}
},
"paymentMethod":"card"
},
"status":"AUTHORIZATION_REQUESTED",
"statusOutput":{
"isCancellable":false,
"statusCategory":"PENDING_CONNECT_OR_3RD_PARTY",
"statusCode":51,
"isAuthorized":false,
"isRefundable":false
},
"id":"***3092546156***"
},
"type":"payment.authorization_requested"
}
]
CAPTURED
[
{
"apiVersion":"v1",
"created":"2020-12-09T11:20:42.1464012+01:00",
"id":"7aeb0c3d-066e-4d31-bfe9-f9b5e48414df",
"merchantId":"TESTCIMCREDITCARDS",
"payment":{
"paymentOutput":{
"amountOfMoney":{
"amount":1000,
"currencyCode":"EUR"
},
"references":{
"merchantReference":"BDD_20201209112039463_UNNERD0105E2_SS_00"
},
"cardPaymentMethodSpecificOutput":{
"paymentProductId":1,
"authorisationCode":"test123",
"card":{
"cardNumber":"************4675",
"expiryDate":"1221"
},
"fraudResults":{
"fraudServiceResult":"challenged",
"avsResult":"U",
"cvvResult":"M"
},
"threeDSecureResults":{
"version":"2.2.0",
"flow":"challenge",
"cavv":"AAABBEg0VhI0VniQEjRWAAAAAAA=",
"eci":"9",
"schemeEci":"5",
"authenticationStatus":"Y",
"acsTransactionId":"3E1D57DF-8DB1-4614-91D5-B11962519703",
"dsTransactionId":"3E1D57DF-8DB1-4614-91D5-B11962519703",
"xid":"MzE5NTA3Njg2Ng==",
"challengeIndicator":"no-preference",
"liability":"issuer"
}
},
"paymentMethod":"card"
},
"status":"CAPTURED",
"statusOutput":{
"isCancellable":false,
"statusCategory":"COMPLETED",
"statusCode":9,
"isAuthorized":false,
"isRefundable":true
},
"id":"***3092546156***"
},
"type":"payment.captured"
}
]
Changements de Statut
Notre plateforme associe chaque webhook à une transaction spécifique avec la propriété payment.id. Selon le statut d'une transaction, vous pouvez effectuer des opérations de maintenance sur celle-ci, telles qu'une capture ou un remboursement. Une fois que vous effectuez une telle opération de maintenance, le payment.id de cette transaction change, car vous modifiez le statut de la transaction (c'est-à-dire de statusOutput.statusCode=5 à statusOutput.statusCode=91). Notre plateforme enverra des webhooks pour ces opérations de maintenance, également connues sous le nom d'événements en ligne.
Cependant, il existe des changements de statut de transaction spécifiques déclenchés par notre plateforme et non par des opérations de maintenance (c'est-à-dire de statusOutput.statusCode=91 à statusOutput.statusCode=9). Notre plateforme enverra également des webhooks pour ces changements de statut, mais ne changera pas le payment.id, également connus sous le nom d'événements hors ligne.
Consultez l'exemple suivant pour comprendre comment :
- Le payment.id change au cours du cycle de vie d'une transaction en raison des opérations de maintenance.
- Notre plateforme effectue des changements de statut de transaction sans changer le payment.id.
- Notre plateforme envoie des webhooks pour ces opérations de maintenance (événements en ligne) et changements de statut de transaction (événements hors ligne).
Le payment.id peut changer après chaque opération de maintenance suivant une logique incrémentale. Cependant, comme ce n'est pas le cas dans certains scénarios spécifiques, nous recommandons fortement de ne pas construire vos opérations commerciales autour de lui.
payment.id | Opération de maintenance/changement de statut de transaction/webhook | statusOutput.statusCode |
---|---|---|
payment.id1 | Vous envoyez une demande d'autorisation via CreatePayment/CreateHostedCheckout Notre plateforme envoie un webhook pour l'événement en ligne payment.created |
5 |
payment.id2 | Vous capturez cette transaction via CapturePayment Notre plateforme envoie un webhook pour l'événement en ligne payment.capture_requested |
91 |
payment.id2 |
Notre plateforme reçoit la confirmation que la capture a été réussie Notre plateforme met à jour la demande de capture initiale payment.id1 à statusOutput.status=9 et envoie un webhook pour l'événement hors ligne payment.captured |
9 |
payment.id3 |
Vous remboursez cette transaction via RefundPayment Notre plateforme envoie un webhook pour l'événement en ligne refund.refund_requested |
81 |
payment.id3 |
Notre plateforme reçoit la confirmation que le remboursement a été réussi Notre plateforme met à jour la demande de capture initiale payment.id2 à statusOutput.status=8 et envoie un webhook pour l'événement hors ligne payment.refunded |
8 |
Utilisez GetPaymentDetails pour retracer les changements de payment.id au cours du cycle de vie des transactions via la propriété operations.id :
{
"id": "9000003260847978002",
"operations": [
[...]
"id": "payment.id1",
[...]
},
"id": "payment.id2",
[...]
"id": "payment.id3",
[...]
}
}
]
Réponse
Chaque fois que votre serveur reçoit avec succès un message webhook, il doit renvoyer un code d'état HTTP dans la plage 2xx. Cela garantira à notre système que vous avez bien reçu le webhook.
Cependant, si votre système ne répond pas, notre plateforme supposera que la livraison du webhook a échoué. Découvrez dans notre prochain chapitre nos solutions de secours pour ce scénario.
Dissociez votre logique métier de la gestion effective du message webhook. Nous vous recommandons fortement de répondre immédiatement avec un code d'état 2xx avant d'effectuer toute action de suivi ultérieure.
Cela évitera que nous supposions à tort que le message webhook n'a pas été livré.
Récupération en cas d'échec
Si notre système échoue à envoyer des messages à vos URL d'API endpoint (ou ne reçoit pas de code d'état 2xx de votre serveur), notre plateforme réessaiera de les délivrer ultérieurement. Nous effectuerons cinq tentatives selon le schéma suivant :
Nouvelle tentative | Temps de réessai par rapport à la dernière tentative de livraison |
1 | 10 minutes |
2 | 1 heure |
3 | 2 heures |
4 | 8 heures |
5 | 24 heures |
Chaque réessai inclut un attribut d'en-tête dans le message webhook, appelé retry-count. La première tentative aura un retry-count de 0, et chaque nouvel essai augmentera ce nombre. Cela vous permet de faire la distinction entre un nouvel événement webhook et un réessai d'une tentative échouée précédente.
Testez
Pour garantir le bon fonctionnement des webhooks que vous avez configurés, utilisez nos points de terminaison dédiés ValidateWebhookCredentials/SendTestWebhooks.
Validation des identifiants
Assurez-vous que votre système accepte les notifications des webhooks de notre plateforme en validant votre clé et votre secret de webhooks.
Notre plateforme correspond à la clé de webhooks configurée dans votre compte et calcule un corps de requête vide haché basé sur le secret des webhooks.
Envoyez une requête à notre point de terminaison dédié ValidateWebhookCredentials :
{
"key": "bfa99cffb98dcad6c7f15824f5eb37",
"secret": "0mw3LBod/3yPuI+UOmjpVmzL8U+YaTDC44haC6bzQpw="
}
Propriété | Description |
---|---|
{merchantId} |
Votre compte sur notre plateforme pour lequel vous avez configuré les Webhooks. Ajoutez-le comme un paramètre de chemin à l'URL du point de terminaison ValidateWebhookCredentials. |
key |
La clé de webhooks que vous avez configurée pour le {merchantId}. |
secret |
La valeur encodée en base64 d'une chaîne vide hachée par le secret des webhooks que vous avez configuré dans votre compte. Utilisez exclusivement l'algorithme de hachage HMAC 256 pour votre test. |
Message de test
Instruisez notre plateforme pour envoyer un message de test au point de terminaison de vos webhooks. À la réception du webhook, votre serveur doit retourner un code d'état HTTP dans la plage 2xx. Conséquemment, notre plateforme retournera un code d'état HTTP 204 à votre requête initiale.
Envoyez une requête à notre point de terminaison SendTestWebhook dédié :
{
"url": "https://your-webhooks-url.com"
}
Propriété | Description |
---|---|
{merchantId} |
Votre compte sur notre plateforme pour lequel vous avez configuré les Webhooks. Ajoutez-le comme un paramètre de chemin à l'URL du point de terminaison ValidateWebhookCredentials. |
url |
Votre point de terminaison de webhooks recevant le message de test. Si laissé vide, la valeur par défaut est l'URL codée en dur que vous avez configurée dans votre compte. |
Notre plateforme retournera ce JSON :
{
"apiVersion": "v1",
"apiFullVersion": "v1.1",
"created": "2025-03-11T14:26:49.6746458+01:00",
"id": "a028fc60-b04c-4119-8c87-b836967e30de",
"merchantId": "YourMerchantId",
"payment": {
"paymentOutput": {
"amountOfMoney": {
"amount": 1234,
"currencyCode": "EUR"
},
"references": {
"merchantReference": "YourMerchantReference"
},
"acquiredAmount": {
"amount": 0,
"currencyCode": "EUR"
},
"customer": {
"device": {
"ipAddressCountryCode": "XX"
}
},
"cardPaymentMethodSpecificOutput": {
"paymentProductId": 0,
"card": {
"cardNumber": "************0000",
"expiryDate": "XXX",
"bin": "999999",
"countryCode": "XX"
},
"fraudResults": {
"fraudServiceResult": "no-advice",
"avsResult": "0",
"cvvResult": "0"
},
"threeDSecureResults": {
"eci": "0"
},
"acquirerInformation": {
"name": "Test"
}
},
"paymentMethod": "card"
},
"status": "AUTHORIZATION_REQUESTED",
"statusOutput": {
"isCancellable": false,
"statusCategory": "PENDING_CONNECT_OR_3RD_PARTY",
"statusCode": 0,
"isAuthorized": false,
"isRefundable": false
},
"id": "9999_9"
},
"type": "payment.test"
}