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).
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.
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