Verify Transactions with WebHooks

It is a good practice to verify the state of a transaction independently from your app, i.e. via your backend. With WebHooks you get notified about transaction events.

Register a WebHook

You can edit WebHooks in the Gateway Manager.

Go to the account settings by clicking your email in the top right corner. In the section 'WebHooks', you can create, edit, and delete WebHooks.

After the WebHook is set up, you will receive event callbacks when the status of your transaction changes.

Handle Incoming Event Data

For an APPROVED transaction, a transaction.succeeded event is fired both for CHARGE and REFUND transactions. This is what the body of the HTTP POST request to your registered WebHook URL will look like:

post Request
{
	"identifier": "cf30cfba-e62a-4903-99ff-ea3dbac52c8a",
	"created": "2013-07-09 12:12:01",
	"type": "transaction.succeeded",
	"transaction": {
		"identifier": "1c9b1add-0fec-4e25-8ad9-f314e8bf0a80",
		"groupIdentifier": "a1afe57f-520d-44cc-8b29-0e3800453481",
		"customIdentifier": "myX.12390.12309",
		"referencedTransactionIdentifier": null,
		"amount": 3.14,
		"currency": "EUR",
		"created": "2013-09-03 12:38:36",
		"status": "APPROVED",
		"subject": "A bunch of flowers",
		"type": "CHARGE",
		"mode": "TEST"
		"statusDetails": {…},
		"locationDetails": {…},
		"processingDetails": {…},
		"paymentDetails": {…},
		"receiptDetails": {…},
		"reader": {…}
	}
}
We send the raw JSON with a Content-Type of application/json. Please make sure that you access the HTTP body accordingly. Depending on the language that you implement your WebHook in, this might be considerably different from the way you access POST parameters sent by HTML forms (those usually have a Content-Type of application/x-www-form-urlencoded).

The JSON contains the event with its identifier (referred to as eventIdentifier), type and created date (in UTC). transaction already contains all details about the transaction, like your transactionIdentifier.

For a transaction that results in a status of DECLINED, ABORTED or ERROR a transaction.failed event is fired, also containing all the details in the transaction dictionary:

post Request
{
	"identifier": "cf30cfba-e62a-4903-99ff-ea3dbac52c8a",
	"created": "2013-07-09 12:12:01",
	"type": "transaction.failed",
	"transaction": {…}
}
Should your app during a transaction crash or lose the connection to the platform for any reason, your transaction will remain in the status PENDING for about 15 minutes until it runs into a timeout. Its status will then automatically turn into ERROR and you will receive a transaction.failed event.

Respond to the Incoming Event Data

Respond with a HTTP status code of 200, 201, or 202 to indicate that your server received and processed the call. If you respond with another status code, we consider the event delivery unsuccessful. The platform then tries to send you this transaction event again

  1. after 30 seconds
  2. each hour - for up to 3 days

to make absolutely sure you do not lose information about your transactions.

Query Event to Verify Authenticity

In principle, you get the transaction data directly with the event. However, since the platform does not authenticate itself, everyone may call your WebHook and send event and transaction data. To make absolutely sure that the event happened, you should not rely on the transaction data sent in the WebHook. Instead, query the platform for the event data.

You can use the eventIdentifier to query for the associated data. Do a HTTP GET on /v2/events/<eventIdentifer> and make sure to use the correct Authentication and API End Point.

If the eventIdentifier is valid, the platform will respond with the same data as before:

get /v2/events/{eventId} Try it out! Request
{
	"status": "ok",
	"data": {
		"identifier": "cf30cfba-e62a-4903-99ff-ea3dbac52c8a",
		"created": "2013-07-09 12:12:01",
		"type": "transaction.succeeded",
		"transaction": {...}
	}
}

Note the slightly different data structure: The platform returns an overall status of "ok". In data you receive the same event and transaction details as above.

Why is it more secure to do it in a two step process?

Since you are using a TLS encrypted connection (https) for getting the actual data, you can be sure that it was the platform that sent this response. If someone decided to fake a callback to your WebHook, you wouldn't fall for it, since you would get back a 404 Not Found when you try to access the event that supposedly happened.

Can we help you?

If you cannot find your answer, contact us and we'll get in touch with you soon.

© Copyright 2017 Payworks GmbH. Legal.