django-支付寶支付

安裝python-alipay-sdkhtml

pip install python-alipay-sdk --upgrade

配置python

 

 視圖函數orders/views.pyjquery

# 訂單支付
# /order/pay
from alipay import AliPay, ISVAliPay
import os
from django.conf import settings
class OrderPayView(View):
    def post(self, request):
        '''支付頁面'''
        # 判斷用戶是否登陸
        user = request.user
        if not user.is_authenticated():
            return JsonResponse({'res':0, 'errmsg':'用戶還沒有登陸'})
        # 接收訂單id
        order_id = request.POST.get('order_id')
        # 校驗訂單id
        if not order_id:
            return JsonResponse({'res':1, 'errmsg':'無效的訂單id'})
        # 查詢訂單信息
        try:
            order = OrderInfo.objects.get(order_id=order_id, user=user, pay_method=3, order_status=1)
        except OrderInfo.DoesNotExist:
            return JsonResponse({'res':2, 'errmsg':'訂單錯誤'})

        # 業務處理 使用python sdk調用支付寶的支付接口
        # 支付寶信息   不能放在settings裏 會報錯
        alipay = AliPay(
            appid="2016101200665304",
            app_notify_url=None,  # 默認回調url  若是爲空的話不能用'' 要用None
            # 我的私鑰
            app_private_key_string=os.path.join(settings.BASE_DIR, 'apps/orders/app_private_key.pem'),
            # 支付寶的公鑰,驗證支付寶回傳消息使用,不是你本身的公鑰,
            alipay_public_key_string=os.path.join(settings.BASE_DIR, 'apps/orders/alipay_public_key.pem'),
            # 加密方式
            sign_type="RSA2",  # RSA 或者 RSA2
            # 沙箱是True 正式環境是False
            debug=True  # 默認False
        )
        # 調用支付接口
        # 電腦網站支付,須要跳轉到https://openapi.alipay.com/gateway.do? + order_string 實際地址
        # 沙箱地址 https://openapi.alipaydev.com/gateway.do? + order_string  沙箱地址在alipay後面加上dev
        total_price = order.total_price + order.transit_price  # Decimal
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_id,  # 訂單id
            total_amount=str(total_price),  # 支付總金額 由於Decimal格式不能序列化 因此先轉成字符串
            subject='每天生鮮%s'%order_id,
            return_url=None,
            notify_url=None  # 可選, 不填則使用默認notify url
        )
        # 返回應答
        pay_url = 'https://openapi.alipaydev.com/gateway.do?' + order_string
        return JsonResponse({'res':3, 'pay_url':pay_url})

配置路由urls.pylinux

from django.conf.urls import url
from orders.views import OrderPlaceView, OrderCommitView, OrderPayView


urlpatterns = [
    url(r'^place$', OrderPlaceView.as_view(), name='place'),  # 提交訂單頁面
    url(r'^commit$', OrderCommitView.as_view(), name='commit'),  # 提交訂單處理
    url(r'^pay$', OrderPayView.as_view(), name='pay'),  # 訂單支付

]

 用戶訂單頁面user_center_order.htmlajax

{% block bottomfiles %}
<script src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
<script>
    $('.oper_btn').each(function(){
        //獲取支付狀態
        status = $(this).attr('status')
        if (status == 1){
            $(this).text('去付款')
        }else if (status == 4){
            $(this).text('去評價')
        }else if (status == 5){
            $(this).text('已完成')
        }
    })
    $('.oper_btn').click(function () {
        // 獲取status
        status = $(this).attr('status')
        // 獲取訂單id
        order_id = $(this).attr('order_id')
        console.log(status)
        if (status == 1){
            // 進行支付
            csrf = $('input[name="csrfmiddlewaretoken"]').val()
            // 組織參數
            params = {'order_id':order_id, 'csrfmiddlewaretoken':csrf}
            // 發起ajax post請求,訪問/order/pay, 傳遞參數:order_id
 $.post('/order/pay', params, function (data) { if (data.res == 3){ // 引導用戶到支付頁面
 window.open(data.pay_url)  } else{ alert(data.errmsg) } })
        }
        else if (status == 4){
            // 其餘狀況
            // 跳轉到評價頁面
            location.href = '/order/comment/'+order_id
        }
    })
