支付宝支付接入

第一步:登录支付宝开放平台,填写相关信息

支付宝接入平台
支付宝sdk文档说明

第二步:选择研发中心,研发服务
在这里插入图片描述
第三步:点击左侧沙箱应用,点击设置应用公钥,查看密钥生成方法,跳转后点击下载windows版本生成密钥工具。

第四步:将生成的密钥中的公钥复制粘贴到支付宝设置公钥的地方。

第五步:安装支付宝sdk

pip install python-alipay-sdk --upgrade

第六步:生成本地应用密钥

# openssl
OpenSSL> genrsa -out app_private_key.pem 2048  # 生成私钥
OpenSSL> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 生成公钥
OpenSSL> exit

在这里插入图片描述
第七步:将生成的公钥设置进支付宝沙箱环境中的应用公钥
在这里插入图片描述
注:只复制中间的内容,不需要虚线部分
在这里插入图片描述
第八步:查看支付宝公钥,将公钥内容保存进项目订单应用下的文件(alipay_public_key.pem)中,文件需手动创建。
在这里插入图片描述
注:虚线两行内容需要手动添加,直接复制我们生成的应用公钥文件中的即可。

第九步:将我们生成的本地应用私钥拷贝过来,和刚刚新建的支付宝公钥文件放在一起。
在这里插入图片描述
第十步:导入支付模块,编写订单支付视图处理类

<script src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
    <script>
    // 修改前端页面显示
    $('.orer_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')
      if (status == 1){
          // 进行支付      
          csrf = $('input[name="csrfmiddlewaretoken"]').val()
          // 组织参数
          params = {"order_id": order_id, "csrfmiddlewaretoken": csrf}
          // 发起 ajax post /order/pay 传递参数:order_id
          $.post('{% url "order:pay" %}', params, function (data){
              if(data.res==3){
                  // 引导用户到支付页面(重新打开一个页面)
                  window.open(data.pay_url)
                  // 浏览器访问/order/check,获取支付交易结果
                  // 传递参数:商品订单id
                  $.post('{% url "order:check" %}', params, function (data){
                      if(data.res == 3){
                          alert("支付成功")
                          // 刷新页面
                          location.reload()
                      }
                      alert(data.errmsg)
                  })
              }
              else{
                  alert(data.errmsg)
              }
          })
      }
      else if(status == 4){
		// 跳转到评价页面
		location.href = '/order/comment/' + order_id
      }
    })
    </script>

订单支付

from order.views import OrderPayView

urlpatterns = [
    url(r'^pay$', OrderPayView.as_view(), name='pay'),  # 订单支付
]
from alipay import AliPay, ISVAliPay
from django.conf import settings
import os


