最近在作一个小程序,小程序有涉及到微信支付,说来惭愧,仍是第一次本身动手去作微信支付这一块的实现,因此过程当中遇到了不少人都会踩的坑(例如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内容的字典形式。
吐槽:微信的东西老是有吐不完的槽,但爸爸始终是爸爸。测试