zoukankan      html  css  js  c++  java
  • day85

    一、支付功能接口

    • 这里暂时介绍通过支付宝接口进行电脑网站的支付功能开发
      • 因为支付宝开放平台官网提供的电脑网站支付API的python文档介绍的有些繁琐、难懂,这里使用的是GitHub上的提供的支付宝的支付API文档。

    1. 支付宝支付接口的使用方法

    • 在实际开发中,我们都是先在支付宝提供的沙箱环境中进行测试,无误后再改成真实环境中再次测试。
    • 步骤:
    1. 支付宝开放平台——》开发者中心——》网页&移动应用(点击:了解更多)——》全部文档——》支付能力——》电脑网站支付——》快速接入——》根据快速接入的文档进行创建应用和配置应用
    

    2. 当应用都配置完成后,就可以进行项目中的支付API的配置了(https://github.com/fzlee/alipay#alipay.trade.page.pay)

    3. 项目的支付API配置完成后,因为要在沙箱中进行测试,所以我们要配置沙箱环境:在开发者中心——》进入控制台——》开发服务——》研发服务——》查看沙箱环境
    沙箱环境中的网关都是公网中的合法的网关,用来在网关后面携带拼接参数,生成支付链接用的
    沙箱环境中测试的生成的二维码只能有沙箱版本的支付宝可以扫(只能使用沙箱提供的沙箱账号才能进行测试)

    2. 项目中的支付接口的工作流程图

    (1)流程图

    (2)详解

    • 就只前端发送购买请求给后端,后端处理返回一个支付链接(支付链接中包含前后端的回调接口),并同时产生订单,前端访问支付链接(也给支付宝应用提供前端同步回调接口和后端的异步回调接口),得到支付页面,用户直接与支付宝平台进行交互,支付宝将交易结果返回给前端和后端的回调接口,最后回调接口判断此次交易是否成功,成功则都返回success这7个字符,失败则返回其他任意数据。

    • 支付宝会对前端发送一次get方式的同步回调请求,对后端间歇性的最多发送8次post方式的异步回调请求(防止浪费后端服务器资源)。
    • 注意:后端的回调接口中,当响应结果为成功时,一定要返回这7个字符,即:success,响应结果是失败时,则返回结果无所谓。

    3. 项目中的支付API配置

    • 我们根据GitHub上的提供的支付宝的python支付SDK,进行配置(点我去网址

    (1)配置项目后端的支付API

    1. 安装依赖

    pip install python-alipay-sdk --upgrade
    pip install pyopenssl

    2. 项目中的支付API的结构

    libs
        ├── iPay                            # aliapy二次封装包
        │   ├── __init__.py                 # 包文件
        │   ├── pay.py                      # 支付文件
        └── └── settings.py                 # 应用配置  

    3. iPay文件夹中的settings.py文件

    • 注意:在配置私钥和公钥时的书写格式,共3行,每行的前面都不能有空格。
    # 应用ID
    APP_ID = "2016093000631831"
    

    # 是否是沙箱环境,为True,使用沙箱环境,为False使用真实环境
    DEBUG = True

    # 签名算法 RSA or RSA2
    SIGN = 'RSA2'

    # 网关
    if DEBUG:
    GATEWAY = 'https://openapi.alipaydev.com/gateway.do?'
    else:
    GATEWAY = 'https://openapi.alipay.com/gateway.do?'

    # 应用私钥:首行尾行是固定的,中间是一行私钥字符串(不能有其他字符)
    APP_PRIVATE_KEY_STRING = """-----BEGIN RSA PRIVATE KEY-----
    MIIEowIBAAKCAQEAl079YgKIx0BFbZJL+HOWBa4+HBoRIX4+rKZXSxqM29/Up86RI4YJkqpBQNb6JC2G9+5av/p3bwQffTCPaxWV5iWFJjTfN3tC6efupOHCtBejr+id+lYhyaudfripjhTJX/N9hmoGIMRb6aMY8FbjrPbNyHoYBWE6pVa/8AmvqPkRmpZMr/UcSlHIVPoPWADWunKwQXL258LisiPY6u1I7gWiTQNsyG8JFYcMDK3I23ls0hAALO0ogHhSJEflCqjlLDMW8AXloih8Pqys5aink05cpIqOobUtGGaLRNTAZXx5jaqA2rJyQRx1rdU6pwenqZZY9Gf9LGlJAxdzOsofqQIDAQABAoIBAEDx9Kx27gKoQaSwYM95vXEewyYIwkWgDILKuzlPYhqWTo7giUe4Jq+/SFbub1vL9tzAgE9a0JzkJif0CfsqvraUcDxgAVetHqGLndFD3fCzHN1KeVSUV9haQzW7SXvkzDLVLpHdPFggMFtuWCwA/6SkItvkHB9jBmsleykq3y0lX5xu5zRrnNBNFj4AVHjbPINpO/13ZK6Ue5mFaK+xnLh4FjJzw6K7Nm8d2VniWjHJZSmYacxSX4D23na+ZipbkAsrJqPP3mqm2acg8L8Ms6DD9CfghfwdSdBJpSa+ul9v7jHxZkw6Q46dPvxNRKiQVFbuCwf1728M1EEKI0MB4ykCgYEA6wETGvZLZvY0d1H7cedDp8P12aMgaeYYs7GDwR/Ljd4RLfTzZKaMUsyT91D4jgw4ZGv6b7mZksUeYIA9U5j0A19bvn6mszaDgHoALVrTYLWDpl0HHpCTU56Rp1GOPgbzC8ap19W2Ac7gzIS+AU0Ap7n0BflcLdOIKt9oSfdcOMcCgYEApNOpIPx9hdL+/QDSzOX5w0dSTr1zv5spxb6sVyj5d0MXy48tHdLdzil1eF576dTF0ffX53IRrg3/6GFA0VLSU/OUqHJU9z5d1QlJd3Ff6MVen/dZYEMxMZwp/Ha5xHAryXU/FpNxHGc7ci3EIHQ1u3OgMei1brnoWZXypgWy1A8CgYB5UMy0FoFGXcMn9cKAQorCiH7aI0QQZyBJY1JI2EkUq5biypj7VJ8L/2BDRCGL8vMJpFRcaMvG4MuVtZ3zEfql4wxRgsA7s+Ce6lw9Da4hNpMHxu5t8OSdPjai0Y9EpgHCCoSTT1fuBwY1jjEoKsAz1eMLUncrkQ+yUjJcPL328QKBgQCRnp4RkoCjNqIojA2xEIz0xZImFqKoaUEify5rYrvjbdcb9EZ7zsw/U8mAqpj3IRAUTM7mn5SXHa81cpZ9WJqRqOVxXHFMbkEf8bCCYhvF3nmXAkRoE3Tmy30cmxfMQP2uYnN2UpTf7yRJ370inwjJr4GcFmgUhxKL8zoJC4fOaQKBgFXp/rWzgaG3f+VJW2d9BspEGy7LzxnnkPtIxKsHW/SS0pAIqDqQelkSqX+cxFzgxku15TwAOvWPcAAu2ZTM2yzky6JS1jk++ysafWWwcQDlxoNKOczy5cgmESkf3j3979Azqo+ic2EzcFoSs9r4o4x4HoplxqBE48BMrbcN5iIk
    -----END RSA PRIVATE KEY-----"""

    # 阿里公钥:首行尾行是固定的,中间是一行公钥字符串(不能有其他字符)
    ALIPAY_PUBLIC_KEY_STRING = """-----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgCLK/MIs0gsKSk/DqzKwf7F9m8hyGqJM97af5IRkEdVCvFI5U1Y8xZsR8mWj+YhIU9rv48zZn81uJ7OqkkWXc/ENCMqGTiEe4tKPniLibTdpaIgPNn9c3QSa03psvJI8v/n5+0rs+KKXxN8UwLcmMMN5Zfy8Ejvq/rax9EXepxLqSP7xQ8DXHRBCkFHUY6W2vdIKQZFc8wqMqglRjGjfN8OgYwaN2F6TPPPHdoVbpjduEx1RlACItapHNWv21YTr0PYx+edb3Oj+Tjfinzuyb9S0uXDEHOOGeLrerOSJr3rVwDJpFKye6Lojz9H7aV+gki1Mp4W2qykyefYEmkDtYwIDAQAB
    -----END PUBLIC KEY-----"""

    4. iPay文件夹中的pay.py文件

    from alipay import AliPay
    from .settings import *
    

    alipay = AliPay(
    appid=APP_ID,
    app_notify_url=None, # 该通知接口一般都设置None
    # 应用私钥
    app_private_key_string=APP_PRIVATE_KEY_STRING,
    # 阿里pay公钥
    alipay_public_key_string=ALIPAY_PUBLIC_KEY_STRING,
    # 签名算法,采用RSA2
    sign_type=SIGN, # RSA or RSA2
    # 是否是沙箱环境
    debug=DEBUG
    )

    5. iPay文件夹中的__init__.py文件

    # 对外提供配置生成好的 alipay 支付对象
    from .pay import alipay
    # 对外提供alipay的支付网关
    from .settings import GATEWAY as alipay_gateway

    6. 在项目的dev.py文件中配置支付宝回调接口

    # 上线后必须换成公网地址
    # 后台http根路径
    BASE_URL = 'http://127.0.0.1:8000'
    

    # 前台http根路径
    LUFFY_URL = 'http://127.0.0.1:8080'

    # 订单支付成功的后台异步回调接口
    NOTIFY_URL = BASE_URL + '/order/success'

    # 订单支付成功的前台同步回调接口
    RETURN_URL = LUFFY_URL + '/pay/success'

    (2)项目后端的订单app:order

    1. order的urls.py文件中:*****************************************************
    

    from django.urls import path, re_path
    from . import views
    urlpatterns = [
    # 支付
    path('pay', views.PayAPIView.as_view()),
    # 支付成功回调
    path('success', views.SuccessAPIView.as_view()),
    ]

    2. order的models.py文件中:*****************************************************

    # 订单表: 主键、商品总名、总价、创建订单时间、支付时间、支付用户、订单号、流水号
    # 订单详情表:主键、订单外键、商品(课程)外键

    from django.db import models
    from utils.model import BaseModel
    from user.models import User
    from course.models import Course

    class Order(BaseModel):
    """订单模型"""
    status_choices = (
    (0, '未支付'),
    (1, '已支付'),
    (2, '已取消'),
    (3, '超时取消'),
    )
    pay_choices = (
    (1, '支付宝'),
    (2, '微信支付'),
    )
    subject = models.CharField(max_length=150, verbose_name="订单标题")
    total_amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="订单总价", default=0)
    out_trade_no = models.CharField(max_length=64, verbose_name="订单号", unique=True)
    trade_no = models.CharField(max_length=64, null=True, verbose_name="流水号")
    order_status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="订单状态")
    pay_type = models.SmallIntegerField(choices=pay_choices, default=1, verbose_name="支付方式")
    pay_time = models.DateTimeField(null=True, verbose_name="支付时间")
    user = models.ForeignKey(User, related_name='user_orders', on_delete=models.DO_NOTHING, db_constraint=False,
    verbose_name="下单用户")

    <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Meta</span>:</span>
        db_table = <span class="hljs-string">"luffy_order"</span>
        verbose_name = <span class="hljs-string">"订单记录"</span>
        verbose_name_plural = <span class="hljs-string">"订单记录"</span>
    
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"%s - ¥%s"</span> % (self.subject, self.total_amount)
    

    @property
    def courses(self):
    data_list = []
    for item in self.order_courses.all():
    data_list.append({
    "id": item.id,
    "course_name": item.course.name,
    "real_price": item.real_price,
    })

        <span class="hljs-keyword">return</span> data_list
    

    class OrderDetail(BaseModel):
    """订单详情"""
    order = models.ForeignKey(Order, related_name='order_courses', on_delete=models.CASCADE, db_constraint=False,
    verbose_name="订单")
    course = models.ForeignKey(Course, related_name='course_orders', on_delete=models.CASCADE, db_constraint=False,
    verbose_name="课程")
    price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="课程原价")
    real_price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="课程实价")

    <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Meta</span>:</span>
        db_table = <span class="hljs-string">"luffy_order_detail"</span>
        verbose_name = <span class="hljs-string">"订单详情"</span>
        verbose_name_plural = <span class="hljs-string">"订单详情"</span>
    
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__str__</span><span class="hljs-params">(self)</span>:</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"%s的订单:%s"</span> % (self.course.name, self.order.out_trade_no)
    

    3. order的views.py文件中:*****************************************************

    from rest_framework.views import APIView
    from rest_framework.response import Response

    from . import serializers

    # 需要登录后才能访问
    from rest_framework_jwt.authentication import JSONWebTokenAuthentication
    from rest_framework.permissions import IsAuthenticated
    class PayAPIView(APIView):
    authentication_classes = [JSONWebTokenAuthentication]
    permission_classes = [IsAuthenticated]
    def post(self, request, *args, **kwargs):
    serializer = serializers.OrderModelSerializer(data=request.data, context={'request': request})
    # 信息校验
    serializer.is_valid(raise_exception=True)
    # 订单入库
    serializer.save()
    # 返回一个支付链接
    return Response(serializer.pay_url)

    4. order的serializers.py文件中:*****************************************************

    import time
    from rest_framework import serializers

    from . import models
    from course.models import Course

    from libs.iPay import alipay, alipay_gateway
    from django.conf import settings

    class OrderModelSerializer(serializers.ModelSerializer):
    # 商品的主键们:暂定 '1,2,3' 方式传多个主键
    goods_pks = serializers.CharField(max_length=64)

    <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Meta</span>:</span>
        model = models.Order
        fields = (
            <span class="hljs-string">'subject'</span>,
            <span class="hljs-string">'total_amount'</span>,
            <span class="hljs-string">'pay_type'</span>,
            <span class="hljs-string">'goods_pks'</span>,
        )
        extra_kwargs = {
            <span class="hljs-string">'total_amount'</span>: {
                <span class="hljs-string">'required'</span>: <span class="hljs-keyword">True</span>
            }
        }
    
    <span class="hljs-comment"># 后台要根据所有的主键和总价,校验价格(防止传输中被修改)</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">validate</span><span class="hljs-params">(self, attrs)</span>:</span>
        goods_pks = attrs.pop(<span class="hljs-string">'goods_pks'</span>)
        goods_pks = [pk <span class="hljs-keyword">for</span> pk <span class="hljs-keyword">in</span> goods_pks.split(<span class="hljs-string">','</span>)]
        goods_objs = []
        <span class="hljs-keyword">for</span> pk <span class="hljs-keyword">in</span> goods_pks:
            <span class="hljs-keyword">try</span>:
                obj = Course.objects.get(pk=pk)
                goods_objs.append(obj)
            <span class="hljs-keyword">except</span>:
                <span class="hljs-keyword">raise</span> serializers.ValidationError({<span class="hljs-string">'pk'</span>: <span class="hljs-string">'课程主键有误'</span>})
    
        total_price = <span class="hljs-number">0</span>
        <span class="hljs-keyword">for</span> good <span class="hljs-keyword">in</span> goods_objs:
            total_price += good.price
    
        <span class="hljs-comment"># 商品总价</span>
        total_amount = attrs.get(<span class="hljs-string">'total_amount'</span>)
        <span class="hljs-keyword">if</span> total_price != total_amount:
            <span class="hljs-keyword">raise</span> serializers.ValidationError({<span class="hljs-string">'total_amount'</span>: <span class="hljs-string">'价格被恶意篡改'</span>})
    
        <span class="hljs-comment"># 生成订单号</span>
        order_on = self._get_order_no()
        <span class="hljs-comment"># 订单名</span>
        subject = attrs.get(<span class="hljs-string">'subject'</span>)
    
        <span class="hljs-comment"># 生成订单链接</span>
        order_params = alipay.api_alipay_trade_page_pay(out_trade_no=order_on,
                                                        total_amount=float(total_amount),
                                                        subject=subject,
                                                        return_url=settings.RETURN_URL,  <span class="hljs-comment"># 同步回调的前台接口</span>
                                                        notify_url=settings.NOTIFY_URL  <span class="hljs-comment"># 异步回调的后台接口</span>
                                                        )
        pay_url = alipay_gateway + order_params
    
        <span class="hljs-comment"># 将支付链接保存在serializer对象中</span>
        self.pay_url = pay_url
    
        <span class="hljs-comment"># 添加额外的入库字段</span>
        attrs[<span class="hljs-string">'out_trade_no'</span>] = order_on
        <span class="hljs-comment"># 视图类给序列化类传参</span>
        attrs[<span class="hljs-string">'user'</span>] = self.context.get(<span class="hljs-string">'request'</span>).user
    
        <span class="hljs-comment"># 将所有的商品对象存放在校验数据中,辅助订单详情表商品信息的入库</span>
        attrs[<span class="hljs-string">'courses'</span>] = goods_objs
    
        <span class="hljs-comment"># 代表校验通过</span>
        <span class="hljs-keyword">return</span> attrs
    
    
    <span class="hljs-comment"># 重写create方法,完成订单详情表入库操作</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">create</span><span class="hljs-params">(self, validated_data)</span>:</span>
        courses = validated_data.pop(<span class="hljs-string">'courses'</span>)
    
        order = super().create(validated_data)  <span class="hljs-comment"># 订单表</span>
    
        <span class="hljs-comment"># 关系表操作</span>
        order_detail_list = []
        <span class="hljs-keyword">for</span> course <span class="hljs-keyword">in</span> courses:
            order_detail_list.append(models.OrderDetail(order=order, course=course, price=course.price, real_price=course.price))
    
        <span class="hljs-comment"># 将多个订单详情对象,批量入库</span>
        models.OrderDetail.objects.bulk_create(order_detail_list)  <span class="hljs-comment"># 订单详情表</span>
    
        <span class="hljs-keyword">return</span> order
    
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">_get_order_no</span><span class="hljs-params">(self)</span>:</span>
        no = <span class="hljs-string">'%s'</span> % time.time()
        <span class="hljs-keyword">return</span> no.replace(<span class="hljs-string">'.'</span>, <span class="hljs-string">''</span>, <span class="hljs-number">1</span>)</code></pre>
    

    (3)项目前端的 立即购买 标签的事件

    <template>
        ...
        <span class="buy-now" @click="buy_course(course)">立即购买</span>
    </template>
    <script>
        export default {
            methods: {
                // 购买课程
                buy_course(course) {
                    let token = this.$cookies.get('token');
                    if (!token) {
                        this.$message({
                            message: "请先登录",
                            type: 'warning',
                            duration: 1000,
                        });
                        return false
                    }
                    // 已登录
                    this.$axios({
                        url: this.$settings.base_url + '/order/pay',
                        method: 'post',
                        data: {
                            subject: course.name,
                            total_amount: course.price,
                            goods_pks: `${course.id}`
                        },
                        headers: {
                            authorization: `jwt ${token}`
                        }
                    }).then(response => {
                        // console.log(response.data)
                        let pay_url = response.data;
                        window.open(pay_url, '_self');
                    }).catch(error => {
                        console.log(error.response.data)
                    })
    
            },
        }
    }
    

    </script>

    (4)前端 - 支付成功的回调页面

    // 1. 路由文件中:
    

    const routes = [
    // ...
    {
    path: '/pay/success',
    name: 'pay-success',
    component: PaySuccess
    },
    ];

    // 2. views文件夹下的PaySuccess.vue文件中:

    <template>
    <div class="pay-success">
    <!--如果是单独的页面,就没必要展示导航栏(带有登录的用户)-->
    <!--<Header/>-->
    <div class="main">
    <div class="title">
    <div class="success-tips">
    <p class="tips">您已成功购买 1 门课程!</p>
    </div>
    </div>
    <div class="order-info">
    <p class="info"><b>订单号:</b><span>{{ result.out_trade_no }}</span></p>
    <p class="info"><b>交易号:</b><span>{{ result.trade_no }}</span></p>
    <p class="info"><b>付款时间:</b><span><span>{{ result.timestamp }}</span></span></p>
    </div>
    <div class="study">
    <span>立即学习</span>
    </div>
    </div>
    <!--<Footer/>-->
    </div>

    </template>

    <script>
    // import Header from "@/components/Header"
    // import Footer from "
    @/components/Footer"

    export default {
        name: "</span>Success<span class="hljs-string">",
        data() {
            return {
                result: {},
            };
        },
        created() {
            // url后拼接的参数
            console.log(location.search);
    
            localStorage.this_nav = '/';
            if (!location.search.length) return;
    
            // 解析支付宝回调的url参数
            let params = location.search.substring(1);
            let items = params.length ? params.split('&amp;') : [];
            //逐个将每一项添加到args对象中
            for (let i = 0; i &lt; items.length; i++) {
                let k_v = items[i].split('=');
                //解码操作,因为查询字符串经过编码的
                let k = decodeURIComponent(k_v[0]);
                let v = decodeURIComponent(k_v[1]);
                // let k = k_v[0];
                // let v = k_v[1];
                this.result[k] = v;
                // this.result[k_v[0]] = k_v[1];
            }
            console.log(this.result);
    
            // 把地址栏上面的支付结果,转发给后端
            this.$axios({
                url: this.$settings.base_url + '/order/success' + location.search,
                method: 'patch',
                headers: {
                    Authorization: token
                }
            }).then(response =&gt; {
                console.log(response.data);
            }).catch(() =&gt; {
                console.log('支付结果同步失败');
            })
        },
        components: {
            // Header,
            // Footer,
        }
    }
    

    </script>

    <style scoped>
    .main {
    padding: 60px 0;
    margin: 0 auto;
    1200px;
    background: #fff;
    }

    .main .title {
        display: flex;
        -ms-flex-align: center;
        align-items: center;
        padding: 25px 40px;
        border-bottom: 1px solid #f2f2f2;
    }
    
    .main .title .success-tips {
        box-sizing: border-box;
    }
    
    .title img {
        vertical-align: middle;
         60px;
        height: 60px;
        margin-right: 40px;
    }
    
    .title .success-tips {
        box-sizing: border-box;
    }
    
    .title .tips {
        font-size: 26px;
        color: #000;
    }
    
    
    .info span {
        color: #ec6730;
    }
    
    .order-info {
        padding: 25px 48px;
        padding-bottom: 15px;
        border-bottom: 1px solid #f2f2f2;
    }
    
    .order-info p {
        display: -ms-flexbox;
        display: flex;
        margin-bottom: 10px;
        font-size: 16px;
    }
    
    .order-info p b {
        font-weight: 400;
        color: #9d9d9d;
        white-space: nowrap;
    }
    
    .study {
        padding: 25px 40px;
    }
    
    .study span {
        display: block;
         140px;
        height: 42px;
        text-align: center;
        line-height: 42px;
        cursor: pointer;
        background: #ffc210;
        border-radius: 6px;
        font-size: 16px;
        color: #fff;
    }
    

    </style>

    (5)后端 - 支付成功的回调接口

    from . import models
    from utils.logging import logger
    from rest_framework.response import Response
    class SuccessAPIView(APIView):
        # 不能认证,支付宝异步回调访问该接口,肯定不知道登录认证信息,订单号就是关键的关联信息
        # authentication_classes = [authentications.JWTAuthentication]
        # permission_classes = [IsAuthenticated]
        def patch(self, request, *args, **kwargs):
            # 默认是QueryDict类型,不能使用pop方法
            request_data = request.query_params.dict()
            # 必须将 sign、sign_type(内部有安全处理) 从数据中取出,拿sign与剩下的数据进行校验
            sign = request_data.pop('sign')
            result = alipay.verify(request_data, sign)
            if result:  # 同步回调:修改订单状态
                try:
                    out_trade_no = request_data.get('out_trade_no')
                    order = models.Order.objects.get(out_trade_no=out_trade_no)
                    if order.order_status != 1:
                        order.order_status = 1
                        order.save()
                except:
                    pass
                return APIResponse(0, '支付成功')
            return APIResponse(1, '支付失败')
    
    <span class="hljs-comment"># 支付宝异步回调</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">post</span><span class="hljs-params">(self, request, *args, **kwargs)</span>:</span>
        <span class="hljs-comment"># 默认是QueryDict类型,不能使用pop方法</span>
        request_data = request.data.dict()
        <span class="hljs-comment"># 必须将 sign、sign_type(内部有安全处理) 从数据中取出,拿sign与剩下的数据进行校验</span>
        sign = request_data.pop(<span class="hljs-string">'sign'</span>)
        result = alipay.verify(request_data, sign)
        <span class="hljs-comment"># 异步回调:修改订单状态</span>
        <span class="hljs-keyword">if</span> result <span class="hljs-keyword">and</span> request_data[<span class="hljs-string">"trade_status"</span>] <span class="hljs-keyword">in</span> (<span class="hljs-string">"TRADE_SUCCESS"</span>, <span class="hljs-string">"TRADE_FINISHED"</span> ):
            out_trade_no = request_data.get(<span class="hljs-string">'out_trade_no'</span>)
            logger.critical(<span class="hljs-string">'%s支付成功'</span> % out_trade_no)
            <span class="hljs-keyword">try</span>:
                order = models.Order.objects.get(out_trade_no=out_trade_no)
                <span class="hljs-keyword">if</span> order.order_status != <span class="hljs-number">1</span>:
                    order.order_status = <span class="hljs-number">1</span>
                    order.save()
            <span class="hljs-keyword">except</span>:
                <span class="hljs-keyword">pass</span>
            <span class="hljs-comment"># 支付宝八次异步通知,订单成功一定要返回 success</span>
            <span class="hljs-keyword">return</span> Response(<span class="hljs-string">'success'</span>)
        <span class="hljs-keyword">return</span> Response(<span class="hljs-string">'failed'</span>)</code></pre>
    
  • 相关阅读:
    C# 实现 Snowflake算法生成唯一性Id
    kafka可视化客户端工具(Kafka Tool)的基本使用(转)
    docker 安装kafka
    Model类代码生成器
    使用docker 部署rabbitmq 镜像
    Vue 增删改查 demo
    git 提交代码到库
    Android ble蓝牙问题
    mac 配置 ssh 到git (Could not resolve hostname github.com, Failed to connect to github.com port 443 Operation timed out)
    okhttp
  • 原文地址:https://www.cnblogs.com/gfhh/p/12289582.html
Copyright © 2011-2022 走看看