支付寶沙箱環境的使用


電腦網站的支付流程以及支付寶沙箱環境使用前的配置

  • 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 %}
向后台發起查詢請求

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM