Python project combat-teach you how to use Django framework to realize Alipay payment

Click on " Python crawler and data mining " above to follow

Reply to " Books " to receive a total of 10 e-books of Python from beginner to advanced

now

day

Chickens

soup

Feeling closer to hometown is even more timid, and dare not ask anyone.

I. Introduction

The Spring Festival is approaching, and everyone is sure that all kinds of money will be spent. I believe that when you pay, WeChat and Alipay will definitely be your first choice. Today, the editor on a whim, brings you a very interesting project, that is to use the Python web framework Django to realize Alipay payment, not much nonsense, let's take a look at how to achieve it.

Two, build django application

Let's create a Django project and then create an application in it, as shown in the figure:

Three, configure and start

Then we set the content of the urls file, as shown in the figure:

Then create a urls.py file in the sub-application. Of course, you can also write some view functions directly in the urls.py file in the project. Finally, we write the view function and add the view function to the urls.py file, as shown in the figure:

Finally, we need to submit the changes, open the directory where the project’s manage.py file is located and open cmd, and enter the following command:

python manage.py migrate

Now let us run this project locally, still in this directory, as follows:

python manage.py runserver

Seeing the output result indicates that this sub-application has been started and returned the result. We can also run the Django application directly in the root directory of the created project without going through the sub-application. First, create a view.py file in the pay directory, and then add it to the urls.py file in the directory, as follows:

Look at the picture after running:

Fourth, log in to Alipay and generate rsa key

First log in to the Alipay that we want to collect, address:

https://auth.alipay.com/login/ant_sso_index.htm?goto=https%3A%2F%2Fopenhome.alipay.com%2Fplatform%2FappDaily.htm%3Ftab%3Dinfo

Then log in, as shown in the figure:

Then click the settings behind RSA2 (SHA256), click the public key and download the Alipay key generator or openssl to generate the key, here I choose the Alipay key generator, as shown in the figure:

Then click it to jump to the download interface to download, as shown in the figure:

After downloading, open the tool, select the key length and key format and generate the key, as shown in the figure:

Then enter the public and private key directory, copy this to the sub-application directory of our Django project, and rename it, and wait for it to be used, as shown in the figure:

Then we enter our developer center console, address:

https://open.alipay.com/platform/developerIndex.htm

Then we go to create an application, as shown in the figure:

Just fill in truthfully as required. Then we set its interface encryption method, as shown in the figure:

After verification, fill in the application public key just generated, as shown in the figure:

At this time, the application public key and Alipay public key will appear, save the Alipay public key, as shown in the figure:

Then we save the generated public and private keys of the application and the public key of Alipay as files with the following content, as shown in the figure:

Save these three files in the rsakey folder. Now that the preparations are done, let's start writing the Alipay payment interface.

Note: You can use the key to call the Alipay interface after the project is approved!

4. Alipay payment interface on PC

Here we use a class to encapsulate it, as follows:

from datetime import datetime
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from urllib.parse import quote_plus
from urllib.parse import urlparse, parse_qs
from base64 import decodebytes, encodebytes
import json




