我在将curl请求转换为Python请求调用时遇到了问题:
这里是curl调用的样子:(取自:http://developers.payu.com/en/restapi.html#creating_new_order_api)
curl -X POST https://secure.payu.com/api/v2_1/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 3e5cac39-7e38-4139-8fd6-30adc06a61bd" \
-d '{
"notifyUrl": "https://your.eshop.com/notify",
"customerIp": "127.0.0.1",
"merchantPosId": "145227",
"description": "RTV market",
"currencyCode": "PLN",
"totalAmount": "21000",
"products": [
{
"name": "Wireless Mouse for Laptop",
"unitPrice": "15000",
"quantity": "1"
},
{
"name": "HDMI cable",
"unitPrice": "6000",
"quantity": "1"
}
]
}'
以下是我在请求中写的内容:
import json
import requests
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer 3e5cac39-7e38-4139-8fd6-30adc06a61bd',
}
data = {
"notifyUrl": "https://your.eshop.com/notify",
"customerIp": "127.0.0.1",
"merchantPosId": "145227",
"description": "RTV market",
"currencyCode": "PLN",
"totalAmount": "21000",
"products": [
{
"name": "Wireless Mouse for Laptop",
"unitPrice": "15000",
"quantity": "1"
},
{
"name": "HDMI cable",
"unitPrice": "6000",
"quantity": "1"
}
]
}
resp2 = requests.post('https://secure.payu.com/api/v2_1/orders', headers=headers, json=data)
print(resp2.json())
作为回应打印出来的卷曲:
{"orderId":"V6GRPMNRLR160429GUEST000P01","status":{"statusCode":"SUCCESS"},"redirectUri":"https://secure.payu.com/pl/standard/co/summary?sessionId=HtnLqVtBJ5tcOKG2nX03TKwAXOYtXPHe&merchantPosId=145227&timeStamp=1461948331350&showLoginDialog=false&apiToken=9f31fcd1d0d1c5fde8aa57c2b16b5d6bbdfe81543a5f6a12cd39955a487fdaab"}
而python请求:
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:315: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#snimissingwarning.
SNIMissingWarning
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:120: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
InsecurePlatformWarning
Traceback (most recent call last):
File "/home/ubuntu/workspace/src/billing/testapi.py", line 30, in <module>
print(resp2.json())
File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 808, in json
return complexjson.loads(self.text, **kwargs)
File "/usr/lib/python2.7/dist-packages/simplejson/__init__.py", line 488, in loads
return _default_decoder.decode(s)
File "/usr/lib/python2.7/dist-packages/simplejson/decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "/usr/lib/python2.7/dist-packages/simplejson/decoder.py", line 389, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
simplejson.scanner.JSONDecodeError: Expecting value: line 8 column 1 (char 7)
有谁知道为什么它不能处理请求?感谢
答案 0 :(得分:1)
网站以 302状态代码响应,包括位置标头:
>>> resp = requests.post('https://secure.payu.com/api/v2_1/orders', headers=headers, json=data)
>>> resp.history
[<Response [302]>, <Response [302]>]
>>> resp.history[0].headers['location']
'https://secure.payu.com/pl/standard/co/summary?sessionId=rrQ97fR2bxQJhUqCDORCbRa0uA4WlxJi&merchantPosId=145227&timeStamp=1461950205252&showLoginDialog=false&apiToken=f3599eca78ad55a16d84608e69f3ac7458b782598b064b337be07e8bd6c2c1d5'
>>> resp.history[0].text
u'{"orderId":"Z9W2H77TVD160429GUEST000P01","status":{"statusCode":"SUCCESS"},"redirectUri":"https://secure.payu.com/pl/standard/co/summary?sessionId=rrQ97fR2bxQJhUqCDORCbRa0uA4WlxJi&merchantPosId=145227&timeStamp=1461950205252&showLoginDialog=false&apiToken=f3599eca78ad55a16d84608e69f3ac7458b782598b064b337be07e8bd6c2c1d5"}'
您可以通过查看包含先前请求的response.history
列表来查看重定向历史记录(就像我上面所做的那样)。 resp.history[0]
是最初的回复。请参阅文档中的Redirection and History。
请注意,初始响应中的数据就在那里。
当您使用任何 Accept-Encoding
标头时,网站会执行此操作;如果添加
-H "Accept-Encoding: gzip, deflate"
到curl
命令,或者向supplied payu.apiari.io console添加相同的标头(带有任何值)(单击标题,然后添加Accept-Encoding
标题并为标题添加一个值。
您应该将此视为网站中的错误,因为指定该标头是完全正常的事情。事实上,Python httplib
库(由requests
间接使用)如果您自己省略它,则为该标题设置默认值,因此这不是requests
甚至可以关掉。因此,我已将此报告给PayU作为错误。
作为解决方法,您可以使用response.history[0]
引用,或者更好的是,告诉请求不要首先遵循重定向:
>>> resp = requests.post('https://secure.payu.com/api/v2_1/orders', headers=headers, json=data, allow_redirects=False)
>>> resp.json()
{u'orderId': u'NBWTP5WNKK160429GUEST000P01', u'status': {u'statusCode': u'SUCCESS'}, u'redirectUri': u'https://secure.payu.com/pl/standard/co/summary?sessionId=PcvceJHf5En60Dier5gKxCyExiva4qh0&merchantPosId=145227&timeStamp=1461950329704&showLoginDialog=false&apiToken=5962ef901010ca4f8ef6491619217c060f4d53ed0d8e4eadb513d4e0811fc992'}
但请注意忽略302可能会干扰正常状态代码,我看到a 302 may indicate that additional security info is required。