# ajax post
# 前端传递的参数:订单id(order_id)
# /order/pay
class OrderPayView(View):
    """订单支付"""
    def post(self, request):
        # 登录验证
        user = request.user
        
        if not user.is_authenticated():
            return JsonResponse({"res": 0, "errmsg": "用户未登录"})
     
        # 接收参数
        order_id = request.POST.get('order_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 调用支付宝支付接口
        alipay = AliPay(
            appid="2016092600601590",  # 应用id,由于我们是沙箱环境,所以直接拿沙箱应用下的APPID,实际开发环境根据自己实际应用ID填写
            app_notify_url=None,  # 支付宝默认回调函数,由于我们是本地项目,没有公网ip所以就算填写了,支付宝也访问不过来。
            app_private_key_path=os.path.join(settings.BASE_DIR, 'apps/order/app_private_key.pem'),
            # alipay public key, do not use your own public key!
            alipay_public_key_path=os.path.join(settings.BASE_DIR, 'apps/order/alipay_public_key.pem'),
            sign_type="RSA2",  # RSA or RSA2
            debug=True,  # 沙箱环境,所以需要设置为True
        )
        
        # 调用电脑支付接口
        # 电脑网站支付,需要跳转到: https://openapi.alipay.com/gateway.do? + order_string
        # 沙箱环境需要跳转地址为: https://openapi.alipaydev.com/gateway.do? + order_string
        total_amount = order.total_price + order.transit_price  # Decimal类型,所以不能被序列化,所以需要转化未str
        order_string = alipay.api_alipay_trade_wap_pay(
            out_trade_no="20161112",  # 订单id
            total_amount=str(total_amount),  # 总结额:加运费
            subject='天天生鲜%s' % order_id,  # 标题
            return_url=None,
            notify_url=None
        )
        
        # 返回应答
        pay_url = "https://openapi.alipaydev.com/gateway.do?" + order_string
        return JsonResponse({"res": 3, "pay_url": pay_url})

支付结果查询

from django.conf.urls import url
from order.views import OrderCheckPayView

urlpatterns = [
    url(r'^check$', OrderCheckPayView.as_view(), name='check'),  # 支付结果查询
]

# ajax post
# 前端传递的参数:订单id(order_id)
# /order/check
class OrderCheckPayView(View):
    """支付结果查询"""
    def post(self, request):
        """查询支付结果"""
        # 登录验证
        user = request.user

        if not user.is_authenticated()::
            return JsonResponse({"res": 0, "errmsg": "用户未登录"})

        # 接收参数
        order_id = request.POST.get('order_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 调用支付宝支付接口
        alipay = AliPay(
            appid="2016092600601590",  # 应用id,由于我们是沙箱环境,所以直接拿沙箱应用下的APPID,实际开发环境根据自己实际应用ID填写
            app_notify_url=None,  # 支付宝默认回调函数,由于我们是本地项目,没有公网ip所以就算填写了,支付宝也访问不过来。
            app_private_key_path=os.path.join(settings.BASE_DIR, 'apps/order/app_private_key.pem'),
            # alipay public key, do not use your own public key!
            alipay_public_key_path=os.path.join(settings.BASE_DIR, 'apps/order/alipay_public_key.pem'),
            sign_type="RSA2",  # RSA or RSA2
            debug=True,  # 沙箱环境,所以需要设置为True
        )

        while True:
            # 调用支付宝查询接口
            # 订单支付查询接口                 商户订单号           支付宝交易号
            # 参数必传其一,由于是测试环境,我们就使用订单编号进行查询
            # api_alipay_trade_query(self, out_trade_no=None, trade_no=None)
            response = alipay.api_alipay_trade_query(out_trade_no=order.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",  # 支付结果
                     "total_amount": "20.00"
                }
            """

            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, "errmsg": "支付成功"})

            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": "支付失败"})

订单评论

from django.conf.urls import url
from order.views import OrderCommentView

urlpatterns = [
    url(r'^comment/(?P<order_id>.+)$', OrderCommentView.as_view(), name='comment'),  # 订单评论
]
class OrderCommentView(View):
    """订单评论"""
    def get(self, request, order_id):
        """提供评论页面"""
        user = request.user

        # 校验数据
        if not order_id:
            return redirect(reverse("user:order"))

        try:
            order = OrderInfo.objects.get(order_id=order_id, user=user)
        except OrderInfo.DoesNotExist:
            return redirect(reverse("user:order"))

        # 根据订单的状态获取订单状态标题
        order.status_name = OrderInfo.ORDER_STATUS(order.order_status)

        # 获取订单商品信息
        order_skus = OrderGoods.objects.filter(order_id=order_id)

        for order_sku in order_skus:
            # 计算商品小计
            amount = order_sku.price*order_sku.count
            # 动态给order_sku增加属性amount,保存商品小计
            order_sku.amount = amount

        # 动态给order增加属性,order_skus,保存订单商品信息
        order.order_skus = order_skus

        # 使用模板
        return render(request, 'order_comment.html' {'order': order})

    def post(self, request, order_id):
        """评论内容处理"""
        user = request.user

        # 校验数据
        if not order_id:
            return redirect(reverse("user:order"))

        try:
            order = OrderInfo.objects.get(order_id=order_id, user=user)
        except OrderInfo.DoesNotExist:
            return redirect(reverse("user:order"))

        # 根据订单商品个数获取评论条数
        total_count = request.POST.get('total_count')
        total_count = int(total_count)

        for i in range(1, total_count+1):
            # 获取评论商品的id
            sku_id = request.POST.get('sku_%d' % i)  # sku_1  sku_2
            # 获取评论内容
            content = request.POST.get('content_%d' % i, '')  # content_1  content_2
            try:
                order_goods = OrderGoods.objects.get(order=order, sku_id=sku_id)
            except OrderGoods.DoesNotExist:
                continue

            order_goods.comment = content
            order_goods.save()

        order.order_status = 5  # 修改订单状态为已完成
        order.save()

        return redirect(reverse("user:order", kwargs={'page': 1}))
		<div class="right_content clearfix">
            <h3 class="common_title2">订单评价</h3>
                <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_name}}</li>
				</ul>
            <form method="post">
                {% csrf_token %}
                {# 订单id #}
                <input type="hidden" name="order_id" value="{{order.order_id}}">
                {# 订单中有几个商品 #}
                <input type="hidden" name="total_count" value="{{order.order_skus|length}}">
                {% for order_sku in order.order_skus %}
                <table class="order_list_table w980">
                    <tbody>
                        <tr>
                            <td width="80%">
                                <ul class="order_goods_list clearfix">
                                    <li class="col01"><img src="{{ order_sku.sku.image.url }}"></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>
                                </ul>
                            </td>
                            <td width="20%">{{order_sku.amount}}元</td>
                        </tr>
                    </tbody>
                </table>
                <div class="site_con">
                    <input type="hidden" name="sku_{{forloop.counter}}" value="{{order_sku.sku.id}}">
                    <div class="form_group form_group2">
                        <label>评价内容:</label>
                        <textarea class="site_area" name="content_{{forloop.counter}}"></textarea>
                    </div>
                </div>
                {% endfor %}
            </form>
        </div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值