記錄django-rest-framework處理微信支付notify_url遇到的問題

最近在作一個小程序,小程序有涉及到微信支付,說來慚愧,仍是第一次本身動手去作微信支付這一塊的實現,因此過程當中遇到了不少人都會踩的坑(例如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-Typetext/xml而不是application/xml,真是mmp,看了下XMLParser的源碼,改起來很簡單:post

# ...省略
class WechatPaymentXMLParser(XMLParser):
    media_type = 'text/xml'

class WechatNotifyView(APIView):
    # ...省略
    parser_classes = (WechatPaymentXMLParser,)
    # ...省略

再測試了一次,搞定,request.data打印出來的就是那個xml內容的字典形式。
吐槽:微信的東西老是有吐不完的槽,但爸爸始終是爸爸。測試

相關文章
相關標籤/搜索