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.
HMAC authentication is used in two scenarios:
- A registered Trusted Third Party (TPP) application. TPP registrations are only available in rare circumstances and require the TPP to perform Strong Customer Authentication (SCA). Please contact [email protected] for more information. See HMAC authentication
- A merchant token that has opted in by selecting an HMAC algorithm during token creation. See below.
Ib both cases a secret key is issued and must be used to generate an HMAC signature for each request sent to the NoFrixion API.
HMAC Signing with a Merchant Token
WIth a Merchant Token there is NO need to specify the Merchant ID in the HMAC headers. Each Merchant Token is always tied to a single Merchant and the Merchant ID is implicit.
- Token Id: This ID of the merchant token. It can be found on the portal tokens page.
- Secret key: This is provided when a Merchant Token is created with an HMAC algorithm specified.
HTTP Request Headers required for authentication
Request header | Description |
---|---|
Date | Date 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-key | A value unique to each request such as a Guid. |
Authorization | This should be of type Example:
|
Generating the HMAC signature and request headers
using System.Net;
using System.Security.Cryptography;
using System.Text;
const string authorizationHeaderName = "Authorization";
const string dateHeaderName = "Date";
const string idempotentHeaderName = "idempotency-key";
var tokenId = Guid.NewGuid().ToString();
var idempotencyKey = Guid.NewGuid().ToString();
var secret = "some secret";
var date = DateTime.UtcNow;
var headers = GetAppHMACHeaders(tokenId,
idempotencyKey,
secret,
date);
foreach (var header in headers)
{
Console.WriteLine($"{header.Key}: {header.Value}");
}
static Dictionary<string, string> GetAppHMACHeaders(string tokenId,
string idempotencyKey,
string secret,
DateTime date)
{
var signature = GenerateSignature(idempotencyKey, date, secret);
var headers = new Dictionary<string, string>
{
{authorizationHeaderName, GenerateAppAuthHeaderContent(tokenId, signature)},
{dateHeaderName, date.ToString("R")},
{idempotentHeaderName, idempotencyKey}
};
return headers;
}
static string GenerateAppAuthHeaderContent(string tokenId, string signature)
{
return $"Signature tokenId=\"{tokenId}\",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));
}
/*
This script generates a valid Authorization header with a HMAC signature using CryptoJS
*/
const { v4: uuidv4 } = require('uuid');
const tokenId = '<Your merhcant token 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 tokenId="${appId}",headers="date idempotency-key",signature="${signature}"`
const authHeaders = [
`Date: ${date}`,
`idempotency-key: ${idempotencyKey}`,
signatureHeader
]