3 posts / 0 new
Last post
markwinter4756
{"code":"403", "message":"HMAC validation Failure"}

Hi,
I have been exploring payeezy api from last three days. I am just making a simple http web request from a C# application. I have followed all the steps mentions and correctly verified each and everything. Below is the detail per item.

1) API Key :- I have verified my api key its correct.
2) API Secret :- It is also correct.
3) merchant token :- It is also verified.
4) Nonce :- I have created cryptographically strong random number as following.

RandomNumberGenerator rng = new RNGCryptoServiceProvider();
byte[] nonceData = new byte[18];
rng.GetBytes(nonceData);
string nonce = BitConverter.ToUInt64(nonceData,0).ToString();
5) Timestamp :- string timestamp = Convert.ToInt64(ts.TotalMilliseconds).ToString();
6) payload :-
{"merchant_ref":"Astonishing-Sale","transaction_type":"authorize","method":"credit_card","amount":"1299","currency_code":"USD","credit_card":{"type":"visa","cardholder_name":"John Smith","card_number":"4788250000028291","exp_date":"1020","cvv":"123"}}
7) Then I have created HMAC as following.

private string CreateAuthorization(string data, string secret)
{
// data is in following format.
// data = apiKey + nonce + timestamp + token + payload;
secret = secret ?? "";
using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret)))
{
byte[] hashdata = hmacsha256.ComputeHash(Encoding.UTF32.GetBytes(data));
return Convert.ToBase64String(hashdata);
}
}
8) Now I am getting hmac validation error. My generated hmac string is 64 bit while on your website under docs and sandbox its 86 bit.

Can you please assist me in this as I am stuck on this issue from last three days.
Thanks


rohitrajagopal3402
Re: {"code":"403", "message":"HMAC validation Failure"}

Hello Mark,

These are the common causes for “HMAC validation Failure”:

  1. API key and/or API secret are incorrect.
  2. Leading or trailing spaces in the API key, API secret, merchant token.
  3. Timestamp in the HTTP header is not in milliseconds.
  4. Timestamp in the HTTP header does not represent EPOCH time.
  5. Timestamp in the HTTP header is not within 5 minutes of our server time.
  6. System time is not accurate.

Here is a sample c# code to generate HMAC:

public byte[] CalculateHMAC(string data, string secret)
        {
            HMAC hmacSha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
            byte[] dataBytes = Encoding.UTF8.GetBytes(data);
            byte[] hmac2Hex = hmacSha256.ComputeHash(Encoding.UTF8.GetBytes(data));
         
            string hex = BitConverter.ToString(hmac2Hex);
            hex = hex.Replace("-","").ToLower();
            byte[] hexArray = Encoding.UTF8.GetBytes(hex);
            return hexArray;
        }
        
    protected void Button1_Click(object sender, EventArgs e)
    {                     
        string jsonString = "{ \"merchant_ref\": \"MVC Test\", \"transaction_type\": \"authorize\", \"method\": \"credit_card\", \"amount\": \"1299\", \"currency_code\": \"USD\", \"credit_card\": { \"type\": \"visa\", \"cardholder_name\": \"Test Name\", \"card_number\": \"4005519200000004\", \"exp_date\": \"1020\", \"cvv\": \"123\" } }";

        Random random = new Random();
        string nonce = (random.Next(0, 1000000)).ToString();

        DateTime date = DateTime.UtcNow;
        DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        TimeSpan span = (date - epoch);
        string time = span.TotalSeconds.ToString();
        
        string token = Request.Form["token"];//Merchant token
        string apiKey = Request.Form["apikey"];//apikey
        string apiSecret = Request.Form["apisecret"];//API secret
        string hashData = apiKey+nonce+time+token+jsonString;
        
        string base64Hash = Convert.ToBase64String(CalculateHMAC(hashData, apiSecret));
        
        string url = "https://api-cert.payeezy.com/v1/transactions";
       
        //begin HttpWebRequest
        HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);

        webRequest.Method = "POST";
        webRequest.Accept = "*/*";
        webRequest.Headers.Add("timestamp", time);
        webRequest.Headers.Add("nonce", nonce);
        webRequest.Headers.Add("token", token);
        webRequest.Headers.Add("apikey", apiKey);
        webRequest.Headers.Add("Authorization", base64Hash );
        webRequest.ContentLength = jsonString.Length;
        webRequest.ContentType = "application/json";

        StreamWriter writer = null;
        writer = new StreamWriter(webRequest.GetRequestStream());
        writer.Write(jsonString);
        writer.Close();

        string responseString;
        try
            {
                using(HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
                {
                    using (StreamReader responseStream = new StreamReader(webResponse.GetResponseStream()))
                    {
                        responseString = responseStream.ReadToEnd();
                        request_label.Text = "<h3>Request</h3><br />" + webRequest.Headers.ToString() + System.Web.HttpUtility.HtmlEncode(jsonString);
                        response_label.Text = "<h3>Response</h3><br />" + webResponse.Headers.ToString() + System.Web.HttpUtility.HtmlEncode(responseString);
                    }
                }
            }
        catch (WebException ex)
        {
            if (ex.Response != null) 
            {
                using (HttpWebResponse errorResponse = (HttpWebResponse)ex.Response) 
                {
                    using (StreamReader reader = new StreamReader(errorResponse.GetResponseStream())) 
                    {
                        string remoteEx = reader.ReadToEnd();
                        error.Text = remoteEx;
                    }
                }
            }           
        }
    }


