Payments, Supercharged. (1.0.0)

Download OpenAPI specification:Download

Welcome to Open Banking!

Open Banking payments are authenticated directly between consumers and their own bank. Meaning that chargebacks that merchants traditionally pay because of card fraud or rejected card payments just disappear.

Payments powered by Open Banking also offer near-real-time* transfers, so that the merchant receives the payment quickly and enabling them to ship their product or service as soon as possible.

Volt has developed a REST API for merchants, allowing you to offer the option to use Open Banking payments on your online checkout.

Simple, secure payments

Step 1: You send an API call to Volt to let us know the payment details and we'll respond with a payment ID, which you'll use when you redirect your customer.

Step 2: Volt will then securely route your customer to their bank's online portal to confirm the payment.

Step 3: The payment is then sent directly from your customer's bank account to your bank account in near-real-time*, over the Faster Payments network in the UK, SEPA and similar networks around Europe.

* Depends on the currency and both banks involved.

Quick start guide

Do you need help? Do you have any suggestions? Message us!

If you need any assistance during the integration process, please email us at support@volt.io.

Let us know your thoughts about our product and integration process at hello@volt.io. Your thoughts will help us shape our product to help you.

Check out Volt's checkout!

We now have two options for integration, depending on how and where you want Volt in your payment flow.

  • Option 1 - Volt's hosted checkout

    Our great-looking checkout page is the easiest way to integrate Volt and is the method we'd recommended. It's just a simple redirect to our checkout page, where your customer can select their bank and continue with their payment.

    It's data-driven and completely managed by Volt, meaning that the list of supported banks is always up-to-date so that your customer always has a great user experience.

volt_checkout image

In the future the Volt checkout page will be the point where desktop to mobile handoff will also be possible. Stay tuned for more information on this exciting new feature for 2021.

  • Option 2 - Custom country and bank selection on your site

    You can retrieve data on supported banks via the Volt API and build your own country and bank selectors into your checkout flow.

volt_summary image

You don't have to choose right now. If you don't pass a Bank ID to us in the payment request API call, we'll know you want to use the Volt hosted checkout. If not, we will show your user a simple confirmation page to show them which bank we're about to redirect to.

Step 1. Register a merchant account

To register a new merchant account, please send a request to support@volt.io with following information:

  • Your name
  • Your email address

and we'll get back to you to get some more information.

Once your merchant account is created we will let you know some credentials you can use in our merchant portal, Fuzebox.

We'll also create you some merchant credentials which you can use to access our sandbox environment. These will be in the form of a Customer ID and secret (the equivalent of a username and password for accessing our API)

Step 2. Register your first application

Once you've got a merchant account, you'll need to register an application that you'll use to access the Volt API. This could be a website, mobile app, or any other application you'll be using to consume API resources.

This can be done by going to the Applications under Configuration section of the Fuzebox.

application image

Once your customer has completed the payment experience it will result in either a success, pending or failure state and we'll redirect them to the appropriate URL as configured.

  • Register your success URL - this is where the customer will be redirected to once a payment has been confirmed as sent.
  • Register your pending URL - this is where the customer will be redirected to if a payment has been delayed for any reason.
  • Register your failure URL - this is where the customer will be redirected if a payment fails or if the customer cancels at any point in the process.

create_application image

Note: You can use the same URL for all three - just enter the same URL into each box. We'll send the same details including a status code, to whichever URL we redirect your user to.

The application you create will be referred to as a client in terms of authenticating with the API using oAuth. The two terms (client and application) are therefore interchangeable in this documentation.

We'll give you a Client ID and a Client Secret. You'll need to use both Client ID and Client Secret, along with your merchant credentials, to access the Volt API.

Make a note of the client secret as you'll only be able to retrieve it once - so keep it secure. You can, however, generate a new secret at any time in Fuzebox.

NEW Custom parameters

If you would like us to send custom parameters back to your URL when the customer is returned to you, you can now pass them in your payment request. See the documentation requesting a new payment for more details.

Step 3. Prepare to receive payment status notifications

