VTS X-Pay Token Troubleshooting Guide - Common Errors and Possible Resolutions
Written by Shruti Tandon and @Jitesh_Shah
Please find below the common errors/issues faced by developers while using X-Pay-Token in Visa Token Service (VTS) Use Cases. These steps will help in checking/making sure the X-Pay-Token is being Generated and Used in a correct manner.
#1 Error Scenario Details
{
"responseStatus": {
"status": 401,
"code": "9201",
"severity": "ERROR",
"message": "Token Validation Failed",
"info": ""
}
}
Possible Resolutions :
# 2 Error Scenario Details
{
"responseStatus": {
"status": 401,
"code": "9159",
"severity": "ERROR",
"message": "Token Validation Failed",
"info": ""
}
}
Possible Resolutions:
a. The resource path used in the generation of x pay token must not have “/” in the end. Please find below examples related to resource path.
Example :
b. The word “apiKey” used in queryString while generating x-pay-token is case sensitive and must be same as what is passed in request.
Example :
c. “?” must not be part of query string or resource path while generating x pay token
Example :
d. There must not be any space “ “, new line "\n" or “.” in the request payload or at the end as compared to the one used in creating the x-pay-token.
Example:
{"clientAppID":"appid1234","consumerEntryMode":"KEYENTERED","encPaymentInstrument":"eyJhbGciOiJBMjU2R0NNS1ciLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiUUhGTzAzSEhWMTNRN01LTTFYVzYxM2VIbEw3NndROVNtRy13R3VwWDNmaEQ3dkJaVSIsIml2IjoiUEVZSkQ5VVFfLTNOYzFieSIsInRhZyI6InRYSE5Ed2xla2ZZaGo2cDJ2S1dLbFEifQ.CaKqGn6vmgv8W6rZwSg9Gaz0IU8xI1jDlUsqAZogeKo.gMIF1v5eH8k82Tl1mks2Lh_FxOJepKD8DgDKjChG_-U.hTBNvI1yuzTQQSVg64WZnBwshbUdEAiS9AuMqWoUx5smhBOiBE2o8onz71iykkV_ZOXmM7BtJMxazgQtMueimcYUCM8KyxAjYQiyPGwfp80EcPH_eEG0O_TJueVRAV06KfxEMFvq02X4qHFD08me_54XLKnKd1MxN847gDzNrliLt0mlEFloWRKfBHBkJLBb_GDopdrScV0WvIF7hWXqmtNrhwqoOEBQHtEwtt4OJZgPeWcEnn_5dOgVBqZ__Vd1fL2QNOLWXPyT09Wgr9Bgj9fHWVmdSFmRbTvSctYxN_pf_QL2vr18VAPPsuraXeQ.iLw1SuzRLKhxjaBahPFv1A","locale" :"en_US","panSource":"MANUALLYENTERED"}
"{\"clientAppID\":\"appid1234\",\"consumerEntryMode\":\"KEYENTERED\",\"encPaymentInstrument\":\"eyJhbGciOiJBMjU2R0NNS1ciLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiUUhGTzAzSEhWMTNRN01LTTFYVzYxM2VIbEw3NndROVNtRy13R3VwWDNmaEQ3dkJaVSIsIml2IjoiUEVZSkQ5VVFfLTNOYzFieSIsInRhZyI6InRYSE5Ed2xla2ZZaGo2cDJ2S1dLbFEifQ.CaKqGn6vmgv8W6rZwSg9Gaz0IU8xI1jDlUsqAZogeKo.gMIF1v5eH8k82Tl1mks2Lh_FxOJepKD8DgDKjChG_-U.hTBNvI1yuzTQQSVg64WZnBwshbUdEAiS9AuMqWoUx5smhBOiBE2o8onz71iykkV_ZOXmM7BtJMxazgQtMueimcYUCM8KyxAjYQiyPGwfp80EcPH_eEG0O_TJueVRAV06KfxEMFvq02X4qHFD08me_54XLKnKd1MxN847gDzNrliLt0mlEFloWRKfBHBkJLBb_GDopdrScV0WvIF7hWXqmtNrhwqoOEBQHtEwtt4OJZgPeWcEnn_5dOgVBqZ__Vd1fL2QNOLWXPyT09Wgr9Bgj9fHWVmdSFmRbTvSctYxN_pf_QL2vr18VAPPsuraXeQ.iLw1SuzRLKhxjaBahPFv1A\",\"locale\":\"en_US\",\"panSource\":\"MANUALLYENTERED\"}"
#3 Error Scenario Details
{
"responseStatus": {
"status": 401,
"code": "9102",
"severity": "ERROR",
"message": "Token Validation Failed",
"info": ""
}
}
Possible Resolutions:
--Pseudo code
beforeHash = timeInSeconds + resourcePath + queryString;
create hash using HmacSHA256(beforeHash) with secretKey
xPayToken ="xv2:" + timeInSeconds + ":" + hash;
b. X-pay-token used in the request must not be reused or expired. The expiration period is set to 480 seconds.
#4 Error Scenario Details
{
"errorResponse": {
"status": 401,
"message": "Token Validation Failed",
"reason": "inputValidationError",
"details": [
{
"message": "Token validation failed since expected tokenValue for x-pay-token was not present",
"location": "x-pay-token"
},
{
"message": "Token validation failed since expected tokenValue for authorization was not present",
"location": "authorization"
}
]
}
}
Possible Resolution:
a. X pay token must be passed as part of header parameters. The header parameter name must be x-pay-token (case insensitive)
#5 Error Scenario Details
{
"responseStatus": {
"status": 401,
"code": "9101",
"severity": "ERROR",
"message": "Token Validation Failed",
"info": ""
}
}
Possible Resolution:
a. X pay token must be created in below format:
"xv2:" + timestamp + ":" + HMAC-SHA-256((shared -secret +) (timestamp + Resource path + query string + entity body).
Solved! Go to Solution
Hey @Jitesh_Shah,
Thanks for sharing this with us, it's really helpful.
@fangyang - can you share the full payload of both request and response you are testing?
@Jitesh_Shah or @shrtando - thoughts?
Hi
I am getting 9159 code for this flex token: "https://sandbox.api.visa.com/cybersource/payments/flex/v1/keys?" + queryString.
Please assist as i checked all points you mentioned
Error Response = {"responseStatus":{"status":401,"code":"9159","severity":"ERROR","message":"Token Validation Failed","info":""}}
String resourcePath = "payments/flex/v1/keys";
String queryString = "apikey=" + apiKey;
String requestBody = "{\"encryptionType\":\"RsaOaep256\"}";
url = new URL("https://sandbox.api.visa.com/cybersource/payments/flex/v1/keys?" + queryString);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
con.setRequestProperty("Accept", "application/json,application/octet-stream");
con.setRequestMethod("POST");
xPayToken = generateXpaytoken(resourcePath, queryString, requestBody, sharedSecret);
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);
String token = "xv2:" + timestamp + ":" + hash;
return token;
}
Hi @smol987 - Cybersource payments is no longer available of Visa Developer - so the only way to properly query the Cybersource payments sandbox is to create a merchant account on their portal. Sorry for the inconvenience - let me know if you have any other questions.
Hi @shrtando
Thank you for the error code and details during x-pay-token.
During hmacSHA256Digest String generation from the shared secret, for any illegalStateException or InvalidKeyExcpetion, a SignatureException is thrown back to the xPayToken method.
The question is, how is the SignatureException handled during generation of x-pay-token?
--Sample code:
public static String generateXpaytoken(String resourcePath, String queryString, String requestBody,
String sharedSecret) {
String timestamp = timeStamp();
String token = "";
try {
String beforeHash = timestamp + resourcePath + queryString + requestBody;
String hash = hmacSha256Digest(beforeHash, sharedSecret);
token = "xv2:" + timestamp + ":" + hash;
} catch (Exception signExp) {
logger.error("x-pay-token generation failed" + signExp.getMessage());
}
return token;
}
private static String hmacSha256Digest(String data, String sharedSecret) throws SignatureException {
return getDigest("HmacSHA256", sharedSecret, data, true);
}
private static String getDigest(String algorithm, String sharedSecret, String data, boolean toLower)
throws SignatureException {
try {
Mac sha256HMAC = Mac.getInstance(algorithm);
SecretKeySpec secretKey = new SecretKeySpec(sharedSecret.getBytes(UTF_8), algorithm);
sha256HMAC.init(secretKey);
byte[] hashByte = sha256HMAC.doFinal(data.getBytes(UTF_8));
String hashString = toHex(hashByte);
return toLower ? hashString.toLowerCase() : hashString;
} catch (Exception e) {
throw new SignatureException(e);
}
}
Thank You
Paul
hi, I'm new to this issue I did all ur recommendations .. I still have the same error message
my question is the Resource Path will be :vts/provisionedTokens/{vProvisionedTokenID}
or this param is optional vProvisionedTokenID and if I don't have it the resource path will be just "vts/provisionedTokens"