Hi,
I’m Chrystal Yerro from CyberSource APAC Client Delivery Team. I’m going to implement FLEX API but in order to do that I need to used first, authentication method for calling it - Shared Secret (x-pay-token). I’m following this documentation: https://developer.visa.com/guides/vdpguide#get-started-overview
As I’m testing, I got an error as per below:
{"responseStatus": {
"code": "9101",
"severity": "ERROR",
"message": "Token validation failed",
"info": "",
"status": 401
}}
I followed all the steps and got it correct until the final step that the Token validation failed. May you please elaborate this error and do you have any documentation on the Reason Code/Reply Flag Description list with possible actions to do with that specific error?
Please kindly assist.
Hi Chrystal.
Sorry to hear - looking into this for you and will get shortly!
Thank you,
Ricardo
Hey Chrystal,
The error you are getting will be shown when the x-pay-token sent in the header is invalid.
Few things to note while generating token:
Note:
For Flex Keys resource we have to send xpaytoken
https://sandbox.api.visa.com/cybersource/payments/flex/v1/keys?apikey={apikey}
for flex Tokens there will be no xpaytoken
https://sandbox.api.visa.com/cybersource/payments/flex/v1/tokens
Try this out and keep me updated!
Thank you,
Ricardo
Hi Ricardo,
Thanks for the reply.
I got the explanation 1-3 but can you elaborate on #4. Did you mean that encryptionType will be the payload? As quoted in this docu: https://developer.visa.com/reference#cybersource__cybersource_flex_api
// Body
{ "encryptionType": "RsaOaep256" }
also will I still be using this script to generate the one-time use public key and key ID to encrypt the card number?
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; def hmac(String secretKey, String data) { Mac mac = Mac.getInstance("HmacSHA256") SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256") mac.init(secretKeySpec) byte[] digest = mac.doFinal(data.getBytes()) return digest } def APIKey = ‘VALUE_OF_YOUR_API_KEY’ def sharedSecret = ‘VALUE_OF_YOUR_SHARED_SECRET’ def URI = "helloworld" def QS = "apikey="+APIKey def timeStampUTC = String.valueOf(System.currentTimeMillis().intdiv(1000L)) def payload = "" def HMACDigest = hmac(sharedSecret, timeStampUTC + URI + QS + payload) def encodedDigest = HMACDigest.encodeHex().toString() def XPayToken = "xv2:"+ timeStampUTC + ":" + encodedDigest testRunner.testCase.setPropertyValue("xpayToken", XPayToken) log.info(XPayToken)
I tried it but got an error of:
{"responseStatus": {
"code": "9000",
"severity": "ERROR",
"info": "",
"status": 404,
"message": "Invalid URI"
}}
Note: I didn't used the "helloworld" URI instead "key"
I hope I make sense since I'm new to Flex API. Will be waiting for your reply.
Thanks!
Hi there,
Flex keys API :
URL: https://sandbox.api.visa.com/cybersource/payments/flex/v1/keys?apikey={apikey}
Request Headers:
Content-Type: application/json; charset=UTF-8
x-pay-token: xv2:1476291109:23589c93c9323aac28c76046e666e576a3cf614d835209d42b898bd935270699
Request Payload:
{"encryptionType":"WebCryptoAPI"}
Looks like you are using groovy so please find below the values that should be sent for flex
Generate x-pay-token:
def APIKey = ‘VALUE_OF_YOUR_API_KEY’
def sharedSecret = ‘VALUE_OF_YOUR_SHARED_SECRET’
def URI = "payments/flex/v1/keys" àURI value for Flex
def QS = "apikey="+APIKey
def timeStampUTC = String.valueOf(System.currentTimeMillis().intdiv(1000L))
def payload = "{\"encryptionType\":\"WebCryptoAPI\"}" àmy request payload above and this should are exactly same including space
def HMACDigest = hmac(sharedSecret, timeStampUTC + URI + QS + payload)
def encodedDigest = HMACDigest.encodeHex().toString()
def XPayToken = "xv2:"+ timeStampUTC + ":" + encodedDigest
testRunner.testCase.setPropertyValue("xpayToken", XPayToken)
log.info(XPayToken)
After u make the Success keys API call u will get public key and key ID which can be used to encrypt the card number
Sample Response of keys API:
{"keyId":"08GbCW6NTZ1NChjiLnr0OPwwsbrYVtaJ","der":{"format":"X.509","algorithm":"RSA","publicKey":"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkYcC8/plucNHWEPWErG4ggjZ69rLPyXcSHetc/kFw0pGc9Qqme6cnZgKymVDvffjrfvTKTFhgO8uHPHLn2t9Zju8hCZILkAZJ8+uPequN7nnot4Ec0l1Mp/nG35OUruJZDIhVnhxPr3v/JQf2vcj6TZEx95j48DMAFtAH77htUtCTCAyYijRAq+uOpDUfLbaRwFWVNz/PbWhsL8Kf2k1/NySBVngV2ucPLwmzWeBs+aiOUUFkFvIsoWabnOlenqjEPla/ykoMSKwfCqq16m3noh0SEHLjrKOfYmp/qZ76Vp+xSujH9RBj5TeO4FpW4ihTwvOeSDAkJl5a0dyy9tUqwIDAQAB"},"jwk":{"kty":"RSA","use":"enc","kid":"08GbCW6NTZ1NChjiLnr0OPwwsbrYVtaJ","n":"kYcC8_plucNHWEPWErG4ggjZ69rLPyXcSHetc_kFw0pGc9Qqme6cnZgKymVDvffjrfvTKTFhgO8uHPHLn2t9Zju8hCZILkAZJ8-uPequN7nnot4Ec0l1Mp_nG35OUruJZDIhVnhxPr3v_JQf2vcj6TZEx95j48DMAFtAH77htUtCTCAyYijRAq-uOpDUfLbaRwFWVNz_PbWhsL8Kf2k1_NySBVngV2ucPLwmzWeBs-aiOUUFkFvIsoWabnOlenqjEPla_ykoMSKwfCqq16m3noh0SEHLjrKOfYmp_qZ76Vp-xSujH9RBj5TeO4FpW4ihTwvOeSDAkJl5a0dyy9tUqw","e":"AQAB"}}
Try this out and let me know!
-Ricardo
Hi Ricardo,
Thanks for the detailed steps, but still I was having the same error:
{"responseStatus": {
"code": "9000",
"severity": "ERROR",
"message": "Invalid URI",
"info": "",
"status": 404
}}
Please see attached for my source code. I was sure that I carefully followed your steps.
Please kindly assist. Thank you!
Hi Ricardo,
Thanks for the detailed steps, but still I was having the same error:
{"responseStatus": {
"code": "9000",
"severity": "ERROR",
"message": "Invalid URI",
"info": "",
"status": 404
}}
Please see attached for my source code. I was sure that I carefully followed your steps.
Please kindly assist. Thank you!
i saw the attachment the call you are making is not get method can you please make the method as post and follow the detailed steps which were given earlier.
Thanks Jyostna! That resolved my error: Invalid URI, I didn't notice it was a GET method.
But now I'm getting this error:
{"responseStatus": {
"code": "9101",
"severity": "ERROR",
"message": "Token validation failed",
"info": "",
"status": 401
}}
Still followed what ricardo instructed and changed it to POST method.