Django第三方支付之支付宝

一、搭建支付宝第三方环境

1.在百度上搜索支付宝开发平台

https://open.alipay.com/platform/developerIndex.htmhttps://open.alipay.com/platform/developerIndex.htmicon-default.png?t=LA23https://open.alipay.com/platform/developerIndex.htm

2.在开发服务里找到研发服务,进入沙盒

3、在沙盒应用里,基本信息里有APPID(要记住这个位置,以后要在配置环境里用)

 

 4、沙盒环境里的密钥选择自定义密钥,使用支付宝推荐的RSA2密钥并启用(一会需要下载软件自己配),授权回调地址是支付宝支付过返回的地址

 5、点击文档,再点击网页&移动应用,进入支付宝官方文档,里面有介绍怎么配置的

 6、根据下面的步骤,下载一个支付宝开发平台助手(一会生成密钥使用),安装步骤基本上按默认就行,就不啰嗦了

 7、按照我下面框选的内容生成自己的私钥和公钥,把应用公钥复制一下,添加到自定义密钥里,会生成支付宝公钥,然后保存一下设置

 8、刚刚生成密钥的位置在C:\Users\Administrator\.ssh

 9、需要看官方文档,可以进行下面步骤(后面就不啰嗦)

 10、在这里可以看到买家账号 和 商家账号,可以看到一些支付宝配好的信息,自己可以进行充值的操作等

 二、在pycharm里配置支付宝需要的库以及接口的编写

1、在pycharn虚拟环境上安装支付宝需要的库

pip install  alipay

pip install alipay-sdk-python

 2、在虚拟环境中创建一个支付宝的第三方app

python manage.py startapp third

3、第三方结构如下图所示

需要自己新建alipay.py、urls.py

 4、

alipay.py

from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
from django.conf import settings

client = None


def get_client():
    global client
    if client is None:
        # 创建一个 AlipayClientConfig 配置对象
        alipay_client_config = AlipayClientConfig(sandbox_debug=settings.SANDBOX_DEBUG)
        # 设置 支付宝相关的配置
        alipay_client_config.app_id = settings.ZFB_APP_ID
        alipay_client_config.app_private_key = settings.ZFB_APP_PRIVATE_KEY
        alipay_client_config.alipay_public_key = settings.ZFB_PUBLIC_KEY

        # 创建 alipayclient 对象
        client = DefaultAlipayClient(alipay_client_config=alipay_client_config)

    return client

models.py

from django.contrib.auth.models import User
from django.db import models

# Create your models here.


class ThirdUser(models.Model):
    zfb_user = models.CharField(verbose_name="支付宝用户ID", max_length=64, blank=True, null=True)
    wx_user = models.CharField(verbose_name="微信用户ID", max_length=64, blank=True, null=True)
    qq_user = models.CharField(verbose_name="QQ用户ID", max_length=64, blank=True, null=True)

    user = models.OneToOneField(to=User, on_delete=models.DO_NOTHING, blank=True, null=True, related_name="tuser")

    class Meta:
        db_table = "t_third_user"

urls.py

from django.conf.urls import url
from django.contrib import admin
from django.urls import path
from . import views

app_name = 'third'

urlpatterns = [
    path('login', views.login, name='login'),

    path('zfb_login', views.zfb_login, name='zfb_login'),

    path('bind', views.bind, name='bind'),

    path('pay', views.pay, name='pay'),

    path('zfb_pay', views.zfb_pay, name='zfb_pay'),

    path('unpay', views.unpay, name='unpay'),
]

views.py

from django.contrib.auth.models import User
from django.shortcuts import render, redirect, HttpResponse
from django.conf import settings
from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
from alipay.aop.api.domain.AlipayOpenAuthTokenAppModel import AlipayOpenAuthTokenAppModel
from alipay.aop.api.request.AlipayOpenAuthTokenAppRequest import AlipayOpenAuthTokenAppRequest
from alipay.aop.api.response.AlipayOpenAuthTokenAppResponse import AlipayOpenAuthTokenAppResponse
from django.contrib import auth
from car.models import ShopCar, Car
from user.models import Address
from .models import ThirdUser
from django.views.decorators.http import require_POST
from . import alipay
from order.models import Order
# Create your views here.


def login(request):
    url = settings.ZFB_AUTH_URL + "?app_id=" + settings.ZFB_APP_ID + "&redirect_uri=" + settings.ZFB_REDIRECT_URL

    return redirect(to=url)

def zfb_login(request):
    #获取授权成功返回的数据
    app_id = request.GET.get("app_id")
    source = request.GET.get("source")
    #获取应用授权码
    app_auth_code = request.GET.get("app_auth_code")

    client = alipay.get_client()

    model = AlipayOpenAuthTokenAppModel()
    model.grant_type = "authorization_code"
    model.code = app_auth_code
    # 创建一个该接口的请求对象
    alipay_request = AlipayOpenAuthTokenAppRequest(biz_model=model)

    #执行请求,返回结果
    response_content = client.execute(alipay_request)

    #通过响应对象, 处理结果
    alipay_response = AlipayOpenAuthTokenAppResponse()
    alipay_response.parse_response_content(response_content)

    #如果接口调用成功
    if alipay_response.is_success():
        #可以获取响应的结果
        zfb_user_id = alipay_response.user_id
        #获取返回的令牌
        auth_token = alipay_response.app_auth_token
        #查询支付宝用户ID是否绑定用户
        queryset = ThirdUser.objects.filter(zfb_user=zfb_user_id)
        if ThirdUser.objects.filter(zfb_user=zfb_user_id):
            #获取绑定用户
            user = queryset.first().user
            #进行登录,并返回首页
            auth.login(request, user)
            #跳转首页
            return redirect(to="index")
        return render(request, "bind.html", {"zfb_user":zfb_user_id})

