Skip to main content

Setup HMAC Authentication in Ruby

This guide walks you through implementing HMAC authentication for the Mekari POS API using Ruby and Bundler.

Prerequisites​

Install Dependencies​

Create a Gemfile in your working directory if you don't have one:

source "https://rubygems.org"

git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }

Add two dependencies:

# Gemfile
gem 'faraday'
gem 'dotenv'

Install the dependencies:

bundle install

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. Ruby includes openssl and base64 in the standard library — no extra gems are required for signature generation. See HMAC Authentication for the full specification.

require 'time'
require 'base64'
require 'openssl'

datetime = Time.now.httpdate
request_line = "POST /v2/mekari-pos/v2/categories HTTP/1.1"
payload = ["date: #{datetime}", request_line].join("\n")
digest = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), ENV['MEKARI_API_CLIENT_SECRET'], payload)
signature = Base64.strict_encode64(digest)

Complete Implementation​

Create a file called main.rb with the full implementation:

require 'time'
require 'base64'
require 'openssl'
require 'faraday'
require 'dotenv'

Dotenv.load

# Generate HMAC authentication headers.
#
# @param method [String] HTTP method (GET, POST, PUT, DELETE)
# @param path [String] Request path without the query string
# @return [Hash<String, String>]
def generate_headers(method, path)
datetime = Time.now.httpdate
request_line = "#{method} #{path} HTTP/1.1"
payload = ["date: #{datetime}", request_line].join("\n")
digest = OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), ENV['MEKARI_API_CLIENT_SECRET'], payload)
signature = Base64.strict_encode64(digest)

{
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Date' => datetime,
'Authorization' => "hmac username=\"#{ENV['MEKARI_API_CLIENT_ID']}\", algorithm=\"hmac-sha256\", headers=\"date request-line\", signature=\"#{signature}\""
}
end

# Configure the request
method = 'GET'
path = '/v2/mekari-pos/v2/customers' # sign the path only
query = { limit: 50 } # any query works with the same signature
request_headers = generate_headers(method, path)

# Send the request
conn = Faraday.new(url: ENV['MEKARI_API_BASE_URL']) do |faraday|
faraday.response :logger
end

response = conn.get(path, query, request_headers)

puts "Status: #{response.status}"
puts "Body: #{response.body}"

Run the Script​

ruby main.rb

If the credentials and request are valid, the API response status and body are printed. Faraday's logger middleware also logs the full request and response for debugging.

tip

Adapt the method, path, and query (and add a request 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-ruby