I'm having trouble with token validation with the Authorizations v3 API in python. I have ran the helloworld GET API successfully, so I'm confident that my credentials are not the problem. I believe the problem is with how I pass in the PAYLOAD body. I've never ran a successful post request yet and I can't find any examples. Can anyone tell me how to pass the PAYLOAD body into the x_pay_token generator?
I copy & paste the PAYLOAD body as:
body = {PAYLOAD data, with my ClientID from my test data in place}
and then I pass the body into the x_pay_token generator. I use json.dumps to pass it in as a string otherwise it won't go through the _get_x_pay_token() function.
x_pay_token = _get_x_pay_token(shared_secret, resource_path, query_string, json.dumps(body))
When I run this code, the following error occurs:
{"responseStatus":{"status":401,"code":"9159","severity":"ERROR","message":"Token Validation Failed","info":""}
here's the headers, url, and request for extra debugging:
headers = {'X-PAY-TOKEN': x_pay_token, 'Accept': 'application/json', 'Content-Type': 'application/json'}
url = 'https://sandbox.api.visa.com/acs/v3/payments/authorizations?apiKey='{{myApi}}'
r = requests.post(url, headers=headers)
This is all my python code:
def _get_x_pay_token(shared_secret, resource_path, query_string, body):
timestamp = str(timegm(datetime.utcnow().timetuple()))
pre_hash_string = timestamp + resource_path + query_string + body
hash_string = hmac.new(shared_secret,
msg=pre_hash_string.encode('utf-8'),
digestmod=sha256).hexdigest()
return 'xv2:' + timestamp + ':' + hash_string
shared_secret = b'{{mySharedSecret}}'
resource_path = 'authorizations'
query_string = 'apiKey={{myaApi}}'
body = {
"msgIdentfctn": {
"clientId": "{{myclienId}}",
"correlatnId": "Gg6yTAyWkmhyq0jPKHziafe"
},
"Body": {
"Tx": {
"TxAttr": [
"INST"
],
"TxDesc": "transactiondescription",
"TxId": {
"LclDtTm": "2016-11-25T01:02:03"
},
"AddtlData": {
"Val": "freeformdata",
"Tp": "FreeFormDescData"
},
"TxAmts": {
"AmtQlfr": "ESTM",
"TxAmt": {
"Ccy": "008",
"Amt": "123.45"
}
}
},
"Envt": {
"Accptr": {
"PaymentFacltId": "52014057",
"CstmrSvc": "1 4155552235",
"ShrtNm": "ABC Supplies",
"Id": "999999999999999",
"FrgnRtlrInd": True,
"Adr": {
"PstlCd": "78463",
"CtrySubDvsnMjr": "03",
"Ctry": "US",
"CtrySubDvsnMnr": "011"
}
},
"Termnl": {
"TermnlId": {
"Id": "99999999"
}
},
"Wllt": {
"Prvdr": {
"Id": "VCIND"
}
},
"Card": {
"XpryDt": "2312",
"PAN": "4000220177656623"
}
},
"Cntxt": {
"Vrfctn": [
{
"VrfctnInf": {
"Val": {
"HexBinryVal": "099010618111100000000788400707000000000"
},
"Tp": "authenticationValue"
},
"Tp": "THDS"
},
{
"VrfctnInf": {
"Val": {
"TxtVal": "321"
}
},
"Tp": "CSCV"
},
{
"VrfctnInf": {
"Val": {
"TxtVal": "PO Box 12345"
}
},
"Tp": "ADDB"
},
{
"VrfctnInf": {
"Val": {
"TxtVal": "12345"
}
},
"Tp": "PCDV"
}
],
"TxCntxt": {
"MrchntCtgyCd": "3501",
"MrchntCtgySpcfcData": "B",
"AuthntcnOutgInd": True
},
"PtOfSvcCntxt": {
"CardDataNtryMd": "CDFL"
},
"SaleCntxt": {
"GoodsAndSvcsTp": "ELEC",
"GoodsAndSvcsSubTp": "CRCU"
}
},
"SplmtryData": [
{
"Envlp": {
"StrngCstmrAuthntcn": {
"Xmptn": [
{
"Val": "CLAI",
"Tp": "TMBE"
},
{
"Val": "NCLA",
"Tp": "LOWA"
}
],
"DlgtdAuthrty": "CLAI"
}
},
"PlcAndNm": "EUPSD2SCADataSD1V01"
}
],
"AdddmData": {
"AddtlData": {
"Val": "1234567890",
"Tp": "PlanRegSysId"
},
"Instlmt": {
"PmtSeqNb": "12",
"Plan": [
{
"DfrrdInstlmtInd": True,
"PrdUnit": "WEEK",
"SbsqntAmt": "9999.99",
"TtlNbOfPmts": 24,
"InstlmtCcy": 840,
"NbOfPrds": "2",
"PlanOwnr": "ISSR",
"GrdTtlAmt": "234.56"
}
]
}
}
}
}
print(json.dumps(body))
x_pay_token = _get_x_pay_token(shared_secret, resource_path, query_string, json.dumps(body))
headers = {'X-PAY-TOKEN': x_pay_token, 'Accept': 'application/json', 'Content-Type': 'application/json'}
url = 'https://sandbox.api.visa.com/acs/v3/payments/authorizations?apiKey={{myaApi}}'
r = requests.post(url, headers=headers, json=json.dumps(body))
print(r.content)
template = loader.get_template('checkout/sdk.html')
context = {
'code': r.content,
}
return HttpResponse(template.render(context, request))
Hi, @marcusdbb! Thank you for reaching out. An agent is looking for a solution for you and will get back to you as soon as possible. Until then, if any community members know a solution, please share it here. -Jenn
Hi @marcusdbb,
Thanks for your patience!
The 401 Token Validation Failed error you're getting will be seen when the x-pay-token sent in the header is invalid.
A couple of things I'd like you to note while generating the token:
Also, could you check to see if you're passing a correct value for URI. For example, make sure it’s defined correctly in the beginning of your code, and use the same value for the URI in the middle of your code. In general, for cases like this (i.e. “helloworld works, but the API XX doesn’t”) I'd like to ask of you, if you could, to please extend your SOAPUI project, and make sure that you can call a particular API from SOAPUI project first.
Thanks,
Illana