最近在做一個小程式,小程式有涉及到微信支付,說來慚愧,還是第一次自己動手去做微信支付這一塊的實現,所以過程中遇到了很多人都會踩的坑(例如mmp的微信支付各種key各種id要在哪裡找,很難找),這次使用django來開發,介面部分用django-rest-framework(下面簡稱drf)。
入入入入入正題吧。
微信支付統一下單介面,有一個叫notify_url
的引數,作用我就照搬官方文件:
非同步接收微信支付結果通知的回撥地址,通知url必須為外網可訪問的url,不能攜帶引數。
吐槽:官方文件竟然不告訴我到時候是通過Get還是Post(難道是其他HTTP method)請求我,我怕我到時候措不及防,事實證明,是通過Post來請求的。
好了,我前面的支付功能都寫好了,就等微信爸爸來調我的notify_url
了,測試支付完之後,屁顛屁顛跑去IDE的控制檯看debug輸出,結果有Traceback,找找裡面的關鍵資訊:Unsupported media type "text/xml" in request.
,哭唧唧。
唔,聰明如我,drf可以自定義parser類,官方文件也有提到一個xml的parser,安裝了,然後為這個介面指定了parser_classes
,程式碼如下:
# ...省略
class WechatNotifyView(APIView):
"""
微信回撥介面
"""
authentication_classes = []
permission_classes = (AllowAny,)
parser_classes = (XMLParser,)
def post(self, request):
print(request.data)
return Response()
滿心歡喜重新測試一次,結果還是不對,追查了下,發現了關鍵所在,微信呼叫notify_url
的時候,Content-Type
是text/xml
而不是application/xml
,真是mmp,看了下XMLParser的原始碼,改起來很簡單:
# ...省略
class WechatPaymentXMLParser(XMLParser):
media_type = `text/xml`
class WechatNotifyView(APIView):
# ...省略
parser_classes = (WechatPaymentXMLParser,)
# ...省略
再測試了一次,搞定,request.data
列印出來的就是那個xml內容的字典形式。
吐槽:微信的東西總是有吐不完的槽,但爸爸始終是爸爸。