Hello,
I am calling the relevant api for the Visa in-app push provisioning and sending the required parameters. But I am getting the error message as below
{"responseStatus":{"status":401,"code":"9159","severity":"ERROR","message":"Token Validation Failed","info":""}}
// x_pay_token generation code
String apiKey = "ORFVD5VTRV9VGG87NA0I21tOEhhcon6rn808NnxOWx8j8jbco";
String sharedSecret = "9VDoyOqTxnfIdkkZODpJ5}ZMQEXc$2lFJtawVulD";
String resourcePath = "vdp/helloworld";
String queryString = "apikey=" + apiKey;
String requestBody;
JSONObject jsonObject = new JSONObject();
jsonObject.put("deviceID",deviceID);
jsonObject.put("clientCustomerID",clientCustomerID);
requestBody = String.valueOf(jsonObject);
// This is the filnal x_pay_token
xPayToken = generateXpaytoken(resourcePath,queryString,requestBody,sharedSecret);
// Following code to generate the x_pay_token
public static String generateXpaytoken(String resourcePath, String queryString, String requestBody, String sharedSecret) throws SignatureException {
String timestamp = timeStamp();
String beforeHash = timestamp + resourcePath + queryString + requestBody;
String hash = hmacSha256Digest(beforeHash, sharedSecret);
return "xv2:" + timestamp + ":" + hash;
}
private static String timeStamp() {
return String.valueOf(System.currentTimeMillis() / 1000L);
}
private static String hmacSha256Digest(String data, String sharedSecret)
throws SignatureException {
return getDigest(sharedSecret, data);
}
private static String getDigest(String sharedSecret, String data) throws SignatureException {
try {
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(sharedSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
sha256HMAC.init(secretKey);
byte[] hashByte = sha256HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8));
String hashString = toHex(hashByte);
return hashString.toLowerCase();
} catch (Exception e) {
throw new SignatureException(e);
}
}
private static String toHex(byte[] bytes) {
BigInteger bi = new BigInteger(1, bytes);
return String.format("%0" + (bytes.length << 1) + "X", bi);
}
// Now the code to call the Visa in-app provisioning api
URL url = null;
try {
url = new URL("https://sandbox.api.visa.com/inapp/provisioning/cardData/googlePay?apikey=" + apiKey);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
assert url != null;
InputStream is = null;
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("x-pay-token", xPayToken);
con.addRequestProperty("deviceID",deviceID);
con.addRequestProperty("clientCustomerID",clientCustomerID);
con.setDoOutput(true);
Log.e("json", String.valueOf(jsonObject));
Log.e("Token",xPayToken);
Log.e("Hello","I have token");
Log.e("con is", String.valueOf(con));
con.connect();
String msg = con.getResponseMessage();
Log.e("Http Response message:",msg);
responseCode = con.getResponseCode();
Log.e("Http Status:", String.valueOf(responseCode));
BufferedReader in;
if (responseCode == 200) {
in = new BufferedReader(new InputStreamReader(con.getInputStream()));
} else {
in = new BufferedReader(new InputStreamReader(con.getErrorStream()));
Log.e("Hi","Api Key-Shared Secret (X-Pay-Token) test failed");
}
String response;
StringBuilder content = new StringBuilder();
while ((response = in.readLine()) != null) {
content.append(response);
}
in.close();
con.disconnect();
Log.e("Hi",content.toString());
Log.e("Hi","END Sample Code for Api Key-Shared Secret (X-Pay-Token)");
} catch (IOException | JSONException | SignatureException e) {
e.printStackTrace();
}
Can anyone tell me what I did wrong?
Thanks
Hi @Lakshmi1,
Visa In-App Provisioning APIs require Field Level Encryption (FLE). Can you please confirm that you are encrypting the data elements in the request payload?
Please check out this link for details: https://developer.visa.com/capabilities/visa-in-app-provisioning/docs-authentication