yifengs

安装python-alipay-sdk

pip install python-alipay-sdk --upgrade

配置

 

 视图函数orders/views.py

# 订单支付
# /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.py

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.html

{% 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 %}

点击去付款,报错

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{}中

 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,解决问题,继续

让网站知道已经支付成功

视图函数views.py中添加支付查询功能

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 %}

 

posted on 2019-10-17 13:12  BZ易风  阅读(294)  评论(0编辑  收藏  举报

分类:

技术点:

相关文章: