JSON Authentication
The authentication of this JSON API is based on a standard HMAC Authentication implementation. See this article for a basic explanation of HMAC.
Explanation
To authenticate your application to the API, you need to set the correct Authorization Header. Below is an example of such a header:
Authorization: hmac ABCD1234:WISKbwwMbWhMRSRJc0jFtg/LIvB9vM5VWPvfVa0JnMc=:134ee2ec5c9d43d7acfae9190ec7eb83:1434973589
We will break this header up into pieces. All values are separated by a colon ":"
.
- hmac: The authentication scheme. Always "hmac".
- ABCD1234: Website Key: This key can be found in the Buckaroo payment plaza at Buckaroo Plaza. Click on your merchant name in the menu on the left side of the screen -> websites -> {yourwebsite}. Here you can find the website key in the table in the first row.
- WISKbwwMbWhMRSRJc0jFtg/LIvB9vM5VWPvfVa0JnMc=: A Base64 hash using HMAC SHA256 signed with your Secret Key. The HMAC SHA256 is calculated over a concatenated string (as raw data/binary/bytes) of the following values: WebsiteKey, requestHttpMethod, requestUri, requestTimeStamp, nonce, requestContentBase64String. The Base64 hash should be a string of 44 characters.
- 134ee2ec5c9d43d7acfae9190ec7eb83: Nonce: A random sequence of characters, differing for each request.
- 1434973589: Request TimeStamp: An integer of the total amount of seconds elapsed since 01-01-1970 (00:00:00:00) in UTC time.
Values for HMAC SHA256 Hash
All these parameters (except the Secret Key) should be concatenated into one string for the generation of the HMAC SHA256 hash.
- Website key: This key can be found in the Buckaroo payment plaza at Buckaroo Plaza. Click on 'My Buckaroo' in the bottom left of the screen -> websites -> {yourwebsite}. Here you can find the website key in the table in the first row. If you have multiple websites, use the filter option in the top right to switch between websites.
- Request method: Usually GET or POST, always uppercase.
- Request URI: The request URI without the protocol. First URI encoded and then to lowercase. For example:
https://testcheckout.buckaroo.nl/json/Transaction/Specification/ideal
would becometestcheckout.buckaroo.nl%2fjson%2ftransaction%2fspecification%2fideal
. - Request timestamp: An integer of the total amount of seconds elapsed since 01-01-1970 (00:00:00:00) in UTC time.
- Nonce: A random sequence of characters, differing for each request.
- Request content string: Create an MD5 hash (as raw data/binary/bytes) of the request content. Then convert this hash to a Base64 string. The Base64 string should be 24 characters.
- Secret Key: This key is used to generate the HMAC SHA256 hash. You can create a Secret Key in your Buckaroo account: Buckaroo Plaza.
Additional Headers (Not Mandatory)
- Culture: The user culture if applicable (e.g.,
nl-NL
). If not provided, a default ofen-US
will be used. - Channel: The used channel, mostly 'Web' is used (which is default), but in some cases 'Backoffice' is required.
- Software: A definition of the software used to create the request, formatted as:
{"PlatformName":"X","PlatformVersion":"1.0","ModuleSupplier":"X","ModuleName":"X","ModuleVersion":"1.0"}
Code Examples
C#
NOTE: This solution depends on the "Json.NET" Library (https://www.newtonsoft.com/json).
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static async void Main(string[] args)
{
string apiBaseAddress = "https://testcheckout.buckaroo.nl/";
CustomDelegatingHandler customDelegatingHandler = new CustomDelegatingHandler();
HttpClient client = HttpClientFactory.Create(customDelegatingHandler);
var bodyString = "{ \"Services\": [ { \"Name\": \"ideal\" } ] }";
object body = Newtonsoft.Json.JsonConvert.DeserializeObject<object>(bodyString);
HttpResponseMessage response = await client.PostAsJsonAsync(apiBaseAddress + "json/transactionrequestspecification", body);
var result = response.Content.ReadAsStringAsync().Result;
}
}
public class CustomDelegatingHandler : DelegatingHandler
{
private string WebsiteKey = "WEBSITEKEY";
private string SecretKey = "PRIVATEKEY";
protected async override Task<HttpResponseMessage>SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
HttpResponseMessage response = null;
string requestContentBase64String = string.Empty;
string requestUri = System.Web.HttpUtility.UrlEncode(request.RequestUri.Authority + request.RequestUri.PathAndQuery).ToLower();
string requestHttpMethod = request.Method.Method;
DateTime epochStart = new DateTime(1970, 01, 01, 0, 0, 0, 0, DateTimeKind.Utc);
TimeSpan timeSpan = DateTime.UtcNow - epochStart;
string requestTimeStamp = Convert.ToUInt64(timeSpan.TotalSeconds).ToString();
string nonce = Guid.NewGuid().ToString("N");
if (request.Content != null)
{
byte[] content = await request.Content.ReadAsByteArrayAsync();
MD5 md5 = MD5.Create();
byte[] requestContentHash = md5.ComputeHash(content);
requestContentBase64String = Convert.ToBase64String(requestContentHash);
}
string signatureRawData = String.Format("{0}{1}{2}{3}{4}{5}", WebsiteKey, requestHttpMethod, requestUri, requestTimeStamp, nonce, requestContentBase64String);
var secretKeyByteArray = Encoding.UTF8.GetBytes(SecretKey);
byte[] signature = Encoding.UTF8.GetBytes(signatureRawData);
using (HMACSHA256 hmac = new HMACSHA256(secretKeyByteArray))
{
byte[] signatureBytes = hmac.ComputeHash(signature);
string requestSignatureBase64String = Convert.ToBase64String(signatureBytes);
request.Headers.Authorization = new AuthenticationHeaderValue("hmac", string.Format("{0}:{1}:{2}:{3}", WebsiteKey, requestSignatureBase64String, nonce, requestTimeStamp));
}
request.Headers.Add("culture", "nl-NL");
request.Headers.Add("channel", "Web");
response = await base.SendAsync(request, cancellationToken);
return response;
}
}
JavaScript
NOTE: The Following scripts of the CryptoJs Library (https://code.google.com/p/crypto-js/) are required for this implementation of the HMAC authentication: enc-base64-min.js
, hmac-sha256.js
, md5-min.js
.
Note
This module can be used like the following example:
- var authHeader = BuckarooHmac.GetAuthHeader(requestUri, websiteKey, secretKey, postContent, httpMethod);
var authHeader = BuckarooHmac.GetAuthHeader(requestUri, websiteKey, secretKey, postContent, httpMethod);
var BuckarooHmac = (function () {
var self = {};
function getEncodedContent(content) {
if (content) {
var md5 = CryptoJS.MD5(content);
var base64 = CryptoJS.enc.Base64.stringify(md5);
return base64;
}
return content;
}
function getHash(websiteKey, secretKey, httpMethod, nonce, timeStamp, requestUri, content) {
var encodedContent = getEncodedContent(content);
var rawData = websiteKey + httpMethod + requestUri + timeStamp + nonce + encodedContent;
var hash = CryptoJS.HmacSHA256(rawData, secretKey);
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
return hashInBase64;
}
function getTimeStamp() {
return Math.floor((new Date).getTime() / 1000);
}
function getNonce() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 16; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
self.GetAuthHeader = function (requestUri, websiteKey, secretKey, content, httpMethod) {
var nonce = getNonce();
var timeStamp = getTimeStamp();
content = content ? content : "";
var url = encodeURIComponent(requestUri).toLowerCase();
return "hmac " + websiteKey + ":" + getHash(websiteKey, secretKey, httpMethod, nonce, timeStamp, url, content) + ":" + nonce + ":" + timeStamp;
}
return self;
}());
PHP
This is just an example of how the Authorization Header could be calculated.
<?php
$postArray = array(
"Currency" => "EUR",
"AmountDebit" => 10.00,
"Invoice" => "testinvoice 123",
"Services" => array(
"ServiceList" => array(
array(
"Action" => "Pay",
"Name" => "ideal",
"Parameters" => array(
array(
"Name" => "issuer",
"Value" => "ABNANL2A"
)
)
)
)
)
);
$postJson = json_encode($postArray);
echo $postJson . '<br><br>';
$md5 = md5($postJson, true);
$post = base64_encode($md5);
echo '<b>MD5 from json</b> ' . $md5 . '<br><br>';
echo '<b>base64 from MD5</b> ' . $post . '<br><br>';
$websiteKey = 'WEBSITE_KEY';
$uri = strtolower(urlencode('testcheckout.buckaroo.nl/json/Transaction'));
$nonce = rand(0000000, 9999999);
$time = time();
$hmac = $websiteKey . 'POST' . $uri . $time . $nonce . $post;
$s = hash_hmac('sha256', $hmac, 'Secret Key', true);
$hmac = base64_encode($s);
echo ("hmac " . $websiteKey . ':' . $hmac . ':' . $nonce . ':' . $time);
?>
Updated 5 months ago