day88:luffy:支付宝同步结果通知&接收异步支付结果&用户
1.支付宝同步结果通知 2.用户购买记录表 3.接受异步支付结果 4.善后事宜 5.我的订单 当用户输入用户名和密码确认支付的时候,支付宝会给vue前端回复一个url,这个url很长,后面包含了很多参数,参数如下所示: http://www.luffycity.cn:8080/payments/result? charset=utf8& out_trade_no=20190929151453000001000020& method=alipay.trade.page.pay.return& total_amount=310.00& sign=kebIZBI%2FpCNXmCivfJPPw21gcobulPZoSh%2BXiHR8l6cgexQi2STG4AZgr%2FEUhvc5kEMacJLvCmBaw1Wqo4WK3sPzbUaPmzq3NshUNzYK2lWTsmOauidNxlk1bK0Q%2FANBfQUkmj6TQjyB5T9QqEnS80KFsDrGrasU%2B%2Fz9W%2FjOCLrSji6TnKhRkI9pqBMdw823ABU75b7zOtXzcXKduO%2B6vsXVvluMzedss9dHs1celxPAWQV9jcKjzq%2F1bPbZcmgAGNQQecoJ%2BFSc3uTmTk24uV39PM54LIlg8aeRlkPNjvhBkJh%2FG0%2BURNDdG2593IFIF%2BUqoU%2F7ixm19dX222GCWg%3D%3D& trade_no=2019092922001439881000120282& auth_app_id=2016091600523592& version=1.0& app_id= sign_type=RSA2& seller_id=2088102175868026& timestamp=2019-09-29%2015%3A15%3A53
支付宝将参数传递给了vue前端,vue前端要这些参数发送给后端,让后端去对这些参数做一个校验。判断这个url是不是支付宝发过来的
from django.urls import path,re_path from . views urlpatterns = [ path('result/',views.AlipayResultView.as_view(),) ] payment/view.py class AlipayResultView(APIView): permission_classes = [IsAuthenticated,] def get(self,request): # 1.创建alipay对象 alipay = AliPay( appid=settings.ALIAPY_CONFIG[appid],app_notify_url=None, 默认回调url app_private_key_string=open(settings.ALIAPY_CONFIG[app_private_key_path]).read(), 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥, alipay_public_key_string=open(settings.ALIAPY_CONFIG[alipay_public_key_pathsign_type'],1)"> RSA 或者 RSA2 debug=settings.ALIAPY_CONFIG[debug 默认False ) 2.校验支付宝响应数据 data = request.query_params.dict() 获取那一大堆的参数 out_trade_no = data.get(out_trade_no') 获取商户订单号 sign = data.pop(sign 获取签名 success = alipay.verify(data,sign) 通过参数和签名来验证那一堆参数是不是支付宝发过来的 if not success: logger.error(%s,支付宝响应数据校验失败' % out_trade_no) return Response(支付宝响应数据校验失败',status=status.HTTP_400_BAD_REQUEST) 响应结果 return Response({msg':okdata:res_data}) 3.vue前端发送请求验证get参数
如果校验没有问题 就可以显示购买成功了。 Success.vue created(){ // 把地址栏上面的支付结果,转发给后端 this.send_alipay_params(); methods:{ send_alipay_params(){ let token = localStorage.token || sessionStorage.token; this.$axios.get(`${this.$settings.Host}/payment/result/${location.search}`,{ headers:{ 'Authorization':'jwt ' + token } }).then((res)=>{ 如果后端验证这些参数没有问题 购买成功页面需要的参数就可以传递过来了 this.pay_time = res.data.data.pay_time; 支付时间 this.course_list = res.data.data.course_list; 购买课程列表 this.total_real_price = res.data.data.total_real_price; 课程总真实价格 }).catch((error)=>{ .$message.error(error.response.data.msg); }) },
UserCourse(BaseModel): """用户的课程购买记录""" pay_choices = ( (1,1)">用户购买),(2,1)">免费活动活动赠品系统赠送user_courses"用户") course = models.ForeignKey(Course,1)">course_users课程) trade_no = models.CharField(max_length=128,null=True,blank=True,1)">支付平台的流水号",help_text=将来依靠流水号到支付平台查账单) buy_type = models.SmallIntegerField(choices=pay_choices,default=1,1)">购买方式) pay_time = models.DateTimeField(null=True,1)">购买时间) out_time = models.DateTimeField(null=True,1)">过期时间") null表示永不过期 Meta: db_table = ly_user_course verbose_name = 课程购买记录 verbose_name_plural = verbose_name
post(self,1)"> 创建alipay对象 alipay = ) 校验支付宝响应数据 data = request.data.dict() sign = data.pop() success = alipay.verify(data,sign) if success and data[trade_status"] in (TRADE_SUCCESSTRADE_FINISHED): self.change_order_status(data) success')
1.修改订单状态 2.扣除优惠劵 积分 3.清空购物车数据和结算页面全部数据 4.将相关信息存到用户购买记录表中 AlipayResultView(APIView):
def change_order_status(self,data): 修改订单状态
with transaction.atomic():
out_trade_no = data.get()
trade_no = data.get(trade_no)
A.修改订单状态
1.获取当前订单号的订单对象
order_obj = Order.objects.get(order_number=out_trade_no)
2.将当前订单的订单状态改为1:已支付
order_obj.order_status = 1
3.保存订单信息
order_obj.save()
B.修改优惠券的使用状态
if order_obj.coupon > 0: 如果用户使用了优惠劵
1.获取用户使用的那张优惠劵对象
user_coupon_obj = UserCoupon.objects.get(is_use=False,id=order_obj.coupon)
2.将用户使用的那张优惠劵的状态由未使用改为已使用
user_coupon_obj.is_use = True
3.保存用户的优惠劵的信息
user_coupon_obj.save()
C.支付成功,用户积分应该对应的扣除
1.查询当前订单使用了多少积分
use_credit = order_obj.credit
2.查询到用户的总积分数减去使用的积分数得到用户的剩余积分数
self.request.user.credit -= use_credit
3.保存用户的积分信息
self.request.user.save()
D.保存支付宝的交易流水号(购买记录表)
1.通过订单对象反向查询到所有的订单详情对象
order_detail_objs = order_obj.order_courses.all()
2.获取当前时间
now = datetime.datetime.now()
购买成功 从redis中将课程的选中状态删除掉
conn = get_redis_connection(cart)
pipe = conn.pipeline()
pipe.delete(selected_cart_%s self.request.user.id)
需要给购买成功页面(Success.vue返回的数据)
res_data = {
pay_time: now,course_list: [],1)">total_real_price: order_obj.real_price,}
for order_detail in order_detail_objs:
购买成功 课程学习的学生数+1
course = order_detail.course
course.students += 1
course.save()
购买成功的课程应该显示课程列表的每个课程
res_data[].append(course.name)
从课程详情页获取当前课程的有效期数值
expire_id = order_detail.expire
if expire_id > 0: 如果不是永久有效
根据expire_id查询到课程有效期model对象
expire_obj = CourseExpire.objects.get(id=expire_id)
查询到课程的有效期(天数)
expire_time = expire_obj.expire_time
计算课程的过期时间
out_time = now + datetime.timedelta(days=expire_time)
else: 如果是永久有效,就没有过期时间
out_time = None
一切处理完毕,将相关信息存到用户购买记录表中
UserCourse.objects.create(**{
user:self.request.user,1)">course:course,1)">:trade_no,1)">buy_type':1:now,1)">out_time:out_time,})
购物车redis数据删除
pipe.hdel(cart_%s self.request.user.id,course.id)
pipe.execute()
return res_data
order/serializers.py Myorder.vue index.js users/urls.py user/serializers.py order/models.py 在我的订单页面中,需要展示一些数据 Myorder.vue > (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |