Node.js signature generation code example
/*
This is example to check signature creation, you can run this file directly in the Node.js runtime environment
*/
const tweetnacl = require('tweetnacl');
const util = require('tweetnacl-util');
const fromUint8ArrayToHexString = uArray => uArray.reduce((acc, el) => acc + el.toString(16).padStart(2, '0'), '');
const fromHexStringToUint8Array = hexString => new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
const concatTypedArray = arrays => {
const totalLength = arrays.reduce((acc, value) => acc + value.length, 0);
const result = new Uint8Array(totalLength);
let length = 0;
for(const array of arrays) {
result.set(array, length);
length += array.length;
}
return result;
};
const merchantId = '944bd5ba-fba4-4797-aef6-4fadb87b1ca7';
const merchantPrivateKey = 'ee589f62c0c6eb995a790a966afb20a6317ad4eb4eb5eda4656ee84335a88872';
const body = {
merchantUuid: merchantId,
orderId: 'LOCALHOST-SX4W-rXtU-hqVR', // set your orderId, expiration time and others params
orderExpireAt: 1655369118558,
invoiceCurrency: 'EUR',
type: 'DRAFT',
totalInvoiceAmount: 10,
items: [{name: 'Service'}]
};
const hex1 = 'd3e0253e978720ba494c9223044a66a887daa57d3457445b07870ff68bf7a4c7d29fc76b89a1f81c957c15d374f4394f4dcfa879945ebadf01e408afa9ec7592';
const hex2 = 'd9080f3557762de9d87fe9238947b9fcf2766896f27e208fad9630cae385bacb8aa7b78d792d84c808f3a867a799f162c9e89b2c1f021ec2f00ad0f889886adf';
const prefix = fromHexStringToUint8Array(hex1);
const postfix = fromHexStringToUint8Array(hex2);
/*
use random generation
const prefix = tweetnacl.randomBytes(64);
const postfix = tweetnacl.randomBytes(64);
hex1 and hex2 used only for stable signature reproduction
*/
const bodyUintArray = util.decodeUTF8(JSON.stringify(body));
const message = concatTypedArray([prefix, bodyUintArray, postfix]);
const privateKey = fromHexStringToUint8Array(merchantPrivateKey);
const secretKey = tweetnacl.sign.keyPair.fromSeed(privateKey).secretKey;
const NaCl_PREFIX = fromUint8ArrayToHexString(prefix);
const NaCl_POSTFIX = fromUint8ArrayToHexString(postfix);
const NaCl_SIGNATURE = fromUint8ArrayToHexString(tweetnacl.sign.detached(message, secretKey));
const headers = {
NaClSignature_USER_ID: merchantId,
NaClSignature_PREFIX: NaCl_PREFIX,
NaClSignature_POSTFIX: NaCl_POSTFIX,
NaClSignature_SIGNATURE: NaCl_SIGNATURE,
'Content-Type': 'application/json',
};
console.log(headers);
/*
For this dataset headers is:
{
NaClSignature_USER_ID: '944bd5ba-fba4-4797-aef6-4fadb87b1ca7',
NaClSignature_PREFIX: 'd3e0253e978720ba494c9223044a66a887daa57d3457445b07870ff68bf7a4c7d29fc76b89a1f81c957c15d374f4394f4dcfa879945ebadf01e408afa9ec7592',
NaClSignature_POSTFIX: 'd9080f3557762de9d87fe9238947b9fcf2766896f27e208fad9630cae385bacb8aa7b78d792d84c808f3a867a799f162c9e89b2c1f021ec2f00ad0f889886adf',
NaClSignature_SIGNATURE: '55400548e8fbdbea5970f3469a7fd5270459f14460f703622f2c57741fbdee7a21f90fc98e5a64a332301182541a2ebe346c12115d66ed157650d16bd1c82d0c',
Content-Type: 'application/json'
}
*/
PHP signature generation code example
$merchantId = '944bd5ba-fba4-4797-aef6-4fadb87b1ca7';
$merchantPrivateKey = 'ee589f62c0c6eb995a790a966afb20a6317ad4eb4eb5eda4656ee84335a88872';
$body = [
'merchantUuid' => $merchantId,
'orderId' => 'LOCALHOST-SX4W-rXtU-hqVR', // set your orderId, expiration time and others params
'orderExpireAt' => 1655369118558,
'invoiceCurrency' => 'EUR',
'type' => 'DRAFT',
'totalInvoiceAmount' => 10,
'items' => [['name' => 'Service']]
];
function getRandomBytes(int $length)
{
return implode(array_map(function () {
return dechex(mt_rand(0, 15));
}, array_fill(0, $length, null)));
}
$prefix = 'd3e0253e978720ba494c9223044a66a887daa57d3457445b07870ff68bf7a4c7d29fc76b89a1f81c957c15d374f4394f4dcfa879945ebadf01e408afa9ec7592';
$postfix = 'd9080f3557762de9d87fe9238947b9fcf2766896f27e208fad9630cae385bacb8aa7b78d792d84c808f3a867a799f162c9e89b2c1f021ec2f00ad0f889886adf';
/*
$prefix and $postfix used only for stable signature reproduction
use random generation
$prefix = getRandomBytes(128);
$postfix = getRandomBytes(128);
*/
$message = sprintf('%s%s%s', $prefix, bin2hex(json_encode($body)), $postfix);
$keyPair = sodium_crypto_sign_seed_keypair(hex2bin($merchantPrivateKey));
$privateKey = sodium_crypto_sign_secretkey($keyPair);
$signature = bin2hex(sodium_crypto_sign_detached(hex2bin($message), $privateKey));
$headers = [
'NaClSignature_USER_ID' => $merchantId,
'NaClSignature_PREFIX' => $prefix,
'NaClSignature_POSTFIX' => $postfix,
'NaClSignature_SIGNATURE' => $signature,
'Content-Type' => 'application/json',
];
print_r($headers);
/*
For this dataset headers is:
Array
(
[NaClSignature_USER_ID] => 944bd5ba-fba4-4797-aef6-4fadb87b1ca7
[NaClSignature_PREFIX] => d3e0253e978720ba494c9223044a66a887daa57d3457445b07870ff68bf7a4c7d29fc76b89a1f81c957c15d374f4394f4dcfa879945ebadf01e408afa9ec7592
[NaClSignature_POSTFIX] => d9080f3557762de9d87fe9238947b9fcf2766896f27e208fad9630cae385bacb8aa7b78d792d84c808f3a867a799f162c9e89b2c1f021ec2f00ad0f889886adf
[NaClSignature_SIGNATURE] => 55400548e8fbdbea5970f3469a7fd5270459f14460f703622f2c57741fbdee7a21f90fc98e5a64a332301182541a2ebe346c12115d66ed157650d16bd1c82d0c
[Content-Type] => application/json
)
*/