最近在作一個小程序,小程序有涉及到微信支付,說來慚愧,仍是第一次本身動手去作微信支付這一塊的實現,因此過程當中遇到了不少人都會踩的坑(例如mmp的微信支付各類key各類id要在哪裏找,很難找),此次使用django來開發,接口部分用django-rest-framework(下面簡稱drf)。python
入入入入入正題吧。django
微信支付統一下單接口,有一個叫notify_url
的參數,做用我就照搬官方文檔:小程序
異步接收微信支付結果通知的回調地址,通知url必須爲外網可訪問的url,不能攜帶參數。
吐槽:官方文檔居然不告訴我到時候是經過Get仍是Post(難道是其餘HTTP method)請求我,我怕我到時候措不及防,事實證實,是經過Post來請求的。微信
好了,我前面的支付功能都寫好了,就等微信爸爸來調個人notify_url
了,測試支付完以後,屁顛屁顛跑去IDE的控制檯看debug輸出,結果有Traceback,找找裏面的關鍵信息:Unsupported media type "text/xml" in request.
,哭唧唧。app
唔,聰明如我,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的源碼,改起來很簡單:post
# ...省略 class WechatPaymentXMLParser(XMLParser): media_type = 'text/xml' class WechatNotifyView(APIView): # ...省略 parser_classes = (WechatPaymentXMLParser,) # ...省略
再測試了一次,搞定,request.data
打印出來的就是那個xml內容的字典形式。
吐槽:微信的東西老是有吐不完的槽,但爸爸始終是爸爸。測試