class AliPay(object):
    """
    支付宝支付接口(PC端支付接口)
    """


    def __init__(self, appid, app_notify_url, app_private_key_path,
                 alipay_public_key_path, return_url, debug=False):
        self.appid = appid
        self.app_notify_url = app_notify_url
        self.app_private_key_path = app_private_key_path
        self.app_private_key = None
        self.return_url = return_url
        with open(self.app_private_key_path) as fp:
            self.app_private_key = RSA.importKey(fp.read())
        self.alipay_public_key_path = alipay_public_key_path
        with open(self.alipay_public_key_path) as fp:
            self.alipay_public_key = RSA.importKey(fp.read())


        if debug is True:
            self.__gateway = "https://openapi.alipaydev.com/gateway.do"
        else:
            self.__gateway = "https://openapi.alipay.com/gateway.do"


    def direct_pay(self, subject, out_trade_no, total_amount, return_url=None, **kwargs):
        biz_content = {
            "subject": subject,
            "out_trade_no": out_trade_no,
            "total_amount": total_amount,
            "product_code": "FAST_INSTANT_TRADE_PAY",
            # "qr_pay_mode":4
        }


        biz_content.update(kwargs)
        data = self.build_body("alipay.trade.page.pay", biz_content, self.return_url)
        return self.sign_data(data)


    def build_body(self, method, biz_content, return_url=None):
        data = {
            "app_id": self.appid,
            "method": method,
            "charset": "utf-8",
            "sign_type": "RSA2",
            "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "version": "1.0",
            "biz_content": biz_content
        }


        if return_url is not None:
            data["notify_url"] = self.app_notify_url
            data["return_url"] = self.return_url


        return data


    def sign_data(self, data):
        data.pop("sign", None)
        # 排序后的字符串
        unsigned_items = self.ordered_data(data)
        unsigned_string = "&".join("{0}={1}".format(k, v) for k, v in unsigned_items)
        sign = self.sign(unsigned_string.encode("utf-8"))
        # ordered_items = self.ordered_data(data)
        quoted_string = "&".join("{0}={1}".format(k, quote_plus(v)) for k, v in unsigned_items)


        # 获得最终的订单信息字符串
        signed_string = quoted_string + "&sign=" + quote_plus(sign)
        return signed_string


    def ordered_data(self, data):
        complex_keys = []
        for key, value in data.items():
            if isinstance(value, dict):
                complex_keys.append(key)


        # 将字典类型的数据dump出来
        for key in complex_keys:
            data[key] = json.dumps(data[key], separators=(',', ':'))


        return sorted([(k, v) for k, v in data.items()])


    def sign(self, unsigned_string):
        # 开始计算签名
        key = self.app_private_key
        signer = PKCS1_v1_5.new(key)
        signature = signer.sign(SHA256.new(unsigned_string))
        # base64 编码,转换为unicode表示并移除回车
        sign = encodebytes(signature).decode("utf8").replace("\n", "")
        return sign


    def _verify(self, raw_content, signature):
        # 开始计算签名
        key = self.alipay_public_key
        signer = PKCS1_v1_5.new(key)
        digest = SHA256.new()
        digest.update(raw_content.encode("utf8"))
        if signer.verify(digest, decodebytes(signature.encode("utf8"))):
            return True
        return False


    def verify(self, data, signature):
        if "sign_type" in data:
            sign_type = data.pop("sign_type")
        # 排序后的字符串
        unsigned_items = self.ordered_data(data)
        message = "&".join(u"{}={}".format(k, v) for k, v in unsigned_items)
        return self._verify(message, signature)

In order to facilitate the call, we put this Python file in the sub-application directory and named it pay.py.

Five, write front-end pages

We use the name and price of the front-end product to generate the corresponding product information and initiate a payment request, as follows:

