Generate a Message Signature / Hash
Introduction
All requests to our payment integrations (whether via the API or hosted solutions) require the use of a hash, also referred to as a message signature. This makes use of not only your api key, but your api secret (also available in the portal) to add an extra layer of security to requests and prevent man-in-the-middle attacks.
The high-level idea is that for every request, you must:
- Combine your api key and some request data into a single string
- Hash the string using the HMAC SHA256 method and your secret key
- Add the hash to your request
The rest of this page goes into step-by-step detail on how to do this for each integration method.
Payments API
Message Signature Header
When calling the Payments API, Checkouts and Payment Links endpoints, this is the method that must be used; generating the hash and attaching it as the Message-Signature
header along with the Timestamp
and Client-Request-Id
headers.
For full detail on how to do this, our best resource is the following recipe:
Hosted Payment Page
hashExtended form parameter
When using the Hosted Payment Page, the fields used to generate and pass the has are slightly different to the header above.
The hash needs to be calculated using all of the request parameters in ascending order of the parameter names (parameter hashExtended). When you are using the embedded form, there is also an option where you do not need to know the card details (PAN, CVV and Expiry Date) for the hash calculation. This will be managed with a specific setting performed on your store.
The request parameters that are not specified in our solution can still be submitted in your request to the Gateway, but they must be excluded from the hash calculation. They will be ignored during processing and returned back in the response. Please contact your local support team if you want to enable this feature.
Creating the hash
Transaction request values used for the hash calculation:
Field | Example |
---|---|
chargetotal | 13.00 |
currency | 978 |
paymentMethod | M |
responseFailURL | https://mywebshop/response_failure.jsp |
responseSuccessURL | https://mywebshop/response_success.jsp |
sharedsecret | sharedsecret |
storename | 10123456789 |
timezone | Europe/Berlin |
transactionNotificationURL | https://mywebshop/transactionNotification |
txndatetime | 2022:04:17-17:32:41 |
txntype | sale |
Payment Method Options
Please refer to the Forms fields page in this documentation for the complete list of values
Step 1: The hashExtended
needs to be calculated using all request parameters in ascending order of the parameter names
Join the parameters’ values to one string with pipe separator (use only parameters’ values and not the parameters’ names).
let chargetotal = "13.00";
let currency = "978";
let paymentMethod = "M";
let responseFailURL = "https://mywebshop/response_failure.jsp";
let responseSuccessURL = "https://mywebshop/response_success.jsp";
let sharedsecret = "sharedsecret";
let storename = "10123456789";
let timezone = "Europe/Berlin";
let transactionNotificationURL = "https://mywebshop/transactionNotification";
let txndatetime = "2020:04:17-17:32:41";
let txntype = "sale";
let stringToExtendedHash = `${chargetotal}|${currency}|${paymentMethod}|${responseFailURL}|${responseSuccessURL}|${storename}|${timezone}|${transactionNotificationURL}|${txndatetime}|${txntype}`;
Note the corresponding hash string does not include sharedsecret
, which has to be used as the secret key for the HMAC instead.
Step 2: Pass the created string to the HMACSHA256
algorithm and using shared secret ('sharedsecret') as a key for calculating the hash value.
var hashExtended = CryptoJS.HmacSHA256(stringToExtendedHash, sharedsecret);
Step 3: Use the value returned by the HMACSHA256 algorithm and submit it to our Gateway in the given form.
<input type="hidden" name="hashExtended" value="8CVD62a88mwr/Nfc+t+CWB+XG0g5cqmSrN8JhFlQJVM="/>
Only HMAC algorithm (i.e.: HMACSHA256, HMACSHA384 or HMACSHA512) is supported for generating the extended request hash.
Examples
let chargetotal = "13.00";
let currency = "978";
let paymentMethod = "M";
let responseFailURL = "https://mywebshop/response_failure.jsp";
let responseSuccessURL = "https://mywebshop/response_success.jsp";
let sharedsecret = "sharedsecret";
let storename = "10123456789";
let timezone = "Europe/Berlin";
let transactionNotificationURL = "https://mywebshop/transactionNotification";
let txndatetime = "2020:04:17-17:32:41";
let txntype = "sale";
let stringToExtendedHash = `${chargetotal}|${currency}|${paymentMethod}|${responseFailURL}|${responseSuccessURL}|${storename}|${timezone}|${transactionNotificationURL}|${txndatetime}|${txntype}`;
var hashExtended = CryptoJS.HmacSHA256(stringToExtendedHash, sharedsecret);
<input type="hidden" name="hashExtended" value="8CVD62a88mwr/Nfc+t+CWB+XG0g5cqmSrN8JhFlQJVM="/>
<?php
// Timezeone needs to be set
date_default_timezone_set('Europe/Berlin');
$dateTime = date("Y:m:d-H:i:s");
function getDateTime() {
global $dateTime;
return $dateTime;
}
/*
Function that calculates the hash of the following parameters:
- Store Id
- Date/Time(see $dateTime above)
- chargetotal
- currency (numeric ISO value)
- shared secret
*/
function createExtendedHash($chargetotal, $currency) {
// Please change the store Id to your individual Store ID
$storeId = "10123456789";
// NOTE: Please DO NOT hardcode the secret in that script. For example read it from a database.
$sharedSecret = "sharedsecret";
$separator = "|";
$stringToHash = $storeId . $separator . getDateTime() . $separator . $chargetotal . $separator . $currency;
$hashSHA256 = CryptoJS.HmacSHA384(hashWithAllStrings, sharedSecret);
$hash = CryptoJS.enc.Base64.stringify($hashSHA256);
return $hash;
}
?>
<!-- google CryptoJS for HMAC -->
<script LANGUAGE=JScript RUNAT=Server src="script/cryptoJS/crypto-js.min.js"></script>
<script LANGUAGE=JScript RUNAT=Server src="script/cryptoJS/enc-base64.min.js"></script>
<script LANGUAGE=JScript RUNAT=Server>
var today = new Date();
var txndatetime = today.formatDate("Y:m:d-H:i:s");
/*
Function that calculates the hash of the following parameters:
- chargetotal
- currency
- paymentMethod
- responseFailURL
- responseSuccessURL
- sharedsecret
- storename
- timezone
- transactionNotificationURL
- txndatetime
- txntype
*/
function createExtendedHash(chargetotal, currency) {
// Please change the storename to your individual Store Name
var storename = "10123456789";
// NOTE: Please DO NOT hardcode the secret in that script. For example read it from a database.
var stringToExtendedHash = chargetotal|currency|paymentMethod|responseFailURL|responseSuccessURL|storename|timezone|transactionNotificationURL|txndatetime|txntype;
var hashHMACSHA256 = CryptoJS.HmacSHA256(stringToExtendedHash, sharedSecret);
var extendedhash = CryptoJS.enc.Base64.stringify(hashHMACSHA256);
Response.Write(extendedhash);
}
function getDateTime() {
Response.Write(txndatetime);
}
</script>
NEXO Acquirer API
A similar concept is applied to our NEXO Acquirer API.
Please refer to Nexo encryption and macing section for more information.
Updated 4 months ago