</script>
{% endblock bottomfiles %}

點擊去付款,報錯django

ValueError at /order/pay
RSA key format is not supported

Request Method: POST
Request URL: http://192.168.199.130:8000/order/pay
Django Version: 1.8.2
Python Executable: /home/python/.virtualenvs/bj19/bin/python
Python Version: 3.5.2
Python Path: ['/home/python/bj19/ttsx/dailyfresh/apps', '/home/python/bj19/ttsx/dailyfresh', '/home/python/.virtualenvs/bj19/lib/python35.zip', '/home/python/.virtualenvs/bj19/lib/python3.5', '/home/python/.virtualenvs/bj19/lib/python3.5/plat-x86_64-linux-gnu', '/home/python/.virtualenvs/bj19/lib/python3.5/lib-dynload', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/home/python/.virtualenvs/bj19/lib/python3.5/site-packages', '/home/python/bj19/ttsx/dailyfresh']
Server time: 星期四, 17 十月 2019 15:21:03 +0800
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'tinymce',
 'user',
 'cart',
 'goods',
 'orders',
 'haystack')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware')

Traceback:
File "/home/python/.virtualenvs/bj19/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/python/.virtualenvs/bj19/lib/python3.5/site-packages/django/views/generic/base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)
File "/home/python/.virtualenvs/bj19/lib/python3.5/site-packages/django/views/generic/base.py" in dispatch
  89.         return handler(request, *args, **kwargs)
File "/home/python/bj19/ttsx/dailyfresh/apps/orders/views.py" in post
  374.             debug=True  # 默认False
File "/home/python/.virtualenvs/bj19/lib/python3.5/site-packages/alipay/__init__.py" in __init__
  81.         self._load_key()
File "/home/python/.virtualenvs/bj19/lib/python3.5/site-packages/alipay/__init__.py" in _load_key
  89.         self._app_private_key = RSA.importKey(content)
File "/home/python/.virtualenvs/bj19/lib/python3.5/site-packages/Cryptodome/PublicKey/RSA.py" in import_key
  754.     raise ValueError("RSA key format is not supported")

Exception Type: ValueError at /order/pay
Exception Value: RSA key format is not supported
Request information:
GET: No GET data

查找緣由 視圖函數中Alipay{}中api

 alipay = AliPay(
            appid="2016101200665304",
            app_notify_url=None,  # 默認回調url  若是爲空的話不能用'' 要用None
            # 我的私鑰
            app_private_key_path=os.path.join(settings.BASE_DIR, 'keys/app_private_key.pem'),  # 此處是路徑用path 不是string
            # 支付寶的公鑰,驗證支付寶回傳消息使用,不是你本身的公鑰,
            alipay_public_key_path=os.path.join(settings.BASE_DIR, 'keys/alipay_public_key.pem'),  # 此處是路徑用path 不是string
            # 加密方式
            sign_type="RSA2",  # RSA 或者 RSA2
            # 沙箱是True 正式環境是False
            debug=True  # 默認False
        )

OK,解決問題,繼續瀏覽器

讓網站知道已經支付成功session

視圖函數views.py中添加支付查詢功能app