IMPORTANT - Your customer arriving at your redirect URLs should not be taken as a confirmation of that status as your redirect URLs are publicly accessible. Payment status notifications are sent to a special notifications URL and we'll digitally sign each notification so that you can be sure it's come from Volt.

  • We'll send this notification just before we redirect your customer to the success, pending or failure URL. If a status changes from pending to a success or failure state, we'll send another notification to update you.

  • Each notification will be signed with a secret notification key which you can retrieve and change in Fuzebox

  • You'll then need to confirm that you have received the notification and validated that the signature is correct.

How to setup notifications

  1. Head to Fuzebox and find the application you set up in step 2. Navigate to Notification section and click Configure notifications.

    • Register your notification URL for your application - this is the URL that we'll POST a notification message to and should start with https:// (i.e. it must be a secure URL)

    • Register a notification failure email address - we'll let you know here should we be unable to deliver payment notifications to your configured URL

    configure_notification

    Once you configured your notification URL and failure email address test your notification setup by clicking on the Send a test notification button. We'll send a signed notification to you and process your response

  2. If your Notifications secret ever becomes known, you should change it immediately - you can do that by clicking Generate a new notification secret in Notifications section on Fuzebox

Responding to a notification

  • You should ONLY respond with a 200 OK or 400 Bad Request HTTP code. There's no need to return any details in the body of the response.

  • If we receive no response we'll keep trying to send you the notification up to 5 more times at 1 minute intervals

  • If we fail to send a notification 5 times we'll send an email to your notification failure email address. Please note that you'll only receive an email for the first notification failure.

  • If you've sent us a 400 (Bad Request) response, we'll send an email to your notification failure email address - again only the first time this happens.

  • If notifications are failing, we'll switch notifications off until you confirm, via Fuzebox, that you have sent and received a test notification.

Once you've identified the issue, you can re-enable and re-send any failed notifications from Fuzebox by clicking button Send a test to restart notifications.

Step 4. Authenticate with the Volt API

To use the Volt API you'll first need to use your secure credentials to authenticate and retrieve an access token.

The Volt API uses the oAuth2.0 standard for authentication.

Getting an access token

  • Authenticate by POSTing to the /oauth endpoint.

  • You'll need to use your Client ID and Client Secret, in combination with the API Username and password which you can retrieve from the Fuzebox.

  • The Client ID should be set in the client_id field and the client secret in the client_secret field.

  • The value of the grant_type field should be password

  • For formatting guidelines, please see the API documentation for the oAuth2 Authentication endpoint.

  • Once you've successfully authenticated, you'll be returned an access token in the response, which you'll then use as authorisation for your subsequent API calls.

Using your token to access the rest of the API

To use the rest of the Volt API you'll need to send the access token in a header called Authorization, with the format Bearer {token}, for example :-

Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJ2MmFQNDdIQXVTUi1...

Requesting your first payment

Now you're authenticated and have an access token, you're ready to make your first Open Banking payment!

Step 1. Pull the list of supported banks

NOTE - If you're using the Volt hosted checkout, you can skip this part!

To get a list of banks that we currently support for payment initiation, send a GET request to the /banks endpoint. The list is provided in Json format and will contain an id you'll need when initiating your payment from that bank.

You should start by using one of the model test banks on the sandbox API. In the sandbox bank list that's all you'll see by default.

GET /banks

For sandbox, we suggest you use Ozone Modelo Test Bank or Wood Bank to make test payments in GBP first. Once you're happy that your integration works, you can move on to adding more accounts and currencies to test.

Step 2. Pull the list of your test bank accounts

We've created you a test bank account to send payments to in GBP. Hit the /accounts endpoint to get list of test accounts.

GET /accounts

The list is provided in Json format and again will contain the id you'll need when initiating your payment.

Step 3. Send a payment initiation request

You can initiate a payment request from your customer by POSTing a payment initiation request to the /payments endpoint as detailed in Payments section in this documentation.

POST /payments
{
  "currencyCode": "GBP",
  "amount": 12345,
  "account": "insert your account ID",
  "type": "GOODS",
  "uniqueReference": "sa123456798",
  "bank": "insert your bank ID"
}

create_payment image

NOTE that the amount should not include any decimal places but should be an integer number in the minor currency unit - that is cents, pence etc, rather than dollars, euros or pounds.

  • If your request was successful, the response from this endpoint will contain a 201 Created status and the body will contain the ID of your payment.