ironplanetengin...
Re: {"code":"403", "message":"HMAC validation Failure"}

Hi,

I have setup SANDBOX environment to use Direct API. I have emailed support team multiple times about 403 validation failure.

Generated payload seems to have no issue because posting payload using https://developer.payeezy.com/payeezy-api/apis/post/transactions-3 is successful.

To debug HMAC issue, we tried copying nonce, timestamp and authorize string generated from https://developer.payeezy.com/payeezy-api/apis/post/transactions-3 in our code to test authorize transaction type. We have also hardcoded trans-armor token value to "2537446225198291". We got 500 response Code.

1 Apr 2016 16:53:54 INFO FirstAPIClientV2Helper - XXXX-XXX{"transacti
n_type":"authorize","method":"token","amount":"0","currency_code":"USD","token":{"token_type":"FDToken","token_data":{"type":"visa","cardholder_name":"John Smith","exp_date":"1030
,"value":"2537446225198291"}}}
1 Apr 2016 16:53:54 INFO FirstAPIClientV2Helper - MacHAsh:[-77, 3, -104, -126, -76, 58, -50, 52, -67, 65, 54, -23, -126, -62, -59, 3, 93, 127, -8, -41, -54, 31, -109, 18, 11, 74,
-114, -13, -25, 126, 114, -39]
1 Apr 2016 16:53:54 INFO FirstAPIClientV2Helper - Apache common value:b3039882b43ace34bd4136e982c2c5035d7ff8d7ca1f93120b4a8ef3e77e72d9
1 Apr 2016 16:53:54 INFO FirstAPIClientV2Helper - Authorize: OTc1ODJhMWE1YjQ4YjdkOGEzMTlmZTdmMjQ5YzcxZWI5ZWFhMTAyMjQyNDk0MWRkNTk0OGJjODdhZGQ0NGUwNg
1 Apr 2016 16:53:54 DEBUG RestTemplate - Created GET request for "https://api-cert.payeezy.com/v1/transactions"
1 Apr 2016 16:53:54 DEBUG RestTemplate - Setting request Accept header to [text/plain, application/json, application/*+json, text/plain, application/xml, application/json, */*, */
, */*]
1 Apr 2016 16:53:54 DEBUG RestTemplate - Writing [com.ironplanet.firstdata.util.TransactionRequest@41016c81] as "application/json" using [org.springframework.http.converter.json.M
ppingJacksonHttpMessageConverter@32ce932d]
1 Apr 2016 16:53:55 WARN RestTemplate - GET request for "https://api-cert.payeezy.com/v1/transactions" resulted in 500 (Internal Server Error); invoking error handler
1 Apr 2016 16:53:55 ERROR AddCreditCard - Failed to add a credit card
rg.springframework.web.client.HttpServerErrorException: 500 Internal Server Error
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponseError(RestTemplate.java:556)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:514)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:472)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:420)
at com.ironplanet.firstdata.FirstAPIClientV2Helper.doPrimaryTransactionObject(FirstAPIClientV2Helper.java:372)
at com.ironplanet.firstdata.FirstAPIClientV2Helper.postTokenTransaction(FirstAPIClientV2Helper.java:606)

We checked our server time, also verified no spaces in APIkey, secret and token.

Please help us to resolve this issue.