zoukankan      html  css  js  c++  java
  • 项目支付流程的介绍

    与订单相关的表的表有哪些字段
    订单表
        订单类型字段
        订单编号
        支付宝生成的第三方编号
        账户对象
        实付金额
        支付状态
        付款时间
        订单取消时间
    订单详情表
        fk订单
        fk ContentType  关联的普通课程或学位
        object_id 哪一个字段
        课程原价
        折扣后的价格
        课程的有效期(成功支付的状态下)
    总结:订单详情使用了ContentType字段 用来关联课程表以及字段,
    从购物车到支付的流程:
        可以选择课程依次添加至购物车页面,在购物车页面选择你想要买的课程以及时间,
        点击结算静如结算页面选择你的购物卷和支付方式以及是否使用贝利支付。
        点击立即支付进入支付宝付款界面,将存放在结算API中的付款金额放入到Alipay中
        用户扫码成功后,显示支付成功。三秒后自动跳转到主页面
    
    如何介绍你的项目
        前端基于vue开发,后端是基于Django rest Framework
        需求:为什么要做这个项目
            1.这个项目是一个看k12在线教育平台,它的功能有
                登录与注册
                课程信息
                课程详细信息
                课程的购物车
                课程结算
                课程支付
                课程订单
            2.我负责这个项目的结算与支付
                结算主要是将一些数据比如:
                    课程相关的,课程ID,课程图片,课程名,课程价格
                    优惠券list表相关的,优惠券ID,优惠券类型,优惠券抵消价格,优惠券开始的时间,结束的时间(优惠券是多个)
                    选择的优惠券ID,虚拟货币所持有的数量
                    然后进行计算最后所需要支付的价格,这里还是挺繁琐的,
                    不仅需要判断和优惠劵虚拟货币是否使用,
                    而且还要判断生成订单后还要扣除相应的优惠券和虚拟货币,
                    还有如果用户通过改变优惠券或者虚拟货币,还要动态改变其最终价格
                支付主要是
                    将信息添加到数据库的订单表和订单详情表中
                    为什么要有订单详情,因为每个订单可能会有多门课程,每单门课程是一张订单详情表
                    订单表中,有提交订单的时间,订单号,优惠券,虚拟货币分别折扣的金额,总付款的金额
                    订单详情表包括,课程图片,课程名称课程有效期,课程的单价
                    
              还要添加一条虚拟货币的交易记录(数据库)
                用户的对象
                交易金额
                账户的余额
                交易的类型
                流水号
                时间  
    然后跳转的支付页面 支付页面是引用了支付宝提供的第三方接口, 需要传入的参数有支付宝的接口地址,商户的ID,支付成功后所要跳转的页面,还有商户的私钥和支付宝的公钥 这里还有一个bug就是支付生成订单后将会扣除之前使用的优惠券和虚拟货币, 但如果是生成的是未支付的订单,如果用户没有及时取消未支付的 订单(我们实现的逻辑是取消订单会退回之前使用的购物券以及虚拟货币) 用户根本无法使用优惠券,虚拟货币,事实上优惠券,虚拟货币根本没有使用, 订单的自动取消机制是15天

     结算流程

    结算中心 =  {
        用户ID: {
            policy_course_dict:{
                1:{
                    'course_id': course_id,
                    'course_name': product['name'],
                    'course_img': product['course_img'],
                    'policy_id': product['choice_policy_id'],
                    'policy_price': policy_price,
                    'policy_': policy_period, # 30/
                    'default_coupon_id': 1,
                    'coupon_record_list': {
                        0:{'id': 0, 'text': '请选择优惠券'},
                        1:{'id': 1, 'type':1, 'text': '优惠券1', ..},
                        2:{'id': 2, 'type':2, 'text': '优惠券1', ..},
                        3: {'id': 3, 'type':3, 'text': '优惠券1', ..},
                    },
                },
                2:{
                    'course_id': course_id,
                    'course_name': product['name'],
                    'course_img': product['course_img'],
                    'policy_id': product['choice_policy_id'],
                    'policy_price': policy_price,
                    'policy_': policy_period,
                    'default_coupon_id': 0,
                    'coupon_record_list': {
                        0:{'id': 0, 'text': '请选择优惠券'},
                        1:{'id': 1, 'type':1, 'text': '优惠券1', ..},
                        2:{'id': 2, 'type':2, 'text': '优惠券1', ..},
                        3: {'id': 3, 'type':3, 'text': '优惠券1', ..},
                    },
                }
            },
            global_coupon_dict:{
                1:{'type': 0, 'text': "通用优惠券", 'id': 1, ..},
                2:{'type': 0, 'text': "通用优惠券", 'id': 2, ..},
                3:{'type': 0, 'text': "通用优惠券", 'id': 3, ...},
                4:{'type': 0, 'text': "通用优惠券", 'id': 4, ...},
            },
            choice_global_coupon:3
        }         
    }
    
    
    
    1. POST请求,创建订单
        - balance
        - alipay
        
        a. 去结算中心获取要结算的所有课程和优惠券
        
        
        总价 = 0
        总折扣 = 0
        b. 循环购买的所有课程
        
        当前时间 = datetime.datetime.now()
        当前日期 = datetime.datetime.now().date
        ****课程信息 = [] *****
        ****使用的优惠券ID列表 = [] *****
        for course_id,values in policy_course_dict.items():
            课程原价 = values['policy_price']
            使用的优惠券ID = values['default_coupon_id']
            discount = 0
            
            # 未使用优惠券
                temp = {
                    课程ID: 1,
                    原价: 10,
                    折扣价:10,
                    有效期:30
                }
                课程信息.append(temp)
                
                总价 += 课程原价
                折扣 += discount
            else:
                去数据库查询:指定优惠券是否已经使用、是否已经过期
                如果优惠券可不用:
                    raise Exception('优惠券不可用')
                
                
                如果是通用优惠券:
                    discount = 通用优惠券(如果大于课程原价,课程原价)
                elif 如果是满减优惠券:
                    if 价格是否大于最小满减要求:
                        discount = 通用优惠券(如果大于课程原价,课程原价)
                elif 如果是折扣优惠券:
                    discount = 课程原价 * (1-折扣)
                使用的优惠券ID列表.append(绑定可以的优惠券ID)
                
                temp = {
                    课程ID: 1,
                    原价: 10,
                    折扣价:9,
                    有效期:30
                }
                课程信息.append(temp)
                
                总价 += 课程原价
                折扣 += discount
            
        pay = 总价 - 总折扣
        
        全站优惠券ID = choice_global_coupon
        数据库获取并检查是否可用(优惠券是否已经使用、是否已经过期)
        如果优惠券可不用:
            raise('全站优惠券不可用')
            
        g_discount = 0
        如果是通用优惠券:
            g_discount = 通用优惠券(如果大于pay,pay)
        elif 如果是满减优惠券:
            if 价格是否大于最小满减要求:
                g_discount = 通用优惠券(如果大于pay,pay)
        elif 如果是折扣优惠券:
            g_discount = pay * (1- 折扣)
        
        总折扣 += g_discount
        使用的优惠券ID列表.append(全站优惠券ID)
        
        # 贝里 
        
        if balance <= request.user.balance:
            总折扣 += balance
        
        
        # 总结算
        如果不相等:只有 总价 - 总折扣 = alipay
            raise Exception('....')
        
        if alipay ==0:
            贝里&优惠券 
            pay_type = 0
        else:
            支付宝支付
            pay_type = 1
            
        # ############ 数据库操作 ##############
    
        事务:
            
            # 1. 创建订单表
                 order_obj = models.Order.objects.create(....status=0) # pay_type = 0
                 或
                 order_obj = models.Order.objects.create(....status=1) # pay_type = 1
                 
            # 2. 生成订单详细
                
                for item in 课程信息:
                    detail_obj = models.OrderDetail.objects.create(order_obj,课程ID,原价和折扣价)
                    models.EnrolledCourse.objects.create(...当前时间,当前时间+30,status=1)
                
            # 3. 处理优惠券
                models.CouponRecord.objects.filter(account=request.user,status=0,id__in=使用的优惠券ID列表]).update(status=1,order=order_obj)
            
            # 4. 处理贝里交易
                models.Account.objects.filter(id=reuqest.user.id).update(balance=F(balance)-balance)
                models.TransactionRecord.objects.create(amount=balance,balance=request.user.balance,transaction_type=1,content_object=order_obj)
                
            
            
        if pay_type==1:
            生成支付宝链接(自动生成自己的订单号),并返回给前端Vue
        
        
        
        
        
    # ##################################### 支付宝的回调 ######################################
    def callback(request,*args,**kwargs):
        models.Order.objects.filter(订单号).update(status=0)
        
        
        
        
        
        
        
        
        
        

    1.订单源码(新版)

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import json
    import time
    import random
    import datetime
    from django.conf import settings
    from django.db import transaction
    from django.db.models import F
    
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    from api.utils.auth.token_auth import LuffyTokenAuthentication
    from api.utils.auth.token_permission import LuffyPermission
    from api.utils import redis_pool
    from api.utils.alipay import AliPay
    
    from repository import models
    
    
    def generate_order_num():
        """
        生成订单编号, 且必须唯一
        :return:
        """
        while True:
            order_num = time.strftime('%Y%m%d%H%M%S', time.localtime()) + str(random.randint(111, 999))
            if not models.Order.objects.filter(order_number=order_num).exists():
                break
        return order_num
    
    
    def generate_transaction_num():
        """
        生成流水编号, 且必须唯一
        :return:
        """
        while True:
            transaction_number = time.strftime('%Y%m%d%H%M%S', time.localtime()) + str(random.randint(111, 999))
            if not models.TransactionRecord.objects.filter(transaction_number=transaction_number).exists():
                break
        return transaction_number
    
    
    class PayOrderView(APIView):
        authentication_classes = [LuffyTokenAuthentication, ]
        permission_classes = [LuffyPermission, ]
    
        def post(self, request, *args, **kwargs):
            """
            去支付,生成订单。
            获取前端提交的购买信息
                {
                    course_price_list:[
                        {'policy_id':1, '':'course_id':1, 'coupon_record_id':1},
                        {'policy_id':2, '':'course_id':2, 'coupon_record_id':2},
                    ],
                    coupon_record_id:1,
                    alipay: 99,
                    balance: 1
                }
            :param request: 
            :param args: 
            :param kwargs: 
            :return: 
            """
            response = {'code': 1000}
            try:
                # 用户请求验证
                policy_course_list = request.data.get('course_price_list')
                coupon_record_id = request.data.get('coupon_record_id')
                alipay = request.data.get('alipay')  # >= 0
                balance = request.data.get('balance')  # >= 0
    
                if balance > request.user.balance:
                    raise Exception('账户中贝里余额不足')
    
                # 检查用户提交的信息在 redis结算列表 中是否存在,如果不存在,则需要用户从购物车中再次去结算
                payment_dict_bytes = redis_pool.conn.hget(settings.REDIS_PAYMENT_KEY, request.user.id)
                payment_dict = json.loads(payment_dict_bytes.decode('utf-8'))
                policy_course_dict = payment_dict['policy_course_dict']
                global_coupon_record_dict = payment_dict['global_coupon_record_dict']
    
                global_coupon_record = {}
                # 全局优惠券
                if coupon_record_id:
                    if  coupon_record_id not in global_coupon_record_dict:
                        raise Exception('全局优惠券在缓存中不存在')
                    global_coupon_record = global_coupon_record_dict[coupon_record_id]
    
                # 当前时间
                current_date = datetime.datetime.now().date()
                current_datetime = datetime.datetime.now()
    
                # 原价
                total_price = 0
                # 总抵扣的钱
                discount = 0
                # 使用优惠券ID列表
                if coupon_record_id:
                    use_coupon_record_id_list = [coupon_record_id, ]
                else:
                    use_coupon_record_id_list=[]
                # 课程和优惠券
                buy_course_record = []
    
                for cp in policy_course_list:
                    _policy_id = cp['policy_id']
                    _course_id = cp['course_id']
                    _coupon_record_id = cp['coupon_record_id']
    
                    temp = {
                        'course_id': _course_id,
                        'course_name': "course",
                        'valid_period': 0,  # 有效期:30
                        'period': 0,  # 有效期:一个月
                        'original_price': 0,
                        'price': 0,
                    }
    
    
                    if str(_course_id) not in policy_course_dict:
                        raise Exception('课程在缓存中不存在')
    
                    redis_course = policy_course_dict[str(_course_id)]
    
                    if str(_policy_id) != str(redis_course['policy_id']):
                        raise Exception('价格策略在缓存中不存在')
    
                    # 课程是否已经下线或价格策略被修改
                    policy_object = models.PricePolicy.objects.get(id=_policy_id)  # 价格策略对象
                    course_object = policy_object.content_object  # 课程对象
    
                    if course_object.id != _course_id:
                        raise Exception('课程和价格策略对应失败')
                    if course_object.status != 0:
                        raise Exception('课程已下线,无法购买')
    
                    # 选择的优惠券是否在缓存中
                    redis_coupon_list = redis_course['coupon_record_list']
                    redis_coupon_record = None
                    for item in redis_coupon_list:
                        if item['id'] == _coupon_record_id:
                            redis_coupon_record = item
                            break
                    if not redis_coupon_record:
                        raise Exception('单课程优惠券在缓存中不存在')
    
                    # 计算购买原总价
                    total_price += policy_object.price
    
                    # 未使用单课程优惠券
                    if redis_coupon_record['id'] == 0:
                        temp['price'] = policy_object.price
                        buy_course_record.append(temp)
                        continue
    
                    temp['original_price'] = policy_object.price
                    temp['valid_period'] = redis_coupon_record['policy_valid_period']
                    temp['period'] = redis_coupon_record['policy_period']
    
                    # 缓存中的优惠券是否已经过期
                    begin_date = redis_coupon_record.get('begin_date')
                    end_date = redis_coupon_record.get('end_date')
                    if begin_date:
                        if current_date < begin_date:
                            raise Exception('优惠券使用还未到时间')
                    if end_date:
                        if current_date > end_date:
                            raise Exception('优惠券已过期')
    
                    # 使用的是单课程优惠券抵扣了多少钱;使用的 个人优惠券ID
                    if redis_coupon_record['type'] == 0:
                        # 通用优惠券
                        money = redis_coupon_record['money_equivalent_value']
                        discount += money
                    elif redis_coupon_record['type'] == 1:
                        # 满减券
                        money = redis_coupon_record['money_equivalent_value']
                        minimum_consume = redis_coupon_record['minimum_consume']
                        if policy_object.price >= minimum_consume:
                            discount += money
                    elif redis_coupon_record['type'] == 2:
                        # 打折券
                        money = policy_object.price * redis_coupon_record['off_percent']
                        discount += money
    
                    temp['price'] = policy_object.price - money
                    buy_course_record.append(temp)
                    use_coupon_record_id_list.append(redis_coupon_record['id'])
    
                # 全局优惠券
                print(global_coupon_record)
                begin_date = global_coupon_record.get('begin_date')
                end_date = global_coupon_record.get('end_date')
                if begin_date:
                    if current_date < begin_date:
                        raise Exception('优惠券使用还未到时间')
                if end_date:
                    if current_date > end_date:
                        raise Exception('优惠券已过期')
    
                # 使用全局优惠券抵扣了多少钱
                if global_coupon_record.get('type') == 0:
                    # 通用优惠券
                    money = global_coupon_record['money_equivalent_value']
                    discount += money
                elif global_coupon_record.get('type') == 1:
                    # 满减券
                    money = global_coupon_record['money_equivalent_value']
                    minimum_consume = global_coupon_record['minimum_consume']
                    if (total_price - discount) >= minimum_consume:
                        discount += money
                elif global_coupon_record.get('type') == 2:
                    # 打折券
                    money = (total_price - discount) * global_coupon_record['off_percent']
                    discount += money
    
                # 贝里抵扣的钱
                if balance:
                    discount += balance
    
                if (alipay + discount) != total_price:
                    raise Exception('总价、优惠券抵扣、贝里抵扣和实际支付的金额不符')
    
                # 创建订单 + 支付宝支付
                # 创建订单详细
                # 贝里抵扣 + 贝里记录
                # 优惠券状态更新
                actual_amount = 0
                if alipay:
                    payment_type = 1  # 支付宝
                    actual_amount = alipay
                elif balance:
                    payment_type = 3  # 贝里
                else:
                    payment_type = 2  # 优惠码
    
                with transaction.atomic():
                    order_num = generate_order_num()
                    if payment_type == 1:
                        order_object = models.Order.objects.create(
                            # 支付类型
                            payment_type=payment_type,
                            # 订单号码
                            order_number=order_num,
                            # 用户对象
                            account=request.user,
                            # 支付的金额
                            actual_amount=actual_amount,
                            # 支付状态
                            status=1,  # 待支付
                        )
                    else:
                        order_object = models.Order.objects.create(
                            # 支付类型
                            payment_type=payment_type,
                            # 订单编号
                            order_number=order_num,
                            # 用户名
                            account=request.user,
                            # 支付金额
                            actual_amount=actual_amount,
                            status=0,  # 支付成功,优惠券和贝里已够支付
                            # 支付时间
                            pay_time=current_datetime
                        )
    
                    for item in buy_course_record:
    
                        detail = models.OrderDetail.objects.create(
                            # 订单ID
                            order=order_object,
                            #课程对象
                            content_object=models.Course.objects.get(id=item['course_id']),
                            # 原价
                            original_price=item['original_price'],
                            # 支付价
                            price=item['price'],
                            #有效周期
                            valid_period_display=item['period'],
                            valid_period=item['valid_period']
                        )
    
                    models.Account.objects.filter(id=request.user.id).update(balance=F('balance') - balance)
                    models.TransactionRecord.objects.create(
                        account=request.user,
                        amount=request.user.balance,
                        balance=request.user.balance - balance,
                        transaction_type=1,
                        content_object=order_object,
                        transaction_number=generate_transaction_num()
                    )
                    effect_row = models.CouponRecord.objects.filter(id__in=use_coupon_record_id_list).update(
                        order=order_object,
                        used_time=current_datetime)
    
    
                    if effect_row != len(use_coupon_record_id_list):
                        raise Exception('优惠券使用失败')
    
                    response['payment_type'] = payment_type
                    # 生成支付宝URL地址
                    if payment_type == 1:
                        pay = AliPay(debug=True)
                        query_params = pay.direct_pay(
                            subject="路飞学城",  # 商品简单描述
                            out_trade_no=order_num,  # 商户订单号
                            total_amount=actual_amount,  # 交易金额(单位: 元 保留俩位小数)
                        )
                        pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format(query_params)
    
                        response['pay_url'] = pay_url
    
            except IndentationError as e:
                response['code'] = 1001
                response['msg'] = str(e)
    
            return Response(response)

    我写的

    from rest_framework.views import APIView
    from rest_framework.response import Response
    from django.core.exceptions import ObjectDoesNotExist
    from api import models
    from api.utils.auth.api_view import AuthAPIView
    from api.utils.exception import PricePolicyDoesNotExist
    from pool import POOL
    import json
    import ast
    from django.conf import settings
    
    import redis
    
    CONN = redis.Redis(connection_pool=POOL)
    
    
    class BuyView(AuthAPIView, APIView):
    
        def get(self, request, *args, **kwargs):
          passdef post(self, request, *args, **kwargs):
            """
                    查看购物车
                    :param request:
                    :param args:
                    :param kwargs:
                    :return:
                    """
            course = CONN.hget(settings.LUFFY_SHOPPING_CAR, request.user.id)
            print("c", course)
            course_dict = json.loads(course.decode("utf-8"))
            user_data = {
                "course": {
    
                    "1": {
                        "id": 1,
                        "img": "/img/xx/1.png",
                        "title": "21天学Python",
                        "price": 90,
                        "课程优惠卷_dict": {
                            1: {
                                "id": 1,
                                "优惠券类型": "满减",
                                "price": 9.9,
                                "开始时间": "2018-3-1",
                                "结束时间": "2018-3-15",
                                "最低消费": 100
                            },
                            2: {
                                "id": 2,
                                "优惠券类型": "折扣",
                                "price": 70,
                                "开始时间": "2018-3-1",
                                "结束时间": "2018-3-15",
                                "最低消费": 0
                            },
                            3: {
                                "id": 3,
                                "valid_period": "3个月",
                                "price": 23.9
                            }
                        },
                        "default_coupon_id": 2
                    }
    
                },
                "quanju": {
                    "贝利": 100,
                    "全局优惠卷_dict": {
                        1: {
                            "id": 1,
                            "优惠券类型": '通用',
    
                            "price": 9.9,
                            "开始时间": "2018-3-1",
                            "结束时间": "2018-3-15",
                            "最低消费": 0
                        },
                        2: {
                            "id": 2,
                            "valid_period": "2个月",
                            "price": 15.9
                        }
                    },
                    "default_coupon_id": 1
                }
    
            }
            # 1.
            course_id = request.data.get('course_id')
            default_coupon_id = request.data.get('default_coupon_id')
            global_default_coupon_id = request.data.get('global_default_coupon_id')
    
    
            data = CONN.hget(settings.BUY, request.user.id)
    
            ######################################################
            ret = {
                "code": 1000,
    
            }
            data = data.decode('utf-8')
            user_dict = ast.literal_eval(data)
            if course_id in user_dict['course'].keys():
                if default_coupon_id in user_dict['course'][course_id]['课程优惠卷_dict'].keys():
                    user_dict['course'][str(course_id)]['default_coupon_id'] = default_coupon_id
                else:
                    user_dict['course'][str(course_id)]['default_coupon_id'] = None
                    ret['code'] = '10042'
                    ret['err'] = '课程优惠券ID不存在'
            else:
                ret['code'] = '10041'
                ret['err'] = '课程ID不存在'
            if global_default_coupon_id in user_dict['quanju']['全局优惠卷_dict'].keys():
                user_dict['quanju']['default_coupon_id'] = global_default_coupon_id
            else:
                user_dict['quanju']['default_coupon_id'] = None
                ret['code'] = '1005'
                ret['err'] = '全局优惠券ID不存在'
            for course_id, each_course in user_dict['course'].items():
                # 优惠券ID
                coupon_id = each_course['default_coupon_id']
                # 判断优惠券的类型,计算每个课程折扣后的价格
                print('c', each_course)
                try:
                    if each_course['课程优惠卷_dict'][coupon_id]['优惠券类型'] == '折扣':
                        course_discount = each_course['price'] * each_course['课程优惠卷_dict'][coupon_id]['price'] * 0.01
                    elif each_course['课程优惠卷_dict'][coupon_id]['优惠券类型'] == '满减':
                        print('cccc', each_course,course_id)
                        if each_course['课程优惠卷_dict'][coupon_id]['最低消费'] <= each_course['price']:
    
                            course_discount = each_course['price'] - each_course[coupon_id]['price']
                        else:
                            ret['err'] = '课程优惠卷没有达到最低消费的需求'
                            ret['code'] = '10021'
                    elif each_course['课程优惠卷_dict'][coupon_id]['优惠券类型'] == '通用':
                        course_discount = each_course['price'] - each_course[coupon_id]['price']
    
                    else:
                        ret['err'] = '没有这个优惠券类型'
                        ret['code'] = '10011'
                    each_course['course_discount'] = course_discount
                except KeyError:
                    course_discount = 0
    
            default_coupon_id = user_dict['quanju']['default_coupon_id']
            # 计算折扣后课程总价格
            from functools import reduce
            course_sum = reduce(lambda x, y: x['course_discount'] + y['course_discount'], user_dict['course'].values())
            if isinstance(course_sum, dict):
                print('sum',course_sum)
                try:
                    course_sum = course_sum['course_discount']
                except KeyError:
                    course_sum = course_sum['price']
            # 计算全局优惠价格
            import time
            import datetime
            try:
                start_time = user_dict['quanju']['全局优惠卷_dict'][default_coupon_id]['开始时间']
                end_time = user_dict['quanju']['全局优惠卷_dict'][default_coupon_id]['结束时间']
                current_time = datetime.datetime.now()
                print(datetime.datetime.timetuple(current_time) > time.strptime(start_time, '%Y-%m-%d'))
                print(datetime.datetime.timetuple(current_time) < time.strptime(end_time, '%Y-%m-%d'))
                if datetime.datetime.timetuple(current_time) > time.strptime(start_time,
                                                                             '%Y-%m-%d') and datetime.datetime.timetuple(
                        current_time - datetime.timedelta(-1)) < time.strptime(end_time, '%Y-%m-%d'):
    
                    if user_dict['quanju']['全局优惠卷_dict'][default_coupon_id]['优惠券类型'] == '折扣':
                        global_discount = course_sum * user_dict['quanju']['全局优惠卷_dict'][default_coupon_id]['price']
                    elif user_dict['quanju']['全局优惠卷_dict'][default_coupon_id]['优惠券类型'] == '满减':
                        if user_dict['quanju']['全局优惠卷_dict'][default_coupon_id]['最低消费'] <= course_sum:
                            global_discount = course_sum - user_dict['quanju']['全局优惠卷_dict'][default_coupon_id]['price']
                        else:
                            ret['err'] = '全局没有达到最低消费的需求'
                            ret['code'] = '10022'
                    elif user_dict['quanju']['全局优惠卷_dict'][default_coupon_id]['优惠券类型'] == '通用':
                        global_discount = course_sum - user_dict['quanju']['全局优惠卷_dict'][default_coupon_id]['price']
                    else:
    
                        ret['err'] = '没有这个优惠券类型'
                        ret['code'] = '10012'
                else:
                    ret['err'] = '优惠券在当前时间不可用'
                    ret['code'] = '1003'
                    global_discount = course_sum
            except KeyError:
                global_discount = course_sum
                # 贝利金额
            beili = user_dict['quanju']['贝利']
            # 总原价
            original_price = reduce(lambda x, y: x['price'] + y['price'], user_dict['course'].values())
            if isinstance(original_price, dict):
                original_price = original_price['price']
            # 最总支付价格
            if global_discount >= beili:
                pay_discount = global_discount - beili
                user_dict['quanju']['花费贝利'] = beili
                beili = 0
            else:
                pay_discount = 0
                user_dict['quanju']['花费贝利'] = global_discount
                beili -=global_discount
            user_dict['quanju']['贝利'] = beili
            user_dict['quanju']['pay_discount'] = pay_discount
    
            # 总优惠劵抵扣
            deduction_price = original_price - pay_discount - user_dict['quanju']['花费贝利']
            user_dict['quanju']['deduction_price'] = deduction_price
    
            CONN.hset(settings.BUY, request.user.id, user_data)
    
            print(user_dict)
            ret['data'] = user_dict
            # return Response(course_dict)
            return Response(ret)
    
        def post2(self, request, *args, **kwargs):
            """
            获取课程ID和价格策略ID,放入redis
            :param request:
            :param args:
            :param kwargs:
            :return:
            """
            ret = {"code": 1000, "msg": None}
            print(request.data)
            try:
                course_id = request.data.get("course_id")
                price_policy_id = request.data.get("price_policy_id")
                # 1. 获取课程
                course_obj = models.Course.objects.get(id=course_id)
    
                # 2. 获取当前课程的所有价格策略: id, 有效期,价格
                price_policy_list = []
                flag = False
                price_policy_objs = course_obj.price_policy.all()
                print("price_policy_objs", price_policy_objs)
                for item in price_policy_objs:
                    print(item.id, price_policy_id, type(item.id), type(price_policy_id))
                    if item.id == price_policy_id:
                        flag = True
                    price_policy_list.append(
                        {"id": item.id, "valid_period": item.get_valid_period_display(), "price": item.price})
                if not flag:
                    raise PricePolicyDoesNotExist()
    
                # 3. 课程和价格策略均没有问题,将课程和价格策略放到redis中
                # 课程id,课程图片地址,课程标题,所有价格策略,默认价格策略
                course_dict = {
                    "id": course_obj.id,
                    "img": course_obj.course_img,
                    "title": course_obj.name,
                    "price_policy_list": price_policy_list,
                    "default_policy_id": price_policy_id
                }
                print(course_dict)
                # a. 获取当前用户购物车中的课程 car = {1: {,,,}, 2:{....}}
                # b. car[course_obj.id] = course_dict
                # c. conn.hset("luffy_shopping_car",request.user.id,car)
                nothing = CONN.hget(settings.LUFFY_SHOPPING_CAR, request.user.id)
                print("n", nothing)
                if not nothing:
                    data = {course_obj.id: course_dict}
                else:
                    data = json.loads(nothing.decode("utf-8"))
                    data[course_obj.id] = course_dict
    
                CONN.hset(settings.LUFFY_SHOPPING_CAR, request.user.id, json.dumps(data))
    
            except ObjectDoesNotExist as e:
                ret["code"] = 1001
                ret["msg"] = "课程不存在"
            except PricePolicyDoesNotExist as e:
                ret["code"] = 1002
                ret["msg"] = "价格策略不存在"
            except Exception as e:
                ret["code"] = 1003
                ret["msg"] = "添加购物车异常"
    
            return Response(ret)
    
        """
        conn = {
            "LUFFY_SHOPPING_CAR":{
                "user_id":{
                    "course_id":{
                        "id": course_obj.id,
                        "img": course_obj.course_img,
                        "title": course_obj.name,
                        "price_policy_list": price_policy_list,
                        "default_policy_id": price_policy_id
                    }
                }
            }
        }"""
    
        def put(self, request, *args, **kwargs):
            ret = {"code": "1000"}
            course_id = request.data.get("course_id")
            valid_period_id = request.data.get("valid_period_id")
            user_dict_str = CONN.hget(settings.LUFFY_SHOPPING_CAR, request.user.id)
            user_course_dict = json.loads(user_dict_str)
            user_course_dict[course_id]["default_policy_id"] = valid_period_id
            CONN.hset(settings.LUFFY_SHOPPING_CAR, request.user.id, json.dumps(user_course_dict))
    
            return Response(ret)

    2.支付宝支付接口

    支付宝支付接口需要传入的数据有:

    支付的链接地址

    商户的ID

    支付成功后跳转的链接地址

    from django.shortcuts import render, redirect, HttpResponse
    from api.utils.alipay import AliPay
    import json
    import time
    
    
    def ali():
        # 沙箱环境地址:https://openhome.alipay.com/platform/appDaily.htm?tab=info
        app_id = "2016091100487187"
        # POST请求,用于最后的检测
        notify_url = "http://47.94.172.250:8804/page2/"
        # notify_url = "http://www.wupeiqi.com:8804/page2/"
    
        # GET请求,用于页面的跳转展示
        return_url = "http://47.94.172.250:8804/page2/"
        # return_url = "http://www.wupeiqi.com:8804/page2/"
    
        merchant_private_key_path = "keys/app_private_2048.txt"
        alipay_public_key_path = "keys/alipay_public_2048.txt"
    
        alipay = AliPay(
            appid=app_id,
            app_notify_url=notify_url,
            return_url=return_url,
            app_private_key_path=merchant_private_key_path,
            alipay_public_key_path=alipay_public_key_path,  # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥
            debug=True,  # 默认False,
        )
        return alipay
    
    
    def page1(request):
        if request.method == "GET":
            return render(request, 'page1.html')
        else:
            money = float(request.POST.get('money'))
            alipay = ali()
            # 生成支付的url
            query_params = alipay.direct_pay(
                subject="充气式韩红",  # 商品简单描述
                out_trade_no="x2" + str(time.time()),  # 商户订单号
                total_amount=money,  # 交易金额(单位: 元 保留俩位小数)
            )
    
            pay_url = "https://openapi.alipaydev.com/gateway.do?{}".format(query_params)
    
            return redirect(pay_url)
    
    
    def page2(request):
        alipay = ali()
        if request.method == "POST":
            # 检测是否支付成功
            # 去请求体中获取所有返回的数据:状态/订单号
            from urllib.parse import parse_qs
            body_str = request.body.decode('utf-8')
            post_data = parse_qs(body_str)
    
            post_dict = {}
            for k, v in post_data.items():
                post_dict[k] = v[0]
            print(post_dict)
    
            sign = post_dict.pop('sign', None)
            status = alipay.verify(post_dict, sign)
            print('POST验证', status)
            return HttpResponse('POST返回')
    
        else:
            params = request.GET.dict()
            sign = params.pop('sign', None)
            status = alipay.verify(params, sign)
            print('GET验证', status)
            return HttpResponse('支付成功')
  • 相关阅读:
    python学习-类属性和实例属性
    python学习-名字管理
    phalcon安装-遇坑php-config is not installed 解决方法
    利用scp 远程上传下载文件/文件夹
    linux tar打包
    ELK logstash 启动慢的解决方法
    shell脚本学习
    ELK日志系统:Filebeat使用及Kibana如何设置登录认证(转)
    elastic5.4安装错误解决
    CentOS 6、7 安装 Golang
  • 原文地址:https://www.cnblogs.com/ldq1996/p/8576560.html
Copyright © 2011-2022 走看看