4 posts / 0 new
Last post
laxmibhardwaj17991
HMAC Validation Error

I am getting "HMAC Validation Error" while calling balance inquiry API of gift card . Same is working on my local but I When the same code is deployed on server hosted on CST timezone , it is not working. What can be the possible reason? Please give proper detailed answer.


christopherlord730
Re: HMAC Validation Error

You either have errant spaces in the credentials or the timestamp is not within 5 minutes of the current Unix Epoch timestamp. You can refer to the Docs & Sandbox sample for credit card payments and click the 'i' icon next to the 'generate HMAC' button in the expanded header parameters to ensure you're constructing the authorization header correctly.


laxmibhardwaj17991
Re: HMAC Validation Error

There is no errant spaces in the credentials and the timestamp is also within 5 minutes of the current Unix Epoch timestamp.
If its working on my local then it should work on server hosted on CST timezone too.
Below is the code used for encripting keys:

public static HttpsURLConnection createConnection(String api, String apiKey, String secretKey, String token, String payload) {
HttpsURLConnection con = null;
try {
URL url = new URL(api);
con = (HttpsURLConnection) url.openConnection();
Map encriptedKey = getSecurityKeys(apiKey, secretKey, token, payload);
Debug.log("encriptedKey....." + encriptedKey);
Iterator iter = encriptedKey.keySet().iterator();
while (iter.hasNext()) {
String key = iter.next();
if ("payload".equals(key) || "apisecret".equals(key))
continue;
con.setRequestProperty(key, encriptedKey.get(key));
}
con.setRequestMethod(RequestMethod.POST.name());
return con;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return con;
}

public static Map getSecurityKeys(String appId, String securedSecret, String token, String payLoad) throws Exception {

Map returnMap = new HashMap();
long nonce;
try {

nonce = Math.abs(SecureRandom.getInstance("SHA1PRNG").nextLong());
returnMap.put("nonce", Long.toString(nonce));
returnMap.put("apikey", appId);
returnMap.put("timestamp", Long.toString(System.currentTimeMillis()));
Debug.log("TIMESTAMP used in payeezy ::::::::::: " +Long.toString(System.currentTimeMillis()));
returnMap.put("token", token);
returnMap.put("apisecret", securedSecret);
returnMap.put("payload", payLoad);
returnMap.put("Authorization", getMacValue(returnMap));
return returnMap;

} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}

public static String getMacValue(Map data) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
String apiSecret = data.get("apisecret");
Debug.log("API_SECRET:{}" + apiSecret);
SecretKeySpec secret_key = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA256");
mac.init(secret_key);
StringBuilder buff = new StringBuilder();
buff.append(data.get("apikey")).append(data.get("nonce")).append(data.get("timestamp"));
if (data.get("token") != null)
buff.append(data.get("token"));
if (data.get("payload") != null)
buff.append(data.get("payload"));

Debug.log(buff.toString());
byte[] macHash = mac.doFinal(buff.toString().getBytes("UTF-8"));
Debug.log("MacHAsh:{}" + Arrays.toString(macHash));
String authorizeString = Base64.encodeBase64String(toHex(macHash));
Debug.log("Authorize: {}" + authorizeString);
return authorizeString;
}

public static byte[] toHex(byte[] arr) {
String hex = Hex.encodeHexString(arr);
//System.out.println("Apache common value:{}" + hex);
return hex.getBytes();
}

Let me know if there is any issue in above code.


christopherlord730
Re: HMAC Validation Error

I don't see issues with the code. If it functions in one environment correctly but fails in another than the issue lies with the server environment itself which we can't troubleshoot.