HMAC authentication

You can authenticate HTTP requests by using the HMAC-SHA256 authentication scheme. (HMAC refers to hash-based message authentication code.) These requests must be transmitted over TLS.

To use HMAC authentication you must be registered by NoFrixion as a third party application. Please contact support for more information.

Once registered you will be provided with a secret key that you will use to generate a HMAC signature.


Pre-requisites

  1. Merchant ID: This is the ID of the merchant that was created for you when you registered on the NoFrixion portal. You can get this ID by logging into NoFrixion portal and navigating to profile. You will see the list of merchants with their IDs under "Merchants". **
  2. Application Id: This will be provided to You when your third party application has been registered.
  3. Secret key: This will be provided to You when your third party application has been registered.

HTTP Request Headers required for authentication

Request headerDescription
DateDate and time at which the request was originated. It can't be more than 5 minutes off from the current Coordinated Universal Time (Greenwich Mean Time). The value is an HTTP-date in the RFC1123 date format. E.g. Fri, 01 Mar 2019 15:00:00 GMT.
idempotency-keyA value unique to each request such as a Guid.
x-nfx-merchantidThe id of the NoFrixion merchant the request is for.
AuthorizationThis should be of type Signatureand contain your appId and the signature generated using your secret key. Described below.

Example:

Authorization: Signature appId="ab70963f-45d0-4ca9-955b-4576e6ca91",headers="date idempotency-key",signature="Fh7LE0z%2Bsss6bbFhb99uTIAvPpj3bH89aI7%2FZ4SZYE0%3D"

Generating the HMAC signature and request headers

/*
    This script generates a valid Authorization header with a HMAC signature using CryptoJS
*/
const { v4: uuidv4 } = require('uuid');

const appId = '<Your application id>'

const merchantId = '<Your merchant id>'

const secret = '<Your secret key>'

// Generate a unique idempotency key
const idempotencyKey = uuidv4();

// The date should be in RFC1123 format. E.g. Tue, 30 Apr 2024 07:58:09 GMT
const date = new Date().toUTCString()

let messageToEncrypt = `date: ${date}`
messageToEncrypt += '\n'
messageToEncrypt += `idempotency-key: ${idempotencyKey}`

// Generate the signature using the messageToEncrypt format above
// Should be Base64 encoded and then URI encoded
var signature = encodeURIComponent(CryptoJS.HmacSHA256(messageToEncrypt, secret).toString(CryptoJS.enc.Base64));

// The authorzation header including the signature
let signatureHeader = `Authorization: Signature appId="${appId}",headers="date idempotency-key",signature="${signature}"`

const authHeaders = [
    `Date: ${date}`,
    `idempotency-key: ${idempotencyKey}`,
    `x-nfx-merchantid: ${merchantId}`,
    signatureHeader
]

using System.Net;
using System.Security.Cryptography;
using System.Text;

const string authorizationHeaderName = "Authorization";
const string dateHeaderName = "Date";
const string merchantIdHeaderName = "x-nfx-merchantid";
const string idempotentHeaderName = "idempotency-key";

var appId = Guid.NewGuid().ToString();
var idempotencyKey = Guid.NewGuid().ToString();
var secret = "some secret";
var date = DateTime.UtcNow;
var merchantId = Guid.NewGuid();

var headers = GetAppHMACHeaders(appId, 
    idempotencyKey, 
    secret, 
    date, 
    merchantId);

foreach (var header in headers)
{
    Console.WriteLine($"{header.Key}: {header.Value}");
}

static Dictionary<string, string> GetAppHMACHeaders(string appId,
    string idempotencyKey,
    string secret,
    DateTime date,
    Guid merchantId)
{
    var signature = GenerateSignature(idempotencyKey, date, secret);

    var headers = new Dictionary<string, string>
    {
        {authorizationHeaderName, GenerateAppAuthHeaderContent(appId, signature)},
        {dateHeaderName, date.ToString("R")},
        {idempotentHeaderName, idempotencyKey},
        {merchantIdHeaderName, merchantId.ToString()},
    };

    return headers;
}

static string GenerateAppAuthHeaderContent(string appId, string signature)
{
    return $"Signature appId=\"{appId}\",headers=\"date {idempotentHeaderName}\",signature=\"{signature}\"";
}

static string GenerateSignature(string idempotencyKey, DateTime date, string secret)
{
    return HashAndEncode256($"date: {date:R}\nidempotency-key: {idempotencyKey}", secret) ;
}

static string HashAndEncode256(string message, string secret)
{
    var ascii = Encoding.ASCII;
        
    var hmac = new HMACSHA256(ascii.GetBytes(secret));
    hmac.Initialize();

    var messageBuffer = ascii.GetBytes(message);
    var hash = hmac.ComputeHash(messageBuffer);

    return WebUtility.UrlEncode(Convert.ToBase64String(hash));
}