Hi,
I'm getting the following message back from the API.
message=HTTP error processing FirstData transaction, httpStatusCode=403, httpStatusText=Forbidden, responseBody={"code":"403", "message":"HMAC validation Failure"}
I assume, I have an error in my HMAC creation, but I cant seem to find it.
Could anyone help? Thanks!
private HttpHeaders createPayEezyHeaders(String contentType, String apiKey, String apiSecret, String merchantToken, String payload) throws Exception {
Map securityKeys = getSecurityKeys(apiKey, apiSecret, merchantToken, payload);
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", contentType);
headers.add("apikey", apiKey);
headers.add("token", merchantToken);
headers.add("nonce", (String) securityKeys.get(SecurityUtil.NONCE));
headers.add("timestamp", (String) securityKeys.get(SecurityUtil.TIMESTAMP));
headers.add("Authorization", (String) securityKeys.get(SecurityUtil.AUTHORIZE));
return headers;
}
private Map getSecurityKeys(String apiKey, String apiSecret, String merchantToken, String payLoad) throws Exception {
Map returnMap = new HashMap<>();
returnMap.put(SecurityUtil.NONCE, SecurityUtil.getNonce());
returnMap.put(SecurityUtil.APIKEY, apiKey);
returnMap.put(SecurityUtil.TIMESTAMP, Long.toString(System.currentTimeMillis()));
returnMap.put(SecurityUtil.TOKEN, merchantToken);
returnMap.put(SecurityUtil.APISECRET, apiSecret);
returnMap.put(SecurityUtil.PAYLOAD, payLoad);
try {
returnMap.put(SecurityUtil.AUTHORIZE, SecurityUtil.getMacValue(returnMap));
} catch (NoSuchAlgorithmException e) {
log.error("message=Error occurred while creating authorize header for first data transaction", e);
throw new RuntimeException("message=Error occurred while creating authorize header for first data transaction", e);
}
return returnMap;
}
public static String getMacValue(Map data) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
String apiSecret = data.get(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));
}
log.info("HMAC=" + buff.toString());
byte[] macHash = mac.doFinal(buff.toString().getBytes("UTF-8"));
String authorizeString = new String(Base64.encodeBase64(toHex(macHash)), "UTF-8");
return authorizeString;
}
public static byte[] toHex(byte[] arr) {
String hex = String.valueOf(Hex.encodeHex(arr));
return hex.getBytes();
}
HMAC Validation error can occur due to various reasons.
1) Incorrect API Key
2) Incorrect Merchant token
3) Incorrect HMAC authorization generated using API Secret.
4) Timestamp not in-sync with Payeezy servers.
Is this happening in sandbox or live environment? Review all the parameters and try to resolve this error. If you still have issues, let us know and we can setup a debug session to trace your transactions to find out which parameter is causing HMAC validation error.
Thanks,
Payeezy Team
I have checked all the parameters. They look good. Additionally I changes the nonce method to create a SHA1PRNG.
Still no luck.
Never mind, I found the issue.
It was the local encryption of the API secret.
All good now :)
could you explain what was wrong with the local encryption? I am seeing the same error when trying the sample code Junits.
That's great to hear.
Best Regards,
Payeezy Team
I am receiving the same error. The values look right from my side. I guess it could be 3) Incorrect HMAC authorization generated using API Secret or 4) Timestamp not in-sync with Payeezy servers, but how would I go about figuring out how to fix it?
To check if your server time is not off, compare with http://www.time.gov/.
Regards,
Payeezy team