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
Hello Mark,
These are the common causes for “HMAC validation Failure”:
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;
}
}
}
}
}
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.