Django网站项目线下二维码扫描支付,


1、前期工作

  • 进行项目之前我们需要一个支付宝的沙箱环境,进入沙箱环境的网址:https://openhome.alipay.com/platform/appDaily.htm?tab=info

pip install python-alipay-sdk

这种下载就会没错了。

创建项目app

  • 进入项目目录下运行:python manage.py startapp payment
  • 然后再创建下面图一样的目录(只需要看payment app目录即可,文件颜色不用管)将之前保存的私钥公钥文件都粘贴到key的目录下

 

from django.urls import path from . import views app_name = '[payment]' urlpatterns = [ path("alipay/", views.AliPayView.as_view(), name="alipay"), # 支付宝支付 path("check_pay/", views.CheckPayView.as_view(), name="check_pay"), # 验证支付是否完成 ]

  • 视图文件就很重头戏了
    • 分别创建这两个类了,另外在类的外部先定义好Alipay的对象。相信大家已经看过很多Alipay对象的创建了,他们初始化对象的参数是不一样的,因为他们是没有下载SDK工具包,所以应该都是去github上复制了一份别人封装的alipay的工具包,所以在使用对象调用方法是有些是不一样的。如果你下载了SDK工具包,按照我的步骤就不会错的。还有不能一味的跟着别人的代码敲,多看看里面的源码以及他的实现方式。废话不多说,上代码了(这里我一部分一部分写,这样有助于理解,也让自己增强记忆,但都是同一个views.py文件中)P
    • 第一步就是初始化我们的Alipay类的对象,首先先看下Alipay类的源码,他是继承了BasePay类,所以直接看BasePay类的源码,我这里直接去当前使用并且中的地方。方式:AliPay——>BaseAliPay——>查看他的__init__初始化方法,主要看我添加注释的地方,似乎不是加载应用私钥文件和支付宝公钥文件,最后一句是调用了加载这两种文件的方法——>_load_key方法,里面的注释很重要,这里不复制,主要讲述的内容是我们需要pem文件格式的内容,而在文件头和文件尾都需要添加----- 描述性语言 -----。浏览_load_key方法的时候就会知道为什么需要pem文件和文件头和文件尾的样式。然后在读取文件时也需要像下面这样读取,当然如果你能保证获取的内容相同,读取文件的方式可以不一致。
def __init__( self, appid, app_notify_url, app_private_key_string=None, alipay_public_key_string=None, sign_type="RSA2", debug=False ): """ 初始化: alipay = AliPay( appid="", app_notify_url="http://example.com", sign_type="RSA2" ) """ self._appid = str(appid) self._app_notify_url = app_notify_url # 就是my_private_key.pem里面的内容 self._app_private_key_string = app_private_key_string # 就是alipay_public_key.pem里面的内容 self._alipay_public_key_string = alipay_public_key_string self._app_private_key = None self._alipay_public_key = None if sign_type not in ("RSA", "RSA2"): raise AliPayException(None, "Unsupported sign type {}".format(sign_type)) self._sign_type = sign_type if debug is True: self._gateway = "https://openapi.alipaydev.com/gateway.do" else: self._gateway = "https://openapi.alipay.com/gateway.do" # load key file immediately # 这里很关键,也是重点 self._load_key() AliPay初始化方法__init__
from alipay import AliPay

my_private_key = ""
alipay_public_key = ""
with open("./payment/key/my_private_key.pem") as f1:
    for read in f1.readlines():
        my_private_key += read

with open("./payment/key/alipay_public_key.pem") as f2:
    for read in f2.readlines():
        alipay_public_key += read
alipay = AliPay(appid='2016102100732430',
                app_notify_url='http://127.0.0.1:8000/payment/check_pay/',
                app_private_key_string=my_private_key,
                alipay_public_key_string=alipay_public_key,
                debug=True)
    • 这个时候我们可以在前端发出一个请求,像发出类似支付这样的请求。前端拿到这样的地址,做一个重定向。
class AliPayView(ListAPIView):
    # 这里只是定义一个全局的订单号
    order_id = None

    def get(self, request):
        """
        请求获取支付宝的支付二维码
        :param request: 获取的请求
        :return: 含有支付二维码的请求地址
        """
        all_price = request.GET.get("all_price")
        AliPayView.order_id = request.GET.get("order_id")

        params = alipay.api_alipay_trade_page_pay(
            subject="商品购买",        # 收费的名称
            out_trade_no=str(uuid.uuid4()),   #商户的订单号,唯一,使用uuid比较方便
            total_amount=all_price,      # 从前端获取的价格
            # 这个很关键,这里是支付的时候需要验证一个请求的地址
            return_url="http://127.0.0.1:8000/payment/check_pay/",    
        )
        # 支付宝网关的地址:因为是debug=False所以是沙箱的地址
        url = alipay._gateway + "?" + params

        return Response(data={"url": url})
    • 当我们用沙箱支付宝扫码并且支付成功时,会像服务器发出上面return_url地址的get请求,并且他会携带上述的params的参数,而且参数中会有sign的标识,需要使用AliPay对象调用签名验证的方法verify,他的返回值是boolean值
class CheckPayView(APIView):

    def get(self, request):
        """
        验证用户是否支付成功,支付成功就需要修改订单的状态,
        :param request: 获取的请求
        :return: 重定向到订单页面
        """
        params = request.GET.dict()
        sign = params.pop("sign")
        if alipay.verify(params, sign):
            order = Orders.objects.get(pk=AliPayView.order_id)
            order.status = 2
            order.save()
        return redirect(reverse("operations:order"))
    • 这样views.py文件已经写完

 

相关内容

    暂无相关文章

评论关闭