菜单
菜单
文章目录
  1. 安装支持 Rest Framework 的 XML 渲染库
  2. 复写 XMLRenderer 类
  3. 在微信支付回调视图里添加渲染

Django 处理微信支付的回调

最近在做的项目中需要涉及支付功能的开发,微信支付的下单和回调都是采用 XML 格式,Django Rest Framework 默认不支持 XML 渲染方式。需要安装一个第三方库来支持,并且需要做一些修改。

安装支持 Rest Framework 的 XML 渲染库

1
pip install djangorestframework-xml

复写 XMLRenderer 类

由于 djangorestframework-xml 不支持解析 XML 文件中含有 CDATA 的数据,需要使用 lxml 库来替换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from django.utils import six
from lxml.etree import CDATA, Element, tostring, SubElement
from rest_framework_xml.renderers import XMLRenderer


class WechatXMLRenderer(XMLRenderer):
"""
微信数据 XML 渲染模块
"""

root_tag_name = 'xml'

def _to_xml(self, xml, data):
if isinstance(data, (list, tuple)):
for item in data:
child = SubElement(xml, self.item_tag_name)
self._to_xml(child, item)

elif isinstance(data, dict):
for key, value in six.iteritems(data):
child = SubElement(xml, key)
self._to_xml(child, value)

elif data is None:
# Don't output any value
pass

else:
xml.text = CDATA(data)

def render(self, data, accepted_media_type=None, renderer_context=None):
"""
Renders `data` into serialized XML.
"""
if data is None:
return ''

xml = Element(self.root_tag_name)
self._to_xml(xml, data)

return tostring(xml, encoding="unicode")

在微信支付回调视图里添加渲染

将上一步复写的 XML 渲染类放到视图的 renderer_classes 里。
然后复写 post 方法,对其进行相应的数据验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class WechatPayNotifyView(generics.CreateAPIView):
"""
微信回调
"""

permission_class = ()
authentication_class = ()
serializer_class = WechatPayNotifySerializer
parser_classes = (XMLParser, )
renderer_classes = (WechatXMLRenderer, )

def post(self, request, *args, **kwargs):
# parse_xml 为解析 XML 文件,转换为 JSON
# check_signature 为验证 sign
# 以上实现可使用 wechatpy 库
data = parse_xml(request.body.decode())
if check_signature(data) and data.get('result_code') == "SUCCESS":
sale_record.status = True
sale_record.save()
serializer = self.get_serializer(data={
'return_code': request_data.get('result_code')})
serializer.is_valid(raise_exception=True)
return Response(serializer.data)
支持一下
扫一扫,支持我
  • 微信扫一扫
  • 支付宝扫一扫