We can now send your customer to their bank, so let's begin the the Volt checkout process for your customer.

You'll need to grab the ID we returned and base64 encode it. Then redirect your customer's browser to the Checkout by Volt page - for the sandbox :

https://checkout.sandbox.volt.io/{token}

where {token} is a base64 encoded version of the ID of your payment.

Setting the language for the checkout page

To set the language that the checkout page is displayed in, add the preferred language to the path as follows :

https://checkout.sandbox.volt.io/{language}/{token}

where language can be one of:

  • bg - Bulgarian
  • ce - Czech
  • de - German
  • en - English
  • es - Spanish
  • fr - French
  • hr - Croatian
  • hu - Hungarian
  • it - Italian
  • lt - Lithuanian
  • lv - Latvian
  • nl - Dutch
  • pl - Polish
  • pt - Portuguese
  • ro - Romanian
  • sl - Slovenian
  • sk - Slovak

Step 4. The customer journey

  • If you're using the Volt hosted checkout, your customer will get to choose or search for their bank from our up-to-date list.

  • They will be shown the details of the payment they're about to make and confirm that this is their intent.

    checkout_payment image

  • Once they've confirmed, they'll be taken to their bank's authentication page to complete the payment, where they'll need to authenticate using their normal bank security procedure. This procedure varies from bank to bank and may need the customer to provide 2-factor authentication via their phone or hardware device.

  • Your customer will then review the payment and may have to select the account they'll make the payment from. This part varies from bank to bank.

  • Once the customer has confirmed the payment and it's been made, Volt will show your customer a quick confirmation and redirect them back to your website or application (the success URL you defined on Fuzebox)

  • At this point we'll also POST to your notification URL and process your response. You can see more details about this below.

Note:
Other outcomes at this point might be that the payment was not authorised, the payment could not be completed for some reason or, for corporates, that we're waiting for another person to also authorise that payment.

Step 5. Returning to your website or application

Once the customer has returned to your website, their Volt journey is complete.

  • We'll send a single field called volt in the querystring to your appropriate return URL (success, failure).

  • This field contains the same base-64 encoded Json string comprising 3 fields like this, regardless of the URL we redirect to :-

{
  "id": "{Volt's payment UUID}",
  "uniqueReference": "{your id for the payment}",
  "status": "{COMPLETED|FAILED}"
}

Payment notifications

You should not trust the fact that a customer has reached your payment success URL, but ensure you wait until you receive a digitally signed notification via this webhook from Volt.

Signed notifications

If you get a notification from Volt, it’ll be signed using a secret notification key that's unique to your app, so that you can verify that it’s come from Volt. You shouldn’t process any message that appears to originate at Volt without performing this verification step.

  • To sign the notification, we’ll first generate a notification secret and share it with you via Fuzebox.

  • You’ll get a different secret for each client application you use to access Volt.

  • And it will be different to the client secret you use to identify your client to the API.

  • If you think your notification secret is not so secret any more, no problem, you can generate a new one on Fuzebox.

What the signature contains

The Volt signature is created by combining your notification secret with the body of the notification, and a timestamp. It won’t contain any useful, sensitive or personal information.

  • On each notification request that we send you, we’ll include a custom HTTP header called X-Volt-Signed, which will contain the Volt signature.

How the signature works

  • You will get a POST message from Volt to your preconfigured notification URL.

  • You’ll then need to calculate what you think the signature should be, based on the body of the notification itself and your notification secret.

  • You’ll then check that the Volt signature you received in the X-Volt-Signed header of the notification matches the signature that you calculated.

  • If they match, return an empty HTTP response with a status code of 200 (OK)

  • If they don’t match, then you should 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, which are all included as part of the notification.

  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 version, which is the part after the word Volt

  3. You'll then need to combine X-Volt-Timed with the notification body itself and the version

  4. Concatenate these items in that order (body|time|version) using a pipe (|) delimiter – this is exactly how we create the signature before we send it so you can be sure that if you create your version the same way, they will match.

