Verified hash

Some endpoints require a hash query parameter that contains a hash verifying the POST request body data. The hash is comprised of the query parameters sorted by name, concatenated (recursively) into one string, hashed (sha256) with SHthe client signature secret and finally base64 URL encoded. The verification hash ensures that the data being POST-ed has not been tampered with by a middleman.

Note: After the string is base64 encoded you should replace + with - and / with _. Also you should remove trailing =.

The sort algorithm is natsort ("Natural order string comparison").

{
    "a" : "zebra",
    "x" : "banana",
    "c" : {
        "b" : "orange",
        "c" : "monkey",
        "a" : "sun"
    },
    "b" : "tree"
}    

Should give the following string after concat: zebratreesunorangemonkeybanana

Hashing example

PHP

<?php
function recursiveArrayToString($data) {
    if (!is_array($data)) {
        return "$data";
    }
    $ret = "";
    uksort($data, 'strnatcmp');
    foreach ($data as $v) {
        $ret .= recursiveArrayToString($v);
    }
    return $ret;
}

function base64UrlEncode($input) {
    return rtrim(strtr(base64_encode($input), '+/', '-_'), '=');
}

function createHash($data, $secret) {
    $string = recursiveArrayToString($data);
    return base64UrlEncode(hash_hmac("sha256", $string, $secret, true));
}

$sign_secret = 'foobar';

$data = array(
    'requestReference' => $ref, // unique to reqest
    'clientReference' => $localOrderId, // freely useable by client
    'paymentOptions' => 2,
    'items' => array(
        array('productId' => 100002, 'clientItemReference' => 'first item'),
        array('name' => 'A magazine', 'description' => 'It is really great', 'price' => 2000, 'vat' => 2500),
        array('productId' => 100002, 'name' => 'Banana',  'description' => 'One', 'price' => 1500, 'vat' => 2500, 'quantity' => 1, 'clientItemReference' => 'itemRef4'),
    )
);

$data['hash'] = createHash($data, $sign_secret);
$client->api('/user/123/charge', 'POST', $data);

PHP SDK

<?php
$sign_secret = 'foobar';

$path = "/payment":
$method = "POST";

$data = array(
    'action' => 'sale',
    'productId' => 10001,
    'userId' => 123,
    'price' => 9900
);

$data['hash'] = $client->createHash($data);

try {
    $result = $client->api($path, $method, $data);
} catch (VGS_Client_Exception $e) {
    echo $e->getMessage();
    var_dump($client->container);
}

Java SDK

// no.spid.api.security.SpidSecurityHelper
String signatureSecret = "your secret here";
SpidSecurityHelper securityHelper = new SpidSecurityHelper(signatureSecret);

HashMap<String,String> params = new HashMap<String, String>();
params.put("action", "sale");
params.put("productId", "10001");
params.put("userId", "123");
params.put("price", "9900");

securityHelper.addHash(params);

// Now use params to make a request

Help us improve

Did you spot an error? Or maybe you just have a suggestion for how we can improve? Leave a comment, or better yet, send us a pull request on GitHub to fix it (in-browser editing, only takes a moment).

History of this page

Comments/feedback

Do you have questions, or just want to contribute some newly gained insight? Want to share an example? Please leave a comment. SPiD reads and responds to every question. Additionally, your experience can help others using SPiD, and it can help us continuously improve our documentation.