本文共 4473 字,大约阅读时间需要 14 分钟。
前面章节完成了阿里支付的工具类的编写。现在将此工具类应用至view中:
首先看支付宝文档发现。return_url是采用get方法发起的请求。而notify_url这是post请求的。所以我们可以做到同一个view中
而无论是哪个请求 他们的内部执行方法是一样的。都是创建1个支付宝的工具类然后传递参数。然后将支付宝发送过来的参数将除sign参数之外的其他参数进行排序加密然后跟sign参数的值进行比对。
如果比对成功则修改订单状态。
代码示例
# trade/viewsfrom rest_framework.views import APIViewfrom utils.alipay import AliPayfrom MxShop.settings import private_key_path, public_key_pathfrom datetime import datetimefrom rest_framework.response import Responseclass AliPayViewset(APIView): def get(self, request): """ 处理支付宝的return_url返回 :param request: :return: """ # 将支付宝传递过来的参数分开 分成sign和非sign参数 processed_dict = {} for key, value in request.POST.items(): processed_dict[key] = value sign = processed_dict.pop("sign", None) # 建立支付工具对象 alipay = AliPay( appid="2016101100661810", app_notify_url="http://127.0.0.1:8000/alipay/return/", app_private_key_path=private_key_path, alipay_public_key_path=public_key_path, debug=True, return_url="http://127.0.0.1:8000/alipay/return/" ) # 校验sign是否正确 verify_re = alipay.verify(processed_dict, sign) # 正确的话就修改订单状态 if verify_re is True: order_sn = processed_dict.get('out_trade_no', None) trade_no = processed_dict.get('trade_no', None) trade_status = processed_dict.get('trade_status', None) existed_orders = OrderInfo.objects.filter(order_sn=order_sn) for existed_order in existed_orders: existed_order.pay_status = trade_status existed_order.trade_no = trade_no existed_order.pay_time = datetime.now() existed_order.save() return Response("success")#跟上面一模一样 def post(self, request): """ 处理支付宝的notify_url :param request: :return: """ processed_dict = {} for key, value in request.POST.items(): processed_dict[key] = value sign = processed_dict.pop("sign", None) alipay = AliPay( appid="2016101100661810", app_notify_url="http://127.0.0.1:8000/alipay/return/", app_private_key_path= private_key_path, alipay_public_key_path= public_key_path, debug=True, return_url = "http://127.0.0.1:8000/alipay/return/" ) verify_re = alipay.verify(processed_dict, sign) if verify_re is True: order_sn = processed_dict.get('out_trade_no',None) trade_no = processed_dict.get('trade_no', None) trade_status = processed_dict.get('trade_status', None) existed_orders = OrderInfo.objects.filter(order_sn=order_sn) for existed_order in existed_orders: existed_order.pay_status = trade_status existed_order.trade_no = trade_no existed_order.pay_time = datetime.now() existed_order.save() return Response("success")
urls:
path('alipay/return/', AliPayViewset.as_view(), name='alipay'),
settings.py中设置下公钥和私钥的路径 省的因为路径出问题
#支付宝相关配置private_key_path = os.path.join(BASE_DIR, 'apps/trade/keys/private_2048.txt')public_key_path = os.path.join(BASE_DIR, 'apps/trade/keys/alipay_key_2048.txt')
订单接口这样就OK了
但是还有地方需要订单url 比如订单列表页和订单详情页。但是我们数据库中又没有存储订单url的相关字段,咋办。这就需要serializer动态生成的字段了.使用serializerMethod字段。
官方文档;
具体的代码就是我们在OrderSerializer和OrderDetailSerializer两个类中进行添加字段和函数:
# 两个类都是添加此字段(此方法必须设置read_only=True) alipay_url = serializers.SerializerMethodField(read_only=True)# 通过此函数(格式:get_ + 字段名)rest会自动寻找对应的字段# 生成url地址返回给前端页面 def get_alipay_url(self, obj): alipay = AliPay( appid="2016101100661810", app_notify_url="http://127.0.0.1:8000/alipay/return/", app_private_key_path=private_key_path, alipay_public_key_path=public_key_path, debug=True, return_url = "http://127.0.0.1:8000/alipay/return/" ) url = alipay.direct_pay( subject=obj.order_sn, out_trade_no=obj.order_sn, total_amount=obj.order_mount ) re_url = "https://openapi.alipaydev.com/gateway.do?{data}".format(data=url) return re_url
教程中后来有说到根据前端页面跳转到支付宝之后 支付宝请求数据返回给后端。而后端没办法直接发送数据给vue前端进行跳转(vue毕竟不是服务器)所以给出了1个方案是将vue丢到django中。当做模板来用。 我靠 这样性能得多差,还不好调试
果断不理他。 然后教程也给出了第二种方法 获取支付宝的支付图片。然后vue展示图片并且发心跳请求,来确认订单状态是否是已支付。然而。没教程 = = 就给了接口文档 好吧。等项目中真的用到的时候在写吧 先把文档给出来吧
第十章内容完结。 内容有些多。改天找时间捋一捋流程
转载地址:http://rsepi.baihongyu.com/