• 支付宝沙箱环境的使用


    电脑网站的支付流程以及支付宝沙箱环境使用前的配置

    • 1、电脑网站的支付流程                                                

    •  2、支付宝沙箱环境的介绍以及使用前的配置                                           

     使用前的配置配置

    • 1、打开网站,使用已有的支付宝账号登录

    https://open.alipay.com/platform/home.htm

    • 2、点击开发者中心 ----  研发中心 -------- 沙箱应用 -------- 设置密钥

     

    •  3、公钥和密钥的介绍

    用户需要有自己的公钥和密钥,密钥由自己保持,作用是将发送给支付宝网站的数据进行加密,并且用户需要将自己的公钥告诉支付宝,支付宝可以用公钥进行解密。同样的,用户也需要拿到支付宝的公钥。

    •  4、生成公钥和私钥

    window系统可以使用支付宝提供的软件进行公钥和私钥的生成

     复制公钥,粘贴在上面打开的沙箱应用 ----- RSA2密钥设置中

     同时保存支付宝的公钥

    在项目中创建文件夹key,专门存放用户私钥和支付宝公钥

    在文件夹key中,创建两个文件 alipay_public_key.pem(存放支付宝公钥)和app_private_key.pem(存放用户私钥)

     分别打开,将私钥和公钥复制进去,格式:

    -----BEGIN RSA PRIVATE KEY-----
       公钥或者私钥复制在这里
    -----END RSA PRIVATE KEY-----

    将两个文件的绝对路径加入到项目settings文件中

    ##  公钥和私钥的地址
    APP_PRIVATE_KEY_PATH = os.path.join(BASE_DIR,'key/app_private_key.pem')
    ALIPAY_PUBLIC_KEY_PATH = os.path.join(BASE_DIR,'key/alipay_public_key.pem')
    • 5、使用python-alipay-sdk

    由于支付宝没有提供Python的alipay-SDK,所以需要借助第三方的非官方支付宝 Python SDK

    相关网址:https://github.com/fzlee/alipay/blob/master/README.zh-hans.md#alipay.trade.page.pay

    安装:

    # 从 1.3.0升级上来的用户, 请先卸载pycrypto:
    pip uninstall pycrypto
    # 安装python-alipay-sdk
    pip install python-alipay-sdk --upgrade

    天天生鲜项目的订单支付

    • 1、订单支付的逻辑分析

    当用户在前端点击订单支付时,需要将订单的id传递到后台,后台需要对数据进行校验,并连接支付宝沙箱,并传递支付链接,引导用户跳转到支付链接

    • 2、订单支付的视图函数和模板文件

    from alipay import AliPay
    
    ##  使用支付宝付款,接收的参数:订单id:order_id  参数校验之后引导用户跳转到支付页面
    class OrderPayView(View):
        '''支付处理'''
        def post(self,request):
            '''支付处理'''
            order_id = request.POST.get('order_id')
    
            ##  1、 参数校验
            user = request.user
            if not user.is_authenticated:
                return JsonResponse({'res':0,'errmsg':'用户未登录'})
            if not order_id:
                return JsonResponse({'res':1,'errmsg':'参数不完整'})
            try:
                order = OrderInfo.objects.get(order_id=order_id)
                ##  计算订单的总金额,转化成字符串格式
                total_amount = order.total_price+order.transit_price
                total_amount = str(total_amount)
            except OrderInfo.DoesNoExist:
                return JsonResponse({'res':2,'errmsg':'订单不存在'})
    
            ##  业务处理
            ##  支付初始化
    
            app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read()
            alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read()
    
            alipay = AliPay(
                appid='2016102400751639',
                app_notify_url=None,  # 默认回调url
                app_private_key_string=app_private_key_string,
                # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
                alipay_public_key_string=alipay_public_key_string,
                sign_type="RSA2" , # RSA 或者 RSA2
                debug = True  # 默认False
            )
    
            ##  接口调用
            # 电脑网站支付,需要跳转到https://openapi.alipay.com/gateway.do? + order_string
            order_string = alipay.api_alipay_trade_page_pay(
                out_trade_no=order_id,      ##  订单的编号
                total_amount=total_amount,  ##  订单的总金额
                subject='天天生鲜%s'%order_id,        ##  订单的名称
                return_url=None,
                notify_url=None
            )
    
    
            ##  3、返回应答
            pay_url = 'https://openapi.alipaydev.com/gateway.do?' + order_string
            return JsonResponse({'res':3,'pay_url':pay_url})
    {% extends 'base_user_center.html' %}
    {% load static %}
    {% block title %}天天生鲜-用户中心{% endblock title %}
    {% block right_content %}
            <div class="right_content clearfix">
                {% csrf_token %}
                    <h3 class="common_title2">全部订单</h3>
                {% for order in order_pages %}
                    <ul class="order_list_th w978 clearfix">
                        <li class="col01">{{ order.create_time }}</li>
                        <li class="col02">订单号:{{ order.order_id }}</li>
                        <li class="col02 stress">{{ order.status }}</li>
                    </ul>
    
                    <table class="order_list_table w980">
                        <tbody>
                            <tr>
                                <td width="55%">
                                    {% for order_sku in order.order_skus %}
                                        <ul class="order_goods_list clearfix">
                                        <li class="col01"><a href="{% url 'goods:detail' order_sku.sku.id %}"><img src="{{ order_sku.sku.image.url }}" ></a></li>
                                        <li class="col02">{{ order_sku.sku.name }}<em>{{ order_sku.price }}元/{{ order_sku.sku.unite }}</em></li>
                                        <li class="col03">{{ order_sku.count }}</li>
                                        <li class="col04">{{ order_sku.amount }}元</li>
                                    </ul>
                                    {% endfor %}
                                </td>
                                <td width="15%">{{ order.total_price|add:order.transit_price }}(含运费:{{ order.transit_price }})元</td>
                                <td width="15%">{{ order.status }}</td>
                                <td width="15%"><a href="#" class="oper_btn" order_status="{{ order.order_status }}" order_id="{{ order.order_id }}">去付款</a></td>
                            </tr>
                        </tbody>
                    </table>
                {% endfor %}
    
                    <div class="pagenation">
                        {% if order_pages.has_previous %}
                            <a href="{% url 'user:order' order_pages.previous_page_number %}"><上一页</a>
                        {% endif %}
                        {% for pindex in pages %}
                            {% if pindex == order_pages.number %}
                                <a href="{% url 'user:order' pindex %}" class="active">{{ pindex }}</a>
                            {% else %}
                                <a href="{% url 'user:order' pindex %}">{{ pindex }}</a>
                            {% endif %}
                        {% endfor %}
                        {% if order_pages.has_next %}
                            <a href="{% url 'user:order' order_pages.next_page_number %}">下一页></a>
                        {% endif %}
                    </div>
            </div>
    {% endblock right_content %}
    {% block bottomfiles %}
    <script src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
    <script>
        //    给去付款增加点击事件,向后台传递参数,通过验证后引导用户跳转到支付页面
        $('.oper_btn').click(function(){
            //    判断订单的支付状态,只有待支付才能付款
            var order_status = $(this).attr('order_status');
            if    (order_status == 1){
                //    准备参数: 订单id:order_id
                var order_id = $(this).attr('order_id');
                var csrf = $('input[name="csrfmiddlewaretoken"]').val();
                //    组织参数
                var context = {'order_id':order_id,'csrfmiddlewaretoken':csrf};
                //    ajax post请求,地址:/order/pay
                $.post('/order/pay',context,function(data){
                    if (data.res == 3){
                        //    通过验证,引导用户跳转到支付页面
                        window.open(data.pay_url);
                    }
                    else{
                        //通过失败
                        alert(data.errmsg);
                    }
                })
    
            }
    
        })
    </script>
    
    {% endblock bottomfiles %}
    模板文件
    • 3、订单支付结果的查询

    当用户点击支付按钮的时候,前端不仅需要通过ajax post向后台申请支付页面,还要立即通过ajax post提交向后台请求支付结果的查询

    后端查询支付结果的视图函数:

     1 ##  接收的参数:订单id:order_id
     2 class CheckPayView(View):
     3     '''查询订单支付结果'''
     4     def post(self,request):
     5         '''查询订单支付结果'''
     6         order_id = request.POST.get('order_id')
     7 
     8         ##  1、 参数校验
     9         user = request.user
    10         if not user.is_authenticated:
    11             return JsonResponse({'res': 0, 'errmsg': '用户未登录'})
    12         if not order_id:
    13             return JsonResponse({'res': 1, 'errmsg': '参数不完整'})
    14         try:
    15             order = OrderInfo.objects.get(order_id=order_id)
    16         except OrderInfo.DoesNoExist:
    17             return JsonResponse({'res': 2, 'errmsg': '订单不存在'})
    18 
    19         ##  业务处理
    20         ##  支付初始化
    21 
    22         app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read()
    23         alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read()
    24 
    25         alipay = AliPay(
    26             appid='2016102400751639',
    27             app_notify_url=None,  # 默认回调url
    28             app_private_key_string=app_private_key_string,
    29             # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
    30             alipay_public_key_string=alipay_public_key_string,
    31             sign_type="RSA2",  # RSA 或者 RSA2
    32             debug=True  # 默认False
    33         )
    34         while 1:
    35             ##  循环查询,直到查询到结果才跳出循环
    36             ##  连接到支付宝的支付查询接口
    37             response = alipay.api_alipay_trade_query(order_id)
    38 
    39             # response = {
    40             #         "trade_no": "2017032121001004070200176844", # 支付宝交易号
    41             #         "code": "10000", # 接口调用是否成功
    42             #         "invoice_amount": "20.00",
    43             #         "open_id": "20880072506750308812798160715407",
    44             #         "fund_bill_list": [
    45             #             {
    46             #                 "amount": "20.00",
    47             #                 "fund_channel": "ALIPAYACCOUNT"
    48             #             }
    49             #         ],
    50             #         "buyer_logon_id": "csq***@sandbox.com",
    51             #         "send_pay_date": "2017-03-21 13:29:17",
    52             #         "receipt_amount": "20.00",
    53             #         "out_trade_no": "out_trade_no15",
    54             #         "buyer_pay_amount": "20.00",
    55             #         "buyer_user_id": "2088102169481075",
    56             #         "msg": "Success",
    57             #         "point_amount": "0.00",
    58             #         "trade_status": "TRADE_SUCCESS", # 支付结果
    59             #         "total_amount": "20.00"
    60             # }
    61 
    62 
    63             ##  获取校验的结果并进行相应的处理
    64             code = response.get('code')     ##  接口调用
    65             trade_status = response.get('trade_status')     ##  支付结果
    66             if code == '10000' and trade_status == 'TRADE_SUCCESS':
    67                 ##  支付成功
    68                 ##  更新订单状态,返回应答
    69                 order.order_status = 4
    70                 ##  添加支付编号
    71                 order.trade_no = response.get('trade_no')
    72                 order.save()
    73                 print(order.order_status)
    74                 print('支付成功')
    75                 ##  返回应答
    76                 return JsonResponse({'res':3,'message':'支付成功'})
    77             elif code == '40004' or (code == '10000' and response.get('trade_status') == 'WAIT_BUYER_PAY'):
    78                 # 等待买家付款
    79                 # 业务处理失败,可能一会就会成功
    80                 import time
    81                 time.sleep(5)
    82                 print('这里还在等待支付')
    83                 continue
    84             else:
    85                 ##  支付失败
    86                 return JsonResponse({'res':4,'errmsg':'支付失败'})
    查询支付结果视图函数

    模板文件:

    {% extends 'base_user_center.html' %}
    {% load static %}
    {% block title %}天天生鲜-用户中心{% endblock title %}
    {% block right_content %}
            <div class="right_content clearfix">
                {% csrf_token %}
                    <h3 class="common_title2">全部订单</h3>
                {% for order in order_pages %}
                    <ul class="order_list_th w978 clearfix">
                        <li class="col01">{{ order.create_time }}</li>
                        <li class="col02">订单号:{{ order.order_id }}</li>
                        <li class="col02 stress">{{ order.status }}</li>
                    </ul>
    
                    <table class="order_list_table w980">
                        <tbody>
                            <tr>
                                <td width="55%">
                                    {% for order_sku in order.order_skus %}
                                        <ul class="order_goods_list clearfix">
                                        <li class="col01"><a href="{% url 'goods:detail' order_sku.sku.id %}"><img src="{{ order_sku.sku.image.url }}" ></a></li>
                                        <li class="col02">{{ order_sku.sku.name }}<em>{{ order_sku.price }}元/{{ order_sku.sku.unite }}</em></li>
                                        <li class="col03">{{ order_sku.count }}</li>
                                        <li class="col04">{{ order_sku.amount }}元</li>
                                    </ul>
                                    {% endfor %}
                                </td>
                                <td width="15%">{{ order.total_price|add:order.transit_price }}(含运费:{{ order.transit_price }})元</td>
                                <td width="15%">{{ order.status }}</td>
                                <td width="15%"><a href="#" class="oper_btn" order_status="{{ order.order_status }}" order_id="{{ order.order_id }}">去付款</a></td>
                            </tr>
                        </tbody>
                    </table>
                {% endfor %}
    
                    <div class="pagenation">
                        {% if order_pages.has_previous %}
                            <a href="{% url 'user:order' order_pages.previous_page_number %}"><上一页</a>
                        {% endif %}
                        {% for pindex in pages %}
                            {% if pindex == order_pages.number %}
                                <a href="{% url 'user:order' pindex %}" class="active">{{ pindex }}</a>
                            {% else %}
                                <a href="{% url 'user:order' pindex %}">{{ pindex }}</a>
                            {% endif %}
                        {% endfor %}
                        {% if order_pages.has_next %}
                            <a href="{% url 'user:order' order_pages.next_page_number %}">下一页></a>
                        {% endif %}
                    </div>
            </div>
    {% endblock right_content %}
    {% block bottomfiles %}
    <script src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
    <script>
        //    给去付款增加点击事件,向后台传递参数,通过验证后引导用户跳转到支付页面
        $('.oper_btn').click(function(){
            //    判断订单的支付状态,只有待支付才能付款
            var order_status = $(this).attr('order_status');
            if    (order_status == 1){
                //    准备参数: 订单id:order_id
                var order_id = $(this).attr('order_id');
                var csrf = $('input[name="csrfmiddlewaretoken"]').val();
                //    组织参数
                var context = {'order_id':order_id,'csrfmiddlewaretoken':csrf};
                //    ajax post请求,地址:/order/pay
                $.post('/order/pay',context,function(data){
                    if (data.res == 3){
                        //    通过验证,引导用户跳转到支付页面
                        window.open(data.pay_url);
                        //    发起ajax post 请求 /order/check ,查询订单支付结果,传递的参数:order_id
                        $.post('/order/check',context,function(data){
                            //    判断是否支付成功
                            if (data.res == 3){
                                //    支付成功,打印支付成功信息,并更新订单状态
                                alert(data.message);
                                // 刷新页面
                                location.reload()
                            }
                        })
                    }
                    else{
                        //通过失败
                        alert(data.errmsg);
                    }
                })
    
            }
    
        })
    </script>
    
    {% endblock bottomfiles %}
    向后台发起查询请求
  • 相关阅读:
    layui 标签页切换
    m1配置多个git账户
    sqlserver 获取表和字段的注释方法
    springboot+mybatisPlus 配置多数据源--转载
    nginx 配置静态网页和反向代理
    ORA-01000: maximum open cursors exceeded
    重装系统我们选择FAT还是NTFS?U盘和硬盘格式化两者选谁?
    2、条件表达式
    1、javascript 知识拓展
    1_maven 问题
  • 原文地址:https://www.cnblogs.com/maoxinjueluo/p/12889863.html
Copyright © 2020-2023  润新知