• 支付宝支付(沙箱环境&真实支付)使用详解python


     

    0. 前提

    a. 这里我用前后端不分离项目做演示,这个支付方式,不分开发的模式,全部适用。我用电脑网站支付做案例

    b. django2..2/python3.6.6

    c. 这里用别人封装好的sdk,Alipay的sdk不是很好用

    d. 最后我会粗略讲一下,如果是真实的应用,进行支付的配置,其实就改动几个地方,模拟支付,就可以变成真实支付

    一. 安装sdk

    a. 不清楚sdk是什么的,我这里有介绍

    skd与api的区别https://blog.csdn.net/qq_52385631/article/details/122851280?spm=1001.2014.3001.5501b. 安装

    pip3 install python-alipay-sdk --upgrade -i https://pypi.douban.com/simple/

    二. 公私钥的配置

    a. 扫码支付宝登录

    支付宝登录https://open.alipay.com/platform/home.htmb. 进入沙箱环境

    c. 点击自定义私钥

    d. 公钥私钥的介绍:

    公钥是基于私钥生成的,可解密,但是私钥不行。

    在这里我们需要配置自己的公钥,下面会讲怎么生成

    e. 支付宝加密软件的下载(我们要借助他生成),点击下载安装即可,注意:安装路径不能有空格,不然会有乱码,

    支付宝公私钥加密工具https://ideservice.alipay.com/ide/getPluginUrl.htm?clientType=assistant&platform=win&channelType=WEBps:如果这个链接失效了,你就进入接入文档

    f. 下载安装包,安装即可,打开是这个样子的,根据步骤,生成自己的公钥,私钥

    g. 去支付宝沙盒环境里,生成支付宝公钥。到此私钥,支付宝公钥,生成完成。

    这两个先放在一个自己可以找到的地方,一会我们把他复制到项目中

    三. 第三方alipay支付的sdk使用

    这个是我从github拉下来的https://gitee.com/yqmc/alipay

    a. 点进去之后,找到中文的文档

    b.

    c. 初始化,我们要根据他的提示生成一个alipay对象,我封装好了,直接复制用即可

    d. 公私钥的配置

    1. 在自己项目的根目录创建一个files的文件夹,把自己的公钥支付宝公钥放进去,txt文件即可

    2. 修改格式,在他们两个的第一行,都加上头和尾

    支付宝公钥的头尾(注意密钥不能换行,只能一行展示,全部顶格显示)

    -----BEGIN PUBLIC KEY-----
        你的支付宝公钥
    -----END PUBLIC KEY-----

    私钥钥的头尾(注意密钥不能换行,只能一行展示)

    -----BEGIN RSA PRIVATE KEY-----
        你的私钥
    -----END RSA PRIVATE KEY-----

    e. alipay生成对象需要的参数,在setting里配置即可

    # 支付宝支付相关配置
    import os
    ALIPAY_SETTING = {
        'ALIPAY_APP_ID': "去刚才的沙箱账号里面找自己的APPID",  # 应用ID(上线之后需要改成,真实应用的appid)
        'APLIPAY_APP_NOTIFY_URL': None,  # 应用回调地址[支付成功以后,支付宝返回结果到哪一个地址下面] 一般这里不写,用下面的回调网址即可
        'ALIPAY_DEBUG': False,
        # APIPAY_GATEWAY="https://openapi.alipay.com/gateway.do"   # 真实网关
        'APIPAY_GATEWAY': "https://openapi.alipaydev.com/gateway.do",  # 沙盒环境的网关(上线需要进行修改)
        'ALIPAY_RETURN_URL': "http://127.0.0.1:8000/alipay/result/",  # 同步回调网址--用于前端,支付成功之后回调
        'ALIPAY_NOTIFY_URL': "http://127.0.0.1:8000/alipay/result/",  # 异步回调网址---后端使用,post请求,网站未上线,post无法接收到响应内容,付成功之后回调
        'APP_PRIVATE_KEY_STRING': os.path.join(BASE_DIR, 'files/应用私钥2048.txt'),  # 自己生成的私钥,这个就是路径拼接,配置好了,试试能不能点进去
        # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,********
        'ALIPAY_PUBLIC_KEY_STRING': os.path.join(BASE_DIR, 'files/alipay_public'),  # 一定要注意,是支付宝给你的公钥,不是你自己生成的那个
        'SIGN_TYPE': "RSA2",  # RSA 或者 RSA2  现在基本上都是用RSA2
    
    }
    

    f. alipay对象(导入setting),我一般把他写在app的utils.py里面,这个放的地方随意

    from django.conf import settings
    from alipay import AliPay, DCAliPay, ISVAliPay
    from alipay.utils import AliPayConfig
    
    
    # 生成支付alipay对象,以供调用
    def alipay_obj():
        alipay = AliPay(
            appid=settings.ALIPAY_SETTING.get('ALIPAY_APP_ID'),
            app_notify_url=None,  # 默认回调 url
            app_private_key_string=open(settings.ALIPAY_SETTING.get('APP_PRIVATE_KEY_STRING')).read(),
            # 支付宝的公钥,验证支付宝回传消息使用,不是你自己的公钥,
            alipay_public_key_string=open(settings.ALIPAY_SETTING.get('ALIPAY_PUBLIC_KEY_STRING')).read(),
            sign_type=settings.ALIPAY_SETTING.get('SIGN_TYPE'),  # RSA 或者 RSA2
            debug=settings.ALIPAY_SETTING.get('ALIPAY_DEBUG'),  # 默认 False
            verbose=False,  # 输出调试数据
            # config=AliPayConfig(timeout=50)  # 可选,请求超时时间
        )
        return alipay
    

    四. 进行支付

    1. 生成支付的路由,只要路由,访问该路由,支付宝会返回给,我们一个支付页面

    前端:

    a. html:

    做了一个点击按钮,ajxa向后端发送数据,请求成功获取支付url

    <!DOCTYPE html>
    {% load static %}
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div style="margin: 0 auto">
        <h1>看什么看,快买!</h1>
        <img src="{% static '1.png' %}" alt="" style=" 200px">
        <input type="button" id="btn_ajax" value="点我即可购买">
    </div>
    
    
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script>
        $(function () {
            $("#btn_ajax").click(function () {
                $.ajax({
                    url: '{% url "good_list" %}',
                    type: 'POST',
                    dataType: 'JSON',
                    data: {csrfmiddlewaretoken: '{{ csrf_token }}'},
                    success: function (res) {
                        if (res.status === 1) {
                            // 跳转到支付链接
                            location.href = res.url
                        } else {
    
                        }
                    }
                })
            })
        })
    
    </script>
    </body>
    </html>

    页面如下

    端:

    a. url

        path('good_list/', views.good_list_view, name='good_list'),
    

    b. view

    from django.shortcuts import render
    from app03.utils import alipay_obj
    from django.conf import settings
    from django.http import JsonResponse
    
    
    # Create your views here.
    
    
    def good_list_view(request):
        if request.method == 'GET':
            return render(request, 'good_list.html')
        # 如果是post,我们认为是购买
        # 示例化一个对象
        alipay = alipay_obj()
        # 生成支付路由
        # 拼接url--返回url
        # 电脑网站支付,需要跳转到:https://openapi.alipay.com/gateway.do? + order_string
        order_string = alipay.api_alipay_trade_page_pay(
            # 这下面的数据,都应该是你数据库的数据,但是我这里做测试,直接写死了
            out_trade_no="2016112528123",  # 商品订单号  唯一的
            total_amount=995,  # 商品价格
            subject='表,忙乎?砍一刀否',  # 商品的名称
            return_url=settings.ALIPAY_SETTING.get('ALIPAY_RETURN_URL'),  # 同步回调网址--用于前端,付成功之后回调
            notify_url=settings.ALIPAY_SETTING.get('ALIPAY_NOTIFY_URL')  # 异步回调网址---后端使用,post请求,网站未上线,post无法接收到响应内容
        )
        # 我这里大概讲一下为什么要有同步/异步,因为同步是前端的,
        # 如果前端出现页面崩了,那么校验有后端完成,
        # 而且在实际开发中,后端一定要校验,因为前端的校验,可被修改
        url = 'https://openapi.alipaydev.com/gateway.do' + '?' + order_string
        return JsonResponse({'url': url, 'status': 1})
    
    
    

    2. 成功的支付页面如下

    a. 如果点击出现,以下页面,是正常的,打开一个无痕浏览器窗口即可,一般在浏览器的右上角

    b. 支付页面,

    c. 去支付宝的沙箱环境,找到,自己的账号密码,输入,点击下一步

    d. 输入支付密码

    e. 支付成功

    f. 注意看,支付成功之后,他的跳转路由,是我们配置的同步调用路由,我们在前面说,同步调用路由是前端的,现在证实了,

    另外注意一下,它的参数,有个印象,接下来有用

    到此,支付全部完成

    五. 同步调用----后端进行校验

    a. url(这路由与你配置的同步回调路由,一定要一致,不然无法进行后续的校验)

        path('alipay/result/', views.check_html_view, name='alipay_result/'),
    

    b. view

    def check_html_view(request):
        if request.method == "GET":
            # 进行校验,因为支付成功之后,后端是不知道是否成功的,所以需要校验一下
            alipay = alipay_obj()
            data = request.GET.dict()  # 把get请求的参数转换成字典
            signature = data.pop("sign")  # 把sign pop出去
            # verification 
            success = alipay.verify(data, signature)  # success ----> True False
            # 上面的都是固定用法
            if success:
                # 如果成功支付了,这个success是True
                # 接着写逻辑了,比如修改当前订单的状态
                # 我举一个例子
                print('支付成功,后台已经校验过了,金币+1')
                return HttpResponse('ok')
    
            return HttpResponse('支付失败')
    

    六. 异步回调,当你前端页面崩了以后,支付宝会向该路由,发送post请求,这个是间隔发8次,如果没有返回success

    url 我用同一个路由了,可以选择,用不同的路由,但是必须是配置的,异步回调的路由

        path('alipay/result/', views.check_html_view, name='alipay_result/'),
    

    view

    def check_html_view(request):
        if request.method == "GET":
            # 进行校验,因为支付成功之后,后端是不知道是否成功的,所以需要校验一下
            alipay = alipay_obj()
            data = request.GET.dict()  # 把get请求的参数转换成字典
            signature = data.pop("sign")  # 把sign pop出去
            # verification
            success = alipay.verify(data, signature)  # success ----> True False
            if success:
                # 如果成功支付了,这个success是True
                # 接着写逻辑了,比如修改当前订单的状态
                # 我举一个例子
                print('支付成功,后台已经校验过了,金币+1')
                return HttpResponse('ok')
            return HttpResponse('支付失败')
        # post 请求异步回调校验,最后一定要返回一个success
        alipay = alipay_obj()
        data = request.GET.dict()
        signature = data.pop("sign")
        # verification
        success = alipay.verify(data, signature)  # True False
        if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED"):
            print('支付成功,后台已经校验过了,金币+1')
            return HttpResponse('success')
        return HttpResponse('支付失败')

    ps. 真实应用支付配置

    1. 修改支付网关,带dev的是测试网关

    a. 修改支付成功拼接的url(无dev)

    # 电脑网站支付,需要跳转到:https://openapi.alipay.com/gateway.do? + order_string

    b. 修改settings配置的支付网关

    APIPAY_GATEWAY="https://openapi.alipay.com/gateway.do"   # 真实网关
    

    2. 修改appid,修改成,真实应用的appid即可

     
  • 相关阅读:
    POJ-3131-Cubic Eight-Puzzle(双向BFS+哈希)
    Android WebView与JavaScript交互操作(Demo)
    程序猿Web面试之jQuery
    Java数据类型(基本数据类型和引用数据类型)
    Swift学习——A Swift Tour 枚举和结构体
    大龙的学习笔记之“虚方法,抽象方法,重写,抽象类,接口”
    thinkphp curd的事务回滚 一看就会
    图书源代码下载: Modern Differential Geometry of CURVES and SURFACES with Mathematica
    UOJ#422. 【集训队作业2018】小Z的礼物
    删除所选项(附加搜索部分的jquery)
  • 原文地址:https://www.cnblogs.com/ZhiXiaoBbai/p/16326271.html
Copyright © 2020-2023  润新知