Setup HMAC Authentication in Node.js
This guide walks you through implementing HMAC authentication for the Mekari POS API using Node.js and npm.
Prerequisites
Install Dependencies
Initialize your project if you haven't already:
npm init -y
Install two dependencies:
npm install axios dotenv --save
Your package.json should now include:
{
"dependencies": {
"axios": "^0.24.0",
"dotenv": "^10.0.0"
}
}
Set Up Environment Variables
Create a .env file in your project root with your Mekari API credentials:
# .env
MEKARI_API_CLIENT_ID=YOUR_MEKARI_API_CLIENT_ID
MEKARI_API_CLIENT_SECRET=YOUR_MEKARI_CLIENT_SECRET
MEKARI_API_BASE_URL=https://api.mekari.com
MEKARI_POS_USER_ID=<A_USER_ID_FROM_GET_USERS>
Use https://sandbox-api.mekari.com as MEKARI_API_BASE_URL for the sandbox. MEKARI_POS_USER_ID is the staff user your requests act as (an id from GET /users).
Never commit credentials to version control. Add .env to your .gitignore file.
Generate the HMAC Signature
The signature is an HMAC-SHA256 hash of the request line and Date header, encoded in Base64. Node.js includes the crypto module natively — no extra packages are required. See HMAC Authentication for the full specification.
const crypto = require("crypto");
const datetime = new Date().toUTCString();
const requestLine =
"POST /v2/mekari-pos/v2/categories HTTP/1.1";
const payload = [`date: ${datetime}`, requestLine].join("\n");
const signature = crypto
.createHmac("SHA256", process.env.MEKARI_API_CLIENT_SECRET)
.update(payload)
.digest("base64");
Complete Implementation
Create a file called main.js with the full implementation:
const axios = require("axios");
const crypto = require("crypto");
require("dotenv").config();
/**
* Generate HMAC authentication headers.
*
* @param {string} method - HTTP method (GET, POST, PUT, DELETE)
* @param {string} path - Request path without the query string
* @returns {Object} Headers object with Authorization and Date
*/
function generateHeaders(method, path) {
const datetime = new Date().toUTCString();
const requestLine = `${method} ${path} HTTP/1.1`;
const payload = [`date: ${datetime}`, requestLine].join("\n");
const signature = crypto
.createHmac("SHA256", process.env.MEKARI_API_CLIENT_SECRET)
.update(payload)
.digest("base64");
return {
Accept: "application/json",
"Content-Type": "application/json",
Date: datetime,
Authorization: `hmac username="${process.env.MEKARI_API_CLIENT_ID}", algorithm="hmac-sha256", headers="date request-line", signature="${signature}"`,
};
}
// Configure the request
const method = "GET";
const path = "/v2/mekari-pos/v2/customers"; // sign the path only
const query = "?limit=50"; // any query works with the same signature
const options = {
method: method,
url: `${process.env.MEKARI_API_BASE_URL}${path}${query}`,
headers: generateHeaders(method, path),
};
// Send the request
axios(options)
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
console.log(error.request);
} else {
console.log("Error", error.message);
}
});
Run the Script
node main.js
If the credentials are valid, the API response is logged to the console. Otherwise, the Axios error handler prints the status code and error body for debugging.
Adapt the method, path, and query variables (and add a data body for write requests) to match the Mekari POS endpoint you are calling. Refer to the API reference for available endpoints. Write requests also need the X-User-ID and Idempotency-Key headers (see the header table).
Reference Repository
See the complete example code on GitHub: mekari-api-hmac-example-nodejs