@require_POST
def bind(request):

    zfb_user = request.POST.get("zfb_user")
    username = request.POST.get("username")
    pwd = request.POST.get("pwd")
    user = auth.authenticate(request, username=username, password=pwd)
    if user is None:
        return render(request, "bind.html", {"zfb_user":zfb_user, "username":username, "msg":"用户名或者密码不正确"})
    ThirdUser.objects.create(user=user, zfb_user=zfb_user)
    #进行登录,并返回首页
    auth.login(request, user)
    #跳转首页
    return redirect(to="index")



def unpay(request):

    # 获取订单编号
    order_num = request.GET.get("order")
    mes = Order.objects.get(order_num=order_num)
    mes1 = mes.ids.replace('[', '')
    mes2 = mes1.replace(']', '')
    mes3 = mes2.split(',')
    print(mes3)
    if Car.objects.filter(pk__in=mes3, is_out=0):
        Order.objects.filter(order_num=order_num).delete()
        request.session['ms'] = True
        return redirect(to='order:user_center_order')
    # 根据订单编号,查询该笔订单对应的 金额
    order = Order.objects.filter(order_num=order_num).first()
    money = order.order_money

 # 获取 client对象
    client = alipay.get_client()

    # 调用 alipay.trade.page.pay
    from alipay.aop.api.domain.AlipayTradePagePayModel import AlipayTradePagePayModel
    from alipay.aop.api.request.AlipayTradePagePayRequest import AlipayTradePagePayRequest

    # 构建 model 对象
    model = AlipayTradePagePayModel()
    model.out_trade_no = order_num
    model.total_amount = str(money)
    model.subject = "天泽-提车"
    model.product_code = "FAST_INSTANT_TRADE_PAY"

    # 构建 request 对象
    alipay_request = AlipayTradePagePayRequest(biz_model=model)

    # 设置 通知 商户的 回调地址
    # 设置 异步通知的回调地址(必须是公网能够访问的地址)
    alipay_request.return_url = settings.ZFB_PAY_RETURN_URL
    alipay_request.notify_url = settings.ZFB_PAY_NOTIFY_URL

    # 执行 request
    page = client.page_execute(alipay_request)
    return HttpResponse(page)

def pay(request):

    # 获取充值 金额
    money = request.GET.get("m")
    # 打开支付宝充值 界面

    # 获取 client对象
    client = alipay.get_client()

    # 调用 alipay.trade.page.pay
    from alipay.aop.api.domain.AlipayTradePagePayModel import AlipayTradePagePayModel
    from alipay.aop.api.request.AlipayTradePagePayRequest import AlipayTradePagePayRequest
    import uuid

    # 构建 model 对象
    model = AlipayTradePagePayModel()

    # 生成一个订单编号 ,长度不能超过 64,且不能重复
    out_trade_no = uuid.uuid4().hex.replace("-", "_")

    model.out_trade_no = out_trade_no
    model.total_amount = money
    model.subject = "天泽-提车"
    model.product_code = "FAST_INSTANT_TRADE_PAY"

    # 构建 request 对象
    alipay_request = AlipayTradePagePayRequest(biz_model=model)

    # 设置 通知 商户的 回调地址

    # 设置 异步通知的回调地址(必须是公网能够访问的地址)
    alipay_request.return_url = settings.ZFB_PAY_RETURN_URL
    alipay_request.notify_url = settings.ZFB_PAY_NOTIFY_URL

    # 执行 request
    page = client.page_execute(alipay_request)
    user_id = request.user.pk
    address_id = Address.objects.filter(user_id=user_id).values('id')[0].get('id')
    # print(address_id)
    if request.GET.get('super') == 1:
        return HttpResponse(content=page)
    ids = request.session.get("ids")
    Order.objects.create(order_num=out_trade_no, order_money=money, order_status=0, pay_type='支付宝',
                         address_id=address_id, user_id=user_id, ids=ids)
    for i in ids:
        ShopCar.objects.filter(car_id=i).delete()
    return HttpResponse(content=page)


def zfb_pay(request):
    param = request.GET.dict()

    from alipay.aop.api.util import SignatureUtils

    sign = param.pop("sign")
    sign_type = param.pop("sign_type")

    message = SignatureUtils.get_sign_content(param)

    if SignatureUtils.verify_with_rsa(settings.ZFB_PUBLIC_KEY, message.encode(), sign):

        client = alipay.get_client()

        from alipay.aop.api.domain.AlipayTradeQueryModel import AlipayTradeQueryModel
        from alipay.aop.api.request.AlipayTradeQueryRequest import AlipayTradeQueryRequest
        from alipay.aop.api.response.AlipayTradeQueryResponse import AlipayTradeQueryResponse

        model = AlipayTradeQueryModel()

        model.trade_no = param.get("trade_no")

        alipay_request = AlipayTradeQueryRequest(biz_model=model)

        response_content = client.execute(alipay_request)

        alipay_response = AlipayTradeQueryResponse()

        alipay_response.parse_response_content(response_content)

        if alipay_response.is_success():
            if alipay_response.trade_status == "TRADE_SUCCESS":

                ids = request.session.pop('ids')
                Order.objects.filter(order_num=alipay_response.out_trade_no).update(order_status=1)
                Car.objects.filter(pk__in=ids).update(is_out=0)

            return redirect(to="index")
        return render(request, "info.html", {"title": "充值失败", "msg": "支付宝订单编号为"+ param.get("trade_no") + "存在异常"})
    return render(request, "info.html", {"title": "认证失败", "msg": "本次交易存在巨大风险"})

三、运行效果

 

 

 

 


版权声明:本文为qq_44850339原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。