class OrderCheckView(View):
    def post(self, request):
        '''支付查詢頁面'''
        # 判斷用戶是否登陸
        user = request.user
        if not user.is_authenticated():
            return JsonResponse({'res':0, 'errmsg':'用戶還沒有登陸'})
        # 接收訂單id
        order_id = request.POST.get('order_id')
        # 校驗訂單id
        if not order_id:
            return JsonResponse({'res':1, 'errmsg':'無效的訂單id'})
        # 查詢訂單信息
        try:
            order = OrderInfo.objects.get(order_id=order_id, user=user, pay_method=3, order_status=1)
        except OrderInfo.DoesNotExist:
            return JsonResponse({'res':2, 'errmsg':'訂單錯誤'})

        # 業務處理 使用python sdk調用支付寶的支付接口
        # 支付寶信息   不能放在settings裏 會報錯

        alipay = AliPay(
            appid="2016101200665304",
            app_notify_url=None,  # 默認回調url  若是爲空的話不能用'' 要用None
            # 我的私鑰
            app_private_key_path=os.path.join(settings.BASE_DIR, 'keys/app_private_key.pem'),
            # 支付寶的公鑰,驗證支付寶回傳消息使用,不是你本身的公鑰,
            alipay_public_key_path=os.path.join(settings.BASE_DIR, 'keys/alipay_public_key.pem'),
            # 加密方式
            sign_type="RSA2",  # RSA 或者 RSA2
            # 沙箱是True 正式環境是False
            debug=True  # 默認False
        )

        # 調用支付寶交易查詢接口
        while True:
            response = alipay.api_alipay_trade_query(order_id)

            # response = {
            #     "alipay_trade_query_response": {
            #         "trade_no": "2017032121001004070200176844",  # 支付寶交易號
            #         "code": "10000",  # 返回碼
            #         "invoice_amount": "20.00",
            #         "open_id": "20880072506750308812798160715407",
            #         "fund_bill_list": [
            #             {
            #                 "amount": "20.00",
            #                 "fund_channel": "ALIPAYACCOUNT"
            #             }
            #         ],
            #         "buyer_logon_id": "csq***@sandbox.com",
            #         "send_pay_date": "2017-03-21 13:29:17",
            #         "receipt_amount": "20.00",
            #         "out_trade_no": "out_trade_no15",
            #         "buyer_pay_amount": "20.00",
            #         "buyer_user_id": "2088102169481075",
            #         "msg": "Success",
            #         "point_amount": "0.00",
            #         "trade_status": "TRADE_SUCCESS",  # 交易狀態:WAIT_BUYER_PAY(交易建立,等待買家付款)、TRADE_CLOSED(未付款交易超時關閉,或支付完成後全額退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易結束,不可退款)
            #         "total_amount": "20.00"
            #     },
            #     "sign": ""
            # }

            code = response.get('code')
            if code == '10000' and response.get('trade_status') == 'TRADE_SUCCESS':
                # 支付成功
                # 獲取支付寶交易號
                trade_no = response.get('trade_no')
                # 更新訂單狀態
                order.trade_no = trade_no
                order.order_status = 4
                order.save()  # 更新
                # 返回結果
                return JsonResponse({'res':3, 'message':'支付成功'})
            elif code =='40004' or (code == '10000' and response.get('trade_status') == 'WAIT_BUYER_PAY'):
                # 等待買家付款
                import time
                time.sleep(5)
                continue  # 跳過本次循環 從新開始循環
            else:
                # 支付出錯
                return JsonResponse({'res':4, 'errmsg':'支付失敗'})

模板中ajax轉到查詢

{% block bottomfiles %}
<script src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
<script>
    $('.oper_btn').each(function(){
        //獲取支付狀態
        status = $(this).attr('status')
        if (status == 1){
            $(this).text('去付款')
        }else if (status == 4){
            $(this).text('去評價')
        }else if (status == 5){
            $(this).text('已完成')
        }
    })
    $('.oper_btn').click(function () {
        // 獲取status
        status = $(this).attr('status')
        // 獲取訂單id
        order_id = $(this).attr('order_id')
        console.log(status)
        if (status == 1){
            // 進行支付
            csrf = $('input[name="csrfmiddlewaretoken"]').val()
            // 組織參數
            params = {'order_id':order_id, 'csrfmiddlewaretoken':csrf}
            // 發起ajax post請求,訪問/order/pay, 傳遞參數:order_id
            $.post('/order/pay', params, function (data) {
                if (data.res == 3){
                    // 引導用戶到支付頁面
                    window.open(data.pay_url)
                    // 瀏覽器訪問/order/check, 獲取支付交易的結果
                    // ajax post 傳遞參數:order_id
 $.post('/order/check', params, function (data){ if (data.res == 3){ alert(data.message) // 刷新頁面
 location.reload() } else{ alert(data.errmsg) } })
                }
                else{
                    alert(data.errmsg)
                }
            })
        }
        else if (status == 4){
            // 其餘狀況
            // 跳轉到評價頁面
            location.href = '/order/comment/'+order_id
        }
    })
</script>
{% endblock bottomfiles %}
相關文章
相關標籤/搜索