Webhooks
1. Introduction
Webhooks are messages sent from our platform to your server. These messages inform you about the result of your transactions or about status changes that happen at a later point (i.e. captures, refunds).
Our API allows you to receive the status of a transaction anytime you wish. However, sending API calls on a regular base requires you to build an application keeping track on all your transactions and their current status.
Our webhook solution frees you from this effort. Our system keeps track on all your transactions and notifies you whenever and status update occurs.
Make sure
- You understand the meaning of all statuses our platform returns in the webhooks.
- To whitelist our IP range as described in our Firewall documentation. This will ensure the webhooks feature will work correctly
2. Understand Webhooks
A webhook is a POST request from our platform to an HTTPS or HTTP endpoint at your server. It contains information about the current status of a transaction. Our platform sends webhooks for status updates after
- Online events that are out of your scope (authorisation results from a 3rd party provider like Paypal): the result is not visible to you, as your customer is not on your website at that time
- Offline events (i.e. capture of an authorisation, refund of an order): a change that occurs at a later point after the initial transaction has taken place
Have a look at all the events that trigger a webhook message:
Event | Description |
payment.created | The transaction has been created. This is the initial state once a new payment is created |
payment.redirected | The consumer has been redirected to a 3rd party to complete the authentication/payment |
payment.authorization_requested | We have requested an authorization against an asynchronous system and is awaiting its response (This is only applicable to Union Pay and Braspag.) |
payment.pending_approval | There are transactions waiting for your approval |
payment.pending_completion | There are transactions waiting for you to complete them |
payment.pending_capture | There are transactions waiting for you to capture them. |
payment.capture_requested | The transaction is in the queue to be captured. (For Cards, this means that the that the transaction has been authorized.) |
payment.captured | The transaction has been captured and we have received online confirmation |
payment.chargebacked | The transaction has been chargebacked |
payment.rejected | The transaction has been rejected |
payment.rejected_capture | We or one of our downstream acquirers/providers have rejected the capture requestFor every 4xx and 5xx response an errorId and an array of errors is returned providing detailed error information. |
payment.cancelled | You have cancelled the transaction |
payment.refunded | The transaction has been refunded |
refund.refund_requested | The transaction is in the queue to be refunded |
A webhook event contains a full JSON object with all relevant information you need to update your database.
This example contains three different events (defined in property status): corresponding to a respective transaction status update: CREATED, AUTHORIZATION_REQUESTED and CAPTURED.
You will receive these three webhooks messages separately as soon as the respective status update occurs on our platform:
[
{
"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_0"
},
"type":"payment.created"
},
{
"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_0"
},
"type":"payment.authorization_requested"
},
{
"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_0"
},
"type":"payment.captured"
}
]
3. Understand global transaction status and maintenance operations
As shown in the previous chapter, our platform links every webhook to a specific transaction with property payment.id. The full structure of payment.id is
paymentid_operationid
Both elements of this structure have a different purpose to indicate a transaction’s status:
Element | Description |
---|---|
paymentid |
A unique number referring to your order This is a fixed identifier that will never change over the course of a transaction life cycle. The latest final maintenance operation (i.e. authorisation/capture/refund) you have performed defines the transaction's current global status of your order. |
operationid |
A maintenance operation (i.e. authorisation/capture/refund) performed on this paymentid. Every maintenance operation has an individual operationid. Once you request a new transaction, it will receive a first operationid "0" (i.e. an authorisation or direct sales request). During a transaction's life cycle, every subsequent maintenance operation receives an incremental operationid. It indicates its order in the transaction life cycle (i.e. "1" for a capture after authorisation and "2" for a refund after that capture). Every operationid has its own StatusOutput.statusCode reflecting the outcome of the respective maintenance operation (i.e. an auhorisation request results either in StatusOutput.statusCode=5 or 2. Mind that an update for waiting/uncertain operationid statuses (i.e. from 91/92 to 9 or 93) will not result in an additional operationid. |
Our webhooks refer only to an online/offline event of a specific maintenance operation - and not on the transaction's global status. Have a look at the following example for transaction with paymentid 3136405348 to understand how webhooks work:
Property payment.id |
Maintenance operation/ |
operationid | Operationid StatusOutput.statusCode |
---|---|---|---|
3136405348_0 | You send an authorisiation request via CreatePayment/CreateHostedCheckout Our platform sends a webhook for online event payment.created |
0 | 5 |
3136405348_1 | You capture this transaction via CapturePayment Our platform sends a webhook for online event payment.capture_requested |
1 | 91 |
3136405348_1 |
Our platform receives the confirmation that the capture has been successful Our platform updates the original capture request 3136405348_1 to statusOutput.status=9 and sends a webhook for offline event payment.captured |
1 | 9 |
3136405348_2 |
You refund this transation via RefundPayment Our platform sends a webhook for online event refund.refund_requested |
2 | 81 |
3136405348_2 |
Our platform receives the confirmation that the refund has been successful Our platform updates the original capture request 3136405348_2 to statusOutput.status=8 and sends a webhook for offline event payment.refunded |
2 | 8 |
4. Configure Webhooks
To use webhooks, you need to
a. Configure webhooks in Merchant Portal
To configure webhooks in the Merchant Portal, follow these steps:
- Login to the Merchant Portal. Go to Developer > Webhooks
- If you have not configured anything yet, the screen shows "No keys generated" / "You don’t have endpoints configured at the moment."
- Click on "Generate webhooks keys". The screen now shows both the "Webhooks ID" and the affiliated "Secret Webhook Key" in the table. The resulting webhooks key is used to validate the messages as legitimate data transfer between our platform and your server. If you use one of our SDKs, this process happens automatically. If you choose to build your own application, make sure to include it
- Click on "Add webhook endpoint" and enter your endpoint URL receiving the webhooks on your server in the dialogue box. Click on "Confirm". You can add up to five URLs by repeating the operation
If you already have configured a Webhooks ID/Secret Webhook Key pair, clicking on "Generate webhooks keys" will create a new pair and revoke the existing one immediately
b. Set up webhook endpoint
To process the incoming webhooks in your system, you need to build an application on an HTTPS endpoint on your server. It should be able to
-
- Translate JSON into objects and signature verification. Our server SDKs help you achieve this
- Respond to a GET action and echo the 'X-GCS-Webhooks-Endpoint-Verification' header value in the body
- Respond to the POST action with a 2XX status code for all events delivered
- Validate the signature on the message
5. Respond to Webhooks
Whenever your server successfully receives a webhook message, it should return a HTTP status code in 2xx range. This will ensure our system acknowledges that you have received the webhook.
However, if your system does not respond, our platform will assume that the delivery of the webhook failed. Learn in our next chapter about our fallback solutions for this scenario.
This will prevent that we wrongfully assume that the webhook message was not delivered.
6. Recover failed attempts
If our system fails to send messages to your endpoint URLs (or does not receive a 2xx status code from your server), our platform will retry to deliver them at a later point. We will perform three times according to the following pattern:
Retry attempt | Retry time relative to first delivery attempt |
1 | 30 minutes |
2 | 60 minutes |
3 | 90 minutes |