Notifications

Notifications are used to send events to your application during the verification process.  Below you can see example payloads for specific Verify cases. 

Setup

As a prerequisite, you need to provide us with the URL for us to send you the notifications.  This can be setup in Fuzebox, in the applications area.  You’ll also need a notification secret which we’ll use to sign the notification, and which you should use to check that the signature is genuine.

Find out more about notification setup in Fuzebox Find out more about application setup in Fuzebox

Signature verification

You’ll receive three headers in the notification we post to your endpoint.  They should be used when you verify that the signature is correct, so you’re sure the notification came from Volt.  They are:

  • x-volt-signed –  the signature we calculated which you should recalculate and compare
  • x-volt-type – type of verification basing on the concatenated prefix verify-identification- plus the verification process status
  • x-volt-timed – UNIX timestamp of the notification

Find out how to verify signatures

Notification content

Notification body

The body of the notification contains a JSON formatted data structure containing the following information: 

  • processId (our ID for verification)
  • uniqueReference (your ID)
  • status (possible statuses are described below)
  • message
  • accountData
The accountData field

The accountData field can contain the following details; the actual data supplied is dependent on the information available from your customer’s bank. 

  • Bank name
  • Account holder’s name
  • Sort code (for UK accounts)
  • Account number
  • IBAN
  • Account balance amount & type

Status definitions

Status Meaning
DATA_RETRIEVED Data Retrieved is an indication that the requested details were successfully fetched from a bank and the verification process is finalised.
FAILED

There are several cases when a process can be marked as Failed. For example, it can happen for technical reasons when integrating with the bank.

Such a situation can occur while trying to obtain the bank data (after the shopper has given consent for retrieving the details) or when we get the bank redirection URL (after a user chooses their bank from our list).

When specific reasons for the failure are available to Volt, we will display them in the Message portion of the notification.

CANCELLED_BY_USER

Before a user is redirected to the bank from the Checkout, they have an option to cancel the process. If the process is cancelled, the status will change to Cancelled By User.

If the user later decides to go through the verification process again, a new process will need to be started.

EXPIRED

If the user is inactive for 15 minutes, Verify will terminate the process and mark it as Expired.

The user will need to start a new process to complete verification.

CONSENT_REJECTED

When a user is redirected to the bank, they have the choice to grant us consent to access their bank details or not.

If they choose to decline the request, a Consent Rejected status will be shown.

INSUFFICIENT_CONSENT_GRANTED The Insufficient Consent Granted status means that a user has provided consent but not for all of the data Volt requires. In this instance, the process cannot continue and the request is terminated.
CONSENT_REVOKED In the rare occasion that a user revokes the consent after granting it and before we fetch the bank details, Verify will assign the status to Consent Revoked.

Example when data has been retrieved

Successful/Data Retrieved Notification
{
   "processId":"5b04e695-a2c8-4437-95e0-9d57260c5236",
   "uniqueReference":"merchant-external-123",
   "status":"DATA_RETRIEVED",
   "message":"Data Obtained",
   "accountData":{
      "bank":{
         "name":"N26"
      },
      "accountHolderName":"John Smith",
      "accounts":[
         {
            "sortCode":null,
            "accountNumber":null,
            "iban":"DK0718282826129398",
            "bic":null,
            "name":null,
            "balance":[
               {
                  "type":"Available",
                  "dateTime":"2021-07-15T11:48:11.000Z",
                  "amount":"0",
                  "currency":"GBP"
               },
               {
                  "type":"Current",
                  "dateTime":"2021-07-15T11:49:06.000Z",
                  "amount":"2700",
                  "currency":"GBP"
               }
            ]
         },
         {
            "sortCode":"843881",
            "accountNumber":"62636253",
            "iban":null,
            "bic":null,
            "name":"John Smith",
            "balance":[
               {
                  "type":"Other",
                  "dateTime":"2021-07-15T11:48:08.000Z",
                  "amount":"-1.28",
                  "currency":"GBP"
               }
            ]
         }
      ]
   }
}

Examples when data has not been retrieved