NOTE: Please do not forget to configure a test notification case so you respond with 200 (OK) status code. In this case you will need to treat a content as an empty string: |time|version

  1. Hash the check string with HMAC SHA256, using your notification secret.

  2. And then compare your signature to the value in the notification’s X-Volt-Signed header.


A quick example to test your HMAC Hashing

Using some example values, let's run a quick test to make sure your signature check works as we're expecting it to.

  • Body of the notification : Test_Body

  • The version you extracted : 1.0

  • X-Volt-Timed : 20200131123456

  • Your secret key : 12345

  • X-Volt-Signed : eda5e46baa6a676851975365e12b4ae61ee48442c0cbb8d0e3c3cfd47c3e1085

Firstly, concatenate the body, version and timed items as follows :-

Test_Body|20200131123456|1.0

You'd hash the concatenated string using SHA256 - using your secret key, 12345. If everything is correct, you should get a computed HMAC of

eda5e46baa6a676851975365e12b4ae61ee48442c0cbb8d0e3c3cfd47c3e1085

which should match the X-Volt-Signed key above.


Notification content

The body of the notification contains a Json formatted data structure containing 4 fields; payment (our ID), reference (your id), amount (of the payment) and status (COMPLETED, FAILED, PENDING)

{
  "payment": "00000000-0000-0000-0000-000000000000",
  "reference": "Invoice-12345",
  "amount": 1000,
  "status": "COMPLETED"
}

PLEASE NOTE

At the moment, banks do not supply Volt with any personally identifiable information about your customer.

The COMPLETED status

The status of COMPLETED means that the payment has been instructed and accepted by your customer's bank. The payment request and instruction process is therefore completed.

It's important to note that this does not guarantee receipt of funds for you. Sometimes banks do cancel payments after the instruction has been accepted, for regulatory or technical reasons outside of Volt's control. You should always confirm receipt of funds with your receiving bank before releasing goods or services.

The PENDING status

If the status returned in the notification is PENDING, it means that the payment has not yet been confirmed by the customer's bank. This may be for a number of reasons and you should not count on receiving the funds until the status changes to COMPLETED.

  • As an example, the customer's bank may have encountered a delay in processing payments or the account used might require a second person to approve payments.

  • If Volt is made aware that the payment status has changed, we'll send another notification to you with the final status. The payment status could therefore change to COMPLETED or FAILED.

  • You may also poll us for status changes periodically using the GET /payments/{id} endpoint.

The FAILED status

The status of FAILED means that the payment request could not be completed for technical reasons in the banking network, was cancelled by your customer, or has been rejected by your customer's bank.

This could be for one of many reasons, for example your customer may not have enough funds in their account, they may have simply cancelled the payment process at any point after instruction, or the bank may have had technical or regulatory issues which meant that they had to terminate the payment process.

Not receiving notifications?

Volt will try to deliver the notification up to 5 times, hoping to get a 200 (OK) response from you. We'll leave a few seconds before we try sending again, in case it was a technical glitch at your end, or somewhere in the middle. The first retry will be after 3 seconds, the next after 6 seconds, 10 seconds, 15 seconds and 30 seconds.

If we fail to deliver any notification 5 times in a row, then

  • We’ll assume there's a technical issue somewhere between Volt and you - and we'll stop sending you all notifications temporarily.

  • We’ll send an email to your technical and/or primary contact, plus we'll raise a support ticket at Volt on your behalf.

  • If we don’t hear from you to let us know the problem is fixed, then someone from Volt will be in touch.

  • If it's a problem your end then, once you've fixed the issue, go into Fuzebox and send a test notification (see below) to yourself and if that works we'll automatically switch notifications back on.

Don't worry, we'll send you any notifications you may have missed, once we know you're able to receive them.

Sending test notifications

You can request a test notification to ensure your webhook works. Do this from the Applications section of Fuzebox.

  • We'll send a test notification to your configured URL

  • All you need to do when you receive the notification is respond with either a 200 or 400 status code, as appropriate.

  • Once we receive a 200 response for you, then we'll start to send you live payment notifications

  • This function also acts as a trigger to restart notifications if they've been stopped after we've failed to deliver them to you.

Important implementation note - You should ensure that your application can always receive and respond to a test notification.

No payment notifications?