index.html (product homepage)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
     <style>
  table,table tr th, table tr td { border:1px solid #0094ff; }
        table { width:300px; min-height: 25px; line-height: 25px; text-align: center; border-collapse: collapse; padding:2px;}   
        a{
            text-decoration: none;
        }
</style>
</head>
<body>
    <h1>欢迎来到购物商场</h1>
    <table border="1">
    <thead>商品目录</thead>
    <tr>
        <td>商品名</td>
        <td>商品单价</td>
        <td>商品数量</td>
        <td>是否购买</td>
    </tr>
    <tr>
        <td>梨子</td>
        <td>0.1</td>
        <td>1</td>
        <td><a href="{% url 'dingdan' %}">购买</a></td>
    </table>
</body>
</html>

show.html (payment result display page)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>支付结果:{
    
    {msg}}</h1>
</body>
</html>

Six, write a view function to handle rendering

from django.shortcuts import render,redirect
from django.http import HttpResponse,JsonResponse
from .pay import AliPay
import uuid
from urllib.parse import parse_qs
# Create your views here.
def index(request):
     return render(request,'index.html')


def dingdan(request):
    # 实例化AliPay
    alipay = AliPay(
        appid="自己的APPID",
        app_notify_url='http://127.0.0.1:8000/paypay/check/',#支付宝会向这个地址发送post请求
        return_url='http://127.0.0.1:8000/paypay/show/',#支付宝会向这个地址发送get请求
        app_private_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\private2048.txt',  # 应用私钥
        alipay_public_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\paypublic.txt',  # 支付宝公钥
        debug=True,  # 默认是False
    )
    # 定义请求地址传入的参数
    res=alipay.direct_pay(
        subject='梨子',  # 商品描述
        out_trade_no=str(uuid.uuid4()),  # 订单号
        total_amount='0.1',  # 交易金额(单位是元,保留两位小数)
    )
    #生成跳转到支付宝支付页面的url
    url='https://openapi.alipaydev.com/gateway.do?{0}'.format(res)
    return redirect(url)






def show(request):
    if request.method == 'GET':
        alipay = AliPay(
            appid="自己的APPID",  
            app_notify_url='http://127.0.0.1:8000/paypay/check/',
            return_url='http://127.0.0.1:8000/paypay/show/',
            app_private_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\private2048.txt',  # 应用私钥
            alipay_public_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\paypublic.txt',  # 支付宝公钥
            debug=True,  # 默认是False
        )
        param=request.GET.dict()  # 获取请求携带的参数并转换成字典类型
        sign=param.pop('sign', None)  # 获取sign的值
        # 对sign参数进行验证
        statu = alipay.verify(param,sign)
        if statu:
            return render(request, 'show.html', {'msg': '支付成功'})
        else:
            return render(request, 'show.html', {'msg': '支付失败'})
    else:
        return render(request, 'show.html', {'msg': '只支持GET请求,不支持其它请求'})


def check(request):
    if request.method=='POST':
        alipay=AliPay(appid="自己的APPID",
            app_notify_url='http://127.0.0.1:8000/paypay/check/',  # 支付宝会向这个地址发送post请求
            return_url='http://127.0.0.1:8000/show_msg/',  # 支付宝会向这个地址发送get请求
            app_private_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\private2048.txt',  # 应用私钥
            alipay_public_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\paypublic.txt',  # 支付宝公钥
            debug=True,
        )
        body=request.body.decode('utf-8')  # 转成字符串
        post_data = parse_qs(body)  # 根据&符号分割
        post_dict = {}
        for k, v in post_data.items():
            post_dict[k] = v[0]
        sign = post_dict.pop('sign', None)
        status = alipay.verify(post_dict, sign)
        if status:  # 支付成功
            return HttpResponse('支付成功')
        else:
            return HttpResponse('支付失败')
    else:
        return HttpResponse('只支持POST请求')

        

Seven, add the routing function to the url rule

from django.urls import path
from . import views
urlpatterns=[
  path('',views.index,name='index'),
  path('dingdan/',views.dingdan,name='dingdan'),
  path('show/',views.show,name='show'),
  path('check/',views.check,name='check'),
]

8. Run the project

All the preparations are done, let's quickly try to run the project, as follows:

You can see that the link successfully jumped to the payment interface after we purchased the goods.

Nine, summary

The Alipay payment environment is implemented in a sandbox, so there is no doubt about its security. The code editor has been packaged, but the appid and public and private keys in it need to be filled in by yourself.

Finally, those who need the project code of this article, please reply to the " Alipay " keyword in the backstage of the official account to obtain it. If you encounter any problems during the operation, please feel free to leave a message or add a friend. Fix the bug!

------------------- End -------------------

Recommendations of previous wonderful articles:

Welcome everyone to like , leave a message, forward, reprint, thank you for your company and support

If you want to join the Python learning group, please reply in the background [ Enter the group ]

Thousands of rivers and mountains are always in love, can you click [ Looking ]

/Today's message topic/

Just say a word or two~~

Guess you like

Origin blog.csdn.net/pdcfighting/article/details/113764680