Skip to main content

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:

  • Axios — HTTP client
  • dotenv — environment variable loader
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).

warning

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.

tip

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