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