Let's do a few quick troubleshooting checks for some common causes...

  • Have you sent a test notification to the correct URL and responded to it with a HTTP 200 status?

    • We won't start (or restart) sending live payment notifications until we know you can process the test notification properly.
  • Are notifications showing as enabled in Fuzebox?

  • If you responded to the test notification and it was a success but you're still not receiving payment notifications, then please get in touch with our support team and we'll get to the bottom of it!

If you're making payments and not receiving the notifications, we'll automatically store and buffer those notifications so you'll never miss one. Once we've figured out what's wrong, all the notifications you missed will be sent (unless you ask us not to of course!)

Going into production

Step 1. Register at least one bank account to receive payments

To request a payment on the production system, you'll need to have at least one bank account registered. You'll need one registered account per currency you wish to receive.

You'll therefore need to tell us the currency your account accepts and the bank account details to send payments to (this will be your account number and sort code for UK accounts, IBAN and SWIFT BIC for European accounts)

  • You can configure your bank accounts online in Fuzebox

Step 2. Setup where you'd like to receive payments from

You should now setup which countries you would like to receive payments from. You can do this on an per-country basis or per-region (e.g. all of Europe).

If you're using the Volt hosted checkout page, this will restrict the countries and banks that are shown for your customer to choose from.

For example, it may be a regulatory requirement for your organisation that you can only accept payments from your own country. Or, if your customer lives in another country and wants to send a payment cross-border, they may be charged extra by their bank for this facility. There should be no extra charge for payments in Euros (EUR) sent within the SEPA (Single Euro Payments Area) zone.

  • Again, you can do this online in Fuzebox

Step 3. Ask us to switch on production mode

We'll need to enable your Volt system for production use. Let us know when you're ready by emailing us at support@volt.io. We'll do a quick check that everything's setup correctly and then switch you on.

Step 4. Test your production integration

Make sure that everything works!

  • Make some small test payments to your live bank account.

  • If you have multiple accounts or multiple currencies setup, test them all to make sure that the payments are routing in to the accounts you're expecting them to.

  • Test your notifications - make sure they work - both from a test and live payment point of view.

Step 5. Go live!

When you're happy, put your new checkout live and start receiving payments through Volt's Open Banking gateway.

API : filtering lists

In endpoints that return a list, we offer various ways of filtering the information returned, depending on the field type. Filterable fields are listed in the relevant endpoint documentation.

Equal to =

  • For all field types you can filter by an exact value using a standard query parameter

    ?amount=12345

Greater than / after [gt]=

  • For numeric fields, amounts greater than a value

    ?amount[gt]=12345

  • For date fields, dates later than a given date

    ?createdAt[gt]=20201205

Greater than or equal to / on or later than [gte]=

  • For numeric fields, amounts greater than, or equal to, a value

    ?amount[gte]=12345

  • For date fields, dates on or later than a given date

    ?createdAt[gte]=20201205

Less than / before [lt]=

  • For numeric fields, amounts greater than a value

    ?amount[lt]=12345

  • For date fields, dates later than a given date

    ?createdAt[lt]=20201205

Less than or equal to / before or on [lte]=

  • For numeric fields, amounts less than, or equal to, a value

    ?amount[lte]=12345

  • For date fields, dates on or later than a given date

    ?createdAt[lte]=20201205

Any in a set of values []=, []=

  • Specify the same field more than once in the query string with [] and each value you want to filter by (exact matches only)

    ?status[]=success&status[]=pending

Not equal to a single value [not]=

  • To return values that are not equal to an exact value

    ?status[not]=pending

Not equal to a set of values [][not]=

  • To return values that are not equal to more than one exact value, specify the values in an array by adding the same field multiple times, but with an extra flag of [not].

    ?status[][not]=pending&status[][not]=failed

API : sorting lists

For endpoints that return lists of data (e.g. GET /banks or GET /payments), you can sort the data by certain fields, using the format specification below.

Sort order

  • ASC

    • Numerical from lowest first
    • Text in alphabetical order
    • Dates from earliest first
  • DESC

    • Numerical from highest first
    • Text in reverse alphabetical order
    • Dates from latest first

To sort by a particular field

  • Specify the order parameter and the field name in square brackets and the sort order

    /accounts?order[createdAt]=ASC