VTS X-Pay-Token Troubleshooting Guide

Highlighted
Visa Employee

VTS X-Pay-Token Troubleshooting Guide

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 :

  1. APIKEY used must be environment specific. Production API Key and shared secret must not be used to generate x pay token in Sandbox environment.
  2. API Key and Shared Secret used for creation of X Pay Token must be of type “Inbound” or “Default”.
  3. The API Key/Shared Secret used for X Pay Token Generation must be present under Credentials tab in VDP.  

 

# 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 :

  • API - Get Token status request
  • Sandbox Path- https://cert.api.visa.com/vts/provisionedTokens/ {vProvisionedTokenID}?apiKey=key
  • Correct Resource Path - vts/provisionedTokens/{vProvisionedTokenID}
  • Incorrect Resource Path - vts/provisionedTokens/{vProvisionedTokenID}/

 

bThe 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 :

 

  • Correct QueryString- apikey={key}&async=false
  • Incorrect QueryString- ?apikey={key}&async=false

 

  • Correct Resource Path- /vts/provisionedTokens/{vProvisionedTokenID}
  • Incorrect Resource Path- vts/provisionedTokens/{vProvisionedTokenID}?

 

  • Sample before hash: {timestamp}vts/provisionedTokens/{vProvisionedTokenID}apikey={key}

 

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:

  • Payload used in Enroll Pan Request

 

{"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"}

 

 

  •  Pay load used while creating X pay Token

 

 

"{\"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:

 

  1. Timestamp is the current timestamp in UTC (in seconds) and must not be hardcoded. Timestamp in x pay token (last step) and used while generating x pay token must be same. 

--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).

 

8 REPLIES 8
Highlighted
Visa Employee

VTS X-Pay-Token Troubleshooting Guide

Hope this helps - please let us know if you run into any issues and you need our help!

 

 

Highlighted
Visa Dev Moderator

Re: VTS X-Pay-Token Troubleshooting Guide

Hey @Jitesh_Shah,

 

Thanks for sharing this with us, it's really helpful.

 



Was your question answered? Don't forget to click on "Accept as Solution" to help other devs find the answer to the same question.

Thanks,
Diana

Highlighted
Regular Visitor

Re: VTS X-Pay-Token Troubleshooting Guide

Using a Token that's generated by Java code that doesn't go through the resource path that you've tried and that doesn't go through

Highlighted
Community Manager

Re: VTS X-Pay-Token Troubleshooting Guide

@fangyang - can you share the full payload of both request and response you are testing?

 

@Jitesh_Shah or @shrtando - thoughts?




Was your question answered? Don't forget to click on "Accept as Solution" to help other devs find the answer to the same question.
Highlighted
Visa Employee

Re: VTS X-Pay-Token Troubleshooting Guide

Please share us the resource path you are using along with payload's and also let us know the error.

Helper

Re: VTS X-Pay-Token Troubleshooting Guide

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;
}

Highlighted
Community Manager

Re: VTS X-Pay-Token Troubleshooting Guide

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. 

 

 




Was your question answered? Don't forget to click on "Accept as Solution" to help other devs find the answer to the same question.
Highlighted
Regular Contributor

Re: VTS X-Pay-Token Troubleshooting Guide

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