路飞学城项目-支付相关-支付接口
############### 支付接口 ################
""" 支付逻辑 一,前端传递参数, 点击立即支付,应该做什么? 必须要弄清楚这个业务, 前端需要传递什么? 下面就是前端需要传递的数据, 1,优惠券的信息都不需要发,都在redis里面放着呢, 2,一定要传递最后的应付金额,不能说前面看到900,后台最后支付是1000了,后端和前端的计算要校验一致, 3,只有支付宝支付,所以不需要支付方式, 所以点击立即支付之后,需要传递贝里金额,和总金额 { beili : 100 money : 900 } 二,后端处理; 1,获取前端传过来的数据,有贝里和总金额, 2,数据验证, 2.1 需要两个值都是大于等于0的, 2.2 个人账户是否有100贝里,余额不足就不能往下走, 3,去结算中心获取课程信息,课程信息可能会有多个,需要循环课程信息 payment_userid_courseid : { course_id:1 title img price_policy_id:1 coupon_id :{ 1: { } 2: { } } default_coupoon: period: period_display: price: } payment_global_coupon_用户ID: { 'coupon': { 2: {'money_equivalent_value': 200}, # 优惠券 ID :{优惠券信息} }, 'default_coupon': 0 } 3.1 校验课程,检查课程是否还在有效期,或者上线状态, 3.2 价格策略是否合法,是否在存在 3.3 校验优惠券是否合法, 3.4 获取原价和优惠券类型, 如果是立减,就是原价-优惠金额,如果是结果是负数,就是直接0. 如果是满减,判断是否满足最低的限制, 如果是折扣,就是原价*折扣比例, 4,通用优惠券处理: 4.1 通用优惠券是否合法 如果是立减,就是原价-优惠金额,如果是结果是负数,就是直接0. 如果是满减,判断是否满足最低的限制, 如果是折扣,就是原价*折扣比例, 这一步之后就是实际支付的金额了, 5,处理beli 4.1 计算beli是否充足 4.2 计算beli后的价格 6,总金额校验 实际支付-贝里就是应付金额了,需要和前端传过来的paymoney判断是否一致 最终金额的计算方式,先计算每一个课程的原价-优惠券=折扣价,然后所有课程的折扣价加起来,然后再去-通用优惠券,得到最终的价格, 7,生成订单,如果是一个订单买了三个课程 这里面是基于事务来操作的,要么都成功,要么都失败, 订单表生成数据, 订单详细表生成三条数据,并且对应的生成三条已报名课程的记录, 报名表,需要生成记录, 如果有贝里,第一个还需要生成贝里的交易记录,第二个,余额字段需要扣除, 优惠券的状态更新, 注意:如果支付金额是0,直接不用调用支付宝接口了,订单状态就是已支付, 注意:如果支付金额是大于0,就要调用支付宝的接口了, 生成url,包含了订单号, 回调函数用来更新订单状态, """
############### 支付接口 ################
from django.core.exceptions import ObjectDoesNotExist from utils.pay import AliPay import time class PaymentView(APIView): # 前端需要传递什么? 下面就是前端需要传递的数据, # { # pay_money:800 # course_info :[ # { # course_id:1 # price_policy_id:1 # coupon_record_id :1 # }, # { # course_id:2 # price_policy_id:5 # coupon_record_id :2 # } # ] # global_coupon_id :1 # beli:1000 # } authentication_classes = [TokenAuth, ] def post(self,request): now = datetime.datetime.utcnow() res = BaseException() # 1,获取前端传过来的数据 user = request.user courses_info = request.data.get('courses_info') global_coupon_id = request.data.get('global_coupon_id') beli = request.data.get('beli') pay_money = request.data.get('pay_money') print(courses_info,global_coupon_id,beli,pay_money) # 2,循环课程信息 course_price_list = [] try: for course_info in courses_info: course_id = course_info.get('course_id') price_policy_id = course_info.get('price_policy_id') coupon_id = course_info.get('coupon_record_id') print(course_id,price_policy_id,coupon_id) # 2.1 校验数据 # 2.2 校验课程是否存在, course_obj= models.Course.objects.get(id=course_id) # 2.3 价格策略是否合法, if price_policy_id not in [obj.pk for obj in course_obj.price_policy.all()]: raise CommentException(1051,'价格策略不存在') # 2.4 校验优惠券是否合法 coupon_record = models.CouponRecord.objects.filter( pk = coupon_id, # account = request.user, # status=0, # coupon__valid_begin_date__lte=now, # coupon__valid_end_date__gte=now, # coupon__object_id=course_id ).first() print(coupon_record) if not coupon_record: raise CommentException(1052,'优惠券有问题') # 2.5 计算课程优惠券的折后价 # 要根据不同的优惠券类型来计算 course_price = models.PricePolicy.objects.get(pk= price_policy_id).price print(course_price) coupon_price = self.coupon_price(course_price,coupon_record) course_price_list.append(coupon_price) print(course_price_list) # 3,通用优惠券处理: # 3.1 通用优惠券是否合法 global_coupon_record = models.CouponRecord.objects.filter( pk=global_coupon_id, account=request.user, status=0, coupon__valid_begin_date__lte=now, coupon__valid_end_date__gte=now, coupon__object_id=None ).first() if not global_coupon_record: raise CommentException(1053,'通用优惠券有问题') # 计算通用优惠券后的价格 global_coupon_price = self.coupon_price(sum(course_price_list),global_coupon_record) print(global_coupon_price) # 4,处理beli # 4.1 计算beli是否充足 if beli >request.user.beli: raise CommentException(1054,'beli数不足') # 4.2 计算beli后的价格 final_price = global_coupon_price - beli/10 print(final_price) if final_price < 0: final_price = 0 # 5,比较参数和paymoney是否一致 if final_price != pay_money: raise CommentException(1055,'实际支付价格和参数价格不一致') # 7,生成订单 # 订单表 # 订单详情表 # 8 ,构建支付宝的二维码页面的url, alipay = self.get_alipy() query_params = alipay.direct_pay( subject="充气式韩红", # 商品简单描述 out_trade_no="x2" + str(time.time()), # 商户订单号 total_amount=pay_money, # 交易金额(单位: 元 保留俩位小数) ) pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format(query_params) res.data='订单创建成功' res.url = pay_url except ObjectDoesNotExist as e: res.code =1050 res.error='课程信息不存在' except CommentException as e: res.code =e.code res.error=e.msg except Exception as e: res.code = 500 res.error = str(e) return Response(res.dict) def coupon_price(self,price,coupon_record): coupon_type = coupon_record.coupon.coupon_type money_equivalent_value = coupon_record.coupon.money_equivalent_value off_percent = coupon_record.coupon.off_percent minimum_consume = coupon_record.coupon.minimum_consume rebate_price = 0 if coupon_type==0: rebate_price = price-money_equivalent_value if rebate_price<0: rebate_price=0 elif coupon_type==1: if price<minimum_consume: raise CommentException('不满足最低消费',1054) else: rebate_price*off_percent/100 return rebate_price def get_alipy(self): obj = AliPay( appid=settings.APPID, app_notify_url=settings.NOTIFY_URL, # 如果支付成功,支付宝会向这个地址发送POST请求(校验是否支付已经完成) return_url=settings.RETURN_URL, # 如果支付成功,重定向回到你的网站的地址。 alipay_public_key_path=settings.PUB_KEY_PATH, # 支付宝公钥 app_private_key_path=settings.PRI_KEY_PATH, # 应用私钥 debug=True, # 默认False, ) return obj
############### 支付接口 ################
############### 支付接口 ################
############### 支付接口 ################
技术改变命运