marcopolo Online payment
Sign up

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 basis 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:

Overview

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): 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.
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 transaction has been authorised.)
payment.captured The transaction has been captured and we have received online confirmation.
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. Applicable only for transactions reaching statusOutput.statusCode=6.
payment.refunded The transaction has been refunded.
refund.refund_requested The transaction is in the queue to be refunded.
payment.cancelled Your customers has cancelled the transaction on the Hosted Checkout Page. Applicable only for transactions reaching statusOutput.statusCode=1.

A webhook event contains a full JSON object with all relevant information you need to update your database.

You will receive these three webhooks messages separately (for CREATED, AUTHORIZATION_REQUESTED and CAPTURED) as soon as the respective status (as defined in property status) update occurs on our platform:

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"
   }
]

Status Changes

Our platform links every webhook to a specific transaction with property payment.id. Depending on a transaction’s status, you can perform maintenance operations on it, such as a capture or a refund. Once you perform such a maintenance operation, the payment.id of this transaction changes, as you change the transaction status (i.e. from statusOutput.statusCode=5 to statusOutput.statusCode=91). Our platform will send webhooks for these maintenance operations, also known as online events.

However, there are specific transaction status changes triggered by our platform and not by maintenance operations (i.e. from statusOutput.statusCode=91 to statusOutput.statusCode=9). Our platform will send webhooks for these status changes as well, but not change the payment.id, also known as offline events.

Have a look at the following example to understand how:

  • The payment.id changes over the course of a transaction life cycle due to maintenance operations.
  • Our platform performs transaction status changes without changing the payment.id.
  • Our platform sends webhooks for these maintenance operation (online events) and transaction status changes (offline events).

The payment.id can change after each maintenance operation following an incremental logic. However, as this is not the case in some specific scenarios, we strongly recommend not building your business operations around it.

payment.id Maintenance operation/transaction status change/webhook statusOutput.statusCode
payment.id1 You send an authorisiation request via CreatePayment/CreateHostedCheckout

Our platform sends a webhook for online event payment.created
5
payment.id2 You capture this transaction via CapturePayment

Our platform sends a webhook for online event payment.capture_requested
91
payment.id2

Our platform receives the confirmation that the capture has been successful

Our platform updates the original capture request payment.id1 to statusOutput.status=9 and sends a webhook for offline event payment.captured

9
payment.id3

You refund this transation via RefundPayment

Our platform sends a webhook for online event refund.refund_requested

81
payment.id3

Our platform receives the confirmation that the refund has been successful

Our platform updates the original capture request payment.id2 to statusOutput.status=8 and sends a webhook for offline event payment.refunded

8

Use GetPaymentDetails to retrace the changes of the payment.id over the course of a transactions’ life cycle via property operations.id:


{
  "id": "9000003260847978002",
  "operations": [
    [...]
      "id": "payment.id1",
    [...]
      },
      "id": " payment.id2",
    [...]
      "id": " payment.id3",
    [...]
    }
  }
]

Configuration

To use webhooks, you need to

a. Configure webhooks in Merchant Portal

To configure webhooks in the Merchant Portal, follow these steps:

  1. Login to the Merchant Portal. Go to Developer > Webhooks.
  2. If you have not configured anything yet, the screen shows "No keys generated" / "You don’t have endpoints configured at the moment."
  3. 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.
  4. 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.

Response

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.

Decouple your business logic from the actual handling of the webhook message. We strongly recommend answering right away with a 2xx status code before you perform any follow-up actions later on.

This will prevent that we wrongfully assume that the webhook message was not delivered.

Failure Recovery

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 five times according to the following pattern:

Retry attempt Retry time relative to last delivery attempt
1 10 minutes
2 1 hours
3 2 hours
4 8 hours
5 24 hours

Each retry includes a header attribute in the webhook message, called retry-count. The first attempt will have a retry-count of 0, and each retry will increase this number. This allows you to distinguish between a new webhook event and a retry of a previously failed attempt.

Was this page helpful?

Do you have any comments?

Thank you for your response.