2. Request Signing
Request Signing with HMAC
To guarantee the security and authenticity of requests to our API, we use HMAC (Hash-based Message Authentication Code) together with a private key that will be provided to you.
Suggested Code
We recommend using something similar to the following code to guide you when signing requests:
const crypto = require("crypto");
const privateKey = process.env.PRIVATE_KEY;
const signRequest = ({ apiPath, body, params }) => {
const nonce = Date.now().toString();
let message = "";
if (body) {
message = `${JSON.stringify(body)}${nonce}`;
} else if (apiPath && params) {
const stringParams = Object.keys(params).reduce((acc, key) => {
if (params[key]) {
acc[key] = String(params[key]);
}
return acc;
}, {});
const searchParams = new URLSearchParams(stringParams);
const queryString = searchParams.toString();
const apiPathMessage = `${apiPath}?${queryString}`;
message = `${apiPathMessage}${nonce}`;
}
const hash = crypto.createHash("sha256");
hash.update(message, "utf8");
const messageDigest = hash.digest();
const sign = crypto.createSign("SHA256");
sign.update(messageDigest);
sign.end();
const signature = sign.sign(privateKey, "base64");
return { signature, nonce };
};
module.exports = { signRequest };
The way a request is signed depends on the request type:
- Requests with a body (POST, PATCH, PUT): Sign the body content together with a
nonce
. - Requests with query parameters (GET, DELETE): Sign the
path
, thequeryParams
, and thenonce
.
Example Request to Create a Quote (POST)
When creating a quote, the signature is generated using the request body and a nonce
to ensure the request is secure.
Steps to Sign a POST Request
- Generate a
nonce
: A unique value based on a timestamp. - Create the message: Concatenate the request
body
with thenonce
. - Generate the signature: Use your private key to create an HMAC signature of the message.
Message for POST: body + nonce
Example POST Request to Create a Quote
POST /quotation
Host: baseUrl
nonce: 1657891234567
signature: <generated_signature>
Content-Type: application/json
{
"sourceCountry": "US",
"sourceCurrency": "USD",
"targetCountry": "VE",
"targetCurrency": "VES",
"amount": 1000,
"payoutType": "BANK_TRANSFER",
"amountType": "SOURCE"
}
In this example, the message to sign would be:
{"sourceCountry":"US","sourceCurrency":"USD","targetCountry":"VE","targetCurrency":"VES","amount":1000,"payoutType":"BANK_TRANSFER","amountType":"SOURCE"}1657891234567
Where the request body is concatenated with the nonce
to create the message to sign.
Example Request to Get a Quote by ID (GET)
For GET requests, such as retrieving a specific quote by its ID, the path
and nonce
are signed.
Steps to Sign a GET Request
- Generate a
nonce
: Use a unique timestamp for each request. - Create the message: Concatenate:
- The request
path
- The
?
indicator (always, even if there are no query parameters) - The
queryParams
(if any) - The
nonce
.
- The request
- Generate the signature: Sign the message using your private key.
Message for GET: path + `?` + queryParams + nonce
Example GET Request to Get a Quote by ID
GET /quotation/12345
Host: baseUrl
nonce: 1657891234567
signature: <generated_signature>
In this example, the message to sign would be:
/quotation/12345?1657891234567
Where /quotation/12345
is the request path
, ?
is the query params indicator, and 1657891234567
is the nonce
.
Example GET Request with Query Params
GET /balance?currency=USD&date=2024-10-01
Host: baseUrl
nonce: 1657891234567
signature: <generated_signature>
In this example, the message to sign would be:
/balance?currency=USD&date=2024-10-011657891234567
Where /balance
is the path
, ?
is the query params indicator, currency=USD&date=2024-10-01
are the query params in alphabetical order, and 1657891234567
is the nonce
.
Important:
The query parameters (queryParams
) must be in alphabetical order to ensure the signature is consistent and valid. This means that if you have multiple parameters, they must be sorted alphabetically before generating the signature.