Authentication

Authentication of client requests in UniPayment API is accomplished through the use of the HMAC mechanism. To ensure proper authentication, the HMAC signature must be included in the Authorization header of any request sent from your backend server.

For security purposes, API requests to private resources must include proper authentication or they will fail. Additionally, it's essential to use HTTPS when making any API requests to ensure secure communication between the client and server.

HMAC signatures

First, the client must create a string (MAC - Message Authentication Code) that includes all relevant request data. Typically, this string will contain the following parameters:

  • Client Id
  • HTTP Method
  • Request URI
  • Request Timestamp
  • Nonce
  • Base 64 string representation of the request payload (request body)

Note:

To avoid any potential time zone discrepancies between the client and server, it's necessary to calculate the Request Timestamp value using the UNIX time format (number of seconds since Jan. 1st 1970).

The Nonce is a random number or string which is used only once per request. Here we are going to use GUID to create Nonce.

Once the string is generated by combining all the parameters, then it is the responsibility of the client to generate a HASH (unique signature) of the above string by using SHA256. The important thing here you need to remember is that while generating the unique signature (hash), you need to use the Client Secret which was initially generated when Open Client is created.

Once the unique signature (hash) is generated by the client, then the client needs to send that signature (hash) in the request header using a custom scheme such as “hmac” in Authorization header.

The data in the header will contain the Client Id, the Signature, the Nonce and the Timestamp separated by a colon ‘:’. The format for the Authorization header should be as shown below:

📘

Header fromat

[Authorization: hmac ClientId:Signature:Nonce:Timestamp]

Code Example

static string Sign(string clientId, string clientSecret, string requestHttpMethod, string requestUri, ulong requestTimeStamp, string nonce, string requestContentBase64String)
{
  var signatureRawData = $"{clientId}{requestHttpMethod}{requestUri}{requestTimeStamp}{nonce}{requestContentBase64String}";

  var secretBytes = Encoding.UTF8.GetBytes(clientSecret);
  var signature = Encoding.UTF8.GetBytes(signatureRawData);

  using (var hmac = new HMACSHA256(secretBytes))
  {
    var signatureBytes = hmac.ComputeHash(signature);
    var requestSignatureBase64String = Convert.ToBase64String(signatureBytes);

    // Setting the values in the Authorization header using custom scheme (Hmac)
    return $"{clientId}:{requestSignatureBase64String}:{nonce}:{requestTimeStamp}";
  }
}
def sign_request(self, client_id, client_secret, request_http_method, url, query_params, request_body=None):
        """Create the HMAC SHA-256 Signatute
        :param string: client_id.
        :param string: client_secret.
        :param string: request_http_method.
        :param string: query_params.
        :param string: request_body.
        :return: hmac.
        """
        uri = url
        if query_params is not None:
            uri += '?' + urlencode(query_params)

        uri = quote(uri.lower(), safe='')

        request_body_based64 = ''
        if request_body is not None:
            request_body_json = json.dumps(request_body)
            md5_hash = md5(request_body_json.encode('utf-8')).digest()
            request_body_based64 = b64encode(md5_hash).decode('utf-8')

        nonce = uuid.uuid4().hex
        request_timestamp = int(time())

        raw_data = '{}{}{}{}{}{}'.format(client_id, request_http_method, uri, request_timestamp, nonce,
                                         request_body_based64)
        signature = hmac.new(client_secret.encode('utf-8'), msg=raw_data.encode('utf-8'), digestmod=hashlib.sha256).digest()
        return '{}:{}:{}:{}'.format(client_id, b64encode(signature).decode('utf-8'), nonce, request_timestamp)
public static String sign(String clientId, String clientSecret, String requestHttpMethod, String requestUri, long requestTimeStamp, String nonce, String requestContentBase64String) {
        String signatureRawData = clientId + requestHttpMethod + requestUri + requestTimeStamp + nonce + requestContentBase64String;
        byte[] hmac = new HmacUtils(HmacAlgorithms.HMAC_SHA_256, clientSecret.getBytes(StandardCharsets.UTF_8)).hmac(signatureRawData);
        String requestSignatureBase64String = Base64.encodeBase64String(hmac);
        return clientId + ":" + requestSignatureBase64String + ":" + nonce + ":" + requestTimeStamp;
    }

See also

HMAC authorization Web API