Failed Notification (Obtaining data)
{
   "processId": "5b04e695-a2c8-4437-95e0-9d57260c5236",
   "uniqueReference": "merchant-external-123",
   "status": "FAILED",
   "message": "Obtaining data failed",
   "accountData": null
}
Failed Notification (Obtaining bank url)
{
   "processId": "5b04e695-a2c8-4437-95e0-9d57260c5236",
   "uniqueReference": "merchant-external-123",
   "status": "FAILED",
   "message": "Cannot connect to bank",
   "accountData": null
}
Cancelled Notification
{
   "processId": "5b04e695-a2c8-4437-95e0-9d57260c5236",
   "uniqueReference": "merchant-external-123",
   "status": "CANCELLED_BY_USER",
   "message": "User cancelled process",
   "accountData": null
}
Expired Notification
{
   "processId": "5b04e695-a2c8-4437-95e0-9d57260c5236",
   "uniqueReference": "merchant-external-123",
   "status": "EXPIRED",
   "message": "Process was abandoned",
   "accountData": null
}
Consent Rejected Notification
{
   "processId": "5b04e695-a2c8-4437-95e0-9d57260c5236",
   "uniqueReference": "merchant-external-123",
   "status": "CONSENT_REJECTED",
   "message": "Consent Rejected",
   "accountData": null
}
Insufficient Consent Granted Notification
{
   "processId": "5b04e695-a2c8-4437-95e0-9d57260c5236",
   "uniqueReference": "merchant-external-123",
   "status": "INSUFFICIENT_CONSENT_GRANTED",
   "message": "Insufficient consent granted",
   "accountData": null
}
Consent Revoked Notification
{
   "processId": "5b04e695-a2c8-4437-95e0-9d57260c5236",
   "uniqueReference": "merchant-external-123",
   "status": "CONSENT_REVOKED",
   "message": "Consent revoked",
   "accountData": null
}

Undelivered notifications

If we can’t deliver a notification to your endpoint, we will retry up to 15 times.  After the 15th failure you will be notified via email (if you have configured an email in the client notifications settings of Fuzebox) and notifications will be paused.  Notifications will then be queued until delivery is restarted upon a successful test from Fuzebox.

Retry delays

  • 5 seconds for the first retry, then after 
  • 30 seconds
  • 3 minutes
  • 10 minutes
  • and then every 15 minutes for all remaining retries

Restarting notifications after failure

Restarting notifications requires the successful sending and processing of a test notification to your endpoint.  This can be done in Fuzebox.  

Upon a successful response, this will process all queued notifications and re-enable for future notifications.

Verifying signatures

The Volt signature is created by combining your notification secret, the body of the notification, and a timestamp. It will never contain personal or sensitive information. Each notification request that we send you will also include a custom HTTP header – called X-Volt-Signed – which will contain the Volt signature.

How the signature works

  • You will receive a POST message from Volt to your preconfigured notification URL
  • Based on the body of the notification and your notification secret, you calculate what you think the signature should be
  • You then check your calculation against the signature received in the X-Volt-Signed to confirm they match
  • If they do match, return an empty HTTP response with a status code of 200 (OK)
  • If they do not match, return an empty HTTP response with a code of 400 (Bad Request) and do not process the notification

Verifying the signature

Calculating the verification hash for a signature is based on three things, all of which are included in the notification. To verify, follow these simple steps:

  1. Extract the User-Agent, X-Volt-Timed and X-Volt-Signed headers and the body of the notification
  2. From the User-Agent header, extract the notification version (this is the part after the forward Slash (/) and will be a numeric value. For example, if the User-Agent is Volt/2.0, the version is 2.0)
  3. Link the notification body with the content of the X-Volt-Timed header and the version, using the pipe delimiter | between them, like this: body|X-Volt-Timed|version. This creates your check string
  4. Hash the check string with HMAC SHA256, using your notification secret (see below for an example)
  5. Finally, compare your signature to the value in the notification’s X-Volt-Signed header
Ensure you can respond to an empty test at any time

Your system should always be able to respond to a test notification and respond with a 200 (OK) status code. In the test notification, we’ll send an empty JSON object in the request body, so your check string should look like this:

{}|X-Volt-Timed|version

A quick example to test your HMAC hashing

Using example values, here’s a quick test to ensure your signature check works correctly:

  • The version you extracted from the User-Agent: 1.0
  • X-Volt-Timed: 1631525064
  • X-Volt-Signed: ed22494369277d25cf8c2293d142e5fddb9cecbea1f54e28ac16db0bee3b8009
  • The complete, unmodified, body of the notification: {}
  • Your notification secret: 9c0c8c97-c224-45ed-a195-23b54b1c67e5

Next, use the pipe delimiter to join the body, X-Volt-Timed and version:

{}|1631525064|1.0

Then, hash this string using SHA256 and your notification secret of 9c0c8c97-c224-45ed-a195-23b54b1c67e5. If everything is correct, you should receive an HMAC that is identical to your X-Volt-Signed key:

ed22494369277d25cf8c2293d142e5fddb9cecbea1f54e28ac16db0bee3b8009