支付宝沙箱环境的使用

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

  • 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 %}
向后台发起查询请求
原文地址:https://www.cnblogs.com/maoxinjueluo/p/12889863.html