Build Alipay Payment Integration with Django: Step‑by‑Step Guide

This tutorial walks you through creating a Django project, configuring Alipay RSA keys, implementing the PC‑side payment API in Python, building the necessary front‑end pages, and wiring up views and URLs so you can test a full Alipay payment flow locally.

Python Crawling & Data Mining
Python Crawling & Data Mining
Python Crawling & Data Mining
Build Alipay Payment Integration with Django: Step‑by‑Step Guide

1. Introduction

The article introduces a practical project: using the Python web framework Django to implement Alipay payment. It assumes you have basic Python and Django knowledge and want to integrate the popular Chinese payment gateway.

2. Create Django Project and App

First, create a new Django project and an application inside it. The following screenshot shows the directory structure.

3. Configure and Start

Set up urls.py for the project and the new app. The screenshots illustrate the required URL patterns and the view functions that will be added later.

4. Log in to Alipay and Generate RSA Keys

Log in to the Alipay developer console, create an application, and set the encryption method to RSA2 (SHA256). Download the Alipay key generator or use openssl to generate a public/private key pair. Save the generated keys locally.

After obtaining the public and private keys, place them in a folder (e.g., rsakey) inside the Django app.

5. PC‑Side Alipay Payment Interface (Python)

The following class encapsulates the Alipay PC payment API. It handles request signing, building the request body, and verifying responses.

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, urlparse, parse_qs
from base64 import decodebytes, encodebytes
import json

class AliPay(object):
    """Alipay PC payment interface"""
    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())
        self.__gateway = ("https://openapi.alipaydev.com/gateway.do"
                         if debug else "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",
        }
        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(f"{k}={v}" for k, v in unsigned_items)
        sign = self.sign(unsigned_string.encode("utf-8"))
        quoted_string = "&".join(f"{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 = [k for k, v in data.items() if isinstance(v, dict)]
        for key in complex_keys:
            data[key] = json.dumps(data[key], separators=(",", ":"))
        return sorted(data.items())

    def sign(self, unsigned_string):
        signer = PKCS1_v1_5.new(self.app_private_key)
        signature = signer.sign(SHA256.new(unsigned_string))
        return encodebytes(signature).decode("utf8").replace("
", "")

    def _verify(self, raw_content, signature):
        signer = PKCS1_v1_5.new(self.alipay_public_key)
        digest = SHA256.new()
        digest.update(raw_content.encode("utf8"))
        return signer.verify(digest, decodebytes(signature.encode("utf8")))

    def verify(self, data, signature):
        data.pop("sign_type", None)
        unsigned_items = self.ordered_data(data)
        message = "&".join(f"{k}={v}" for k, v in unsigned_items)
        return self._verify(message, signature)

Save this class as pay.py inside the Django app.

6. Front‑End Pages

Two simple HTML templates are used: index.html to display a product list and show.html to show the payment result.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Product List</title>
    <style>
        table, th, td {border:1px solid #0094ff;}
        table {width:300px; line-height:25px; text-align:center; border-collapse:collapse;}
        a {text-decoration:none;}
    </style>
</head>
<body>
    <h1>Welcome to the Shop</h1>
    <table border="1">
        <thead>Product Catalog</thead>
        <tr><td>Name</td><td>Price</td><td>Qty</td><td>Buy</td></tr>
        <tr><td>Pear</td><td>0.1</td><td>1</td><td><a href="{% url 'dingdan' %}">Buy</a></td></tr>
    </table>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Result</title>
</head>
<body>
    <h1>Payment Result: {{msg}}</h1>
</body>
</html>

7. Views

from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse
from .pay import AliPay
import uuid
from urllib.parse import parse_qs

def index(request):
    return render(request, 'index.html')

def dingdan(request):
    alipay = AliPay(
        appid="YOUR_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:\path\to\private2048.txt',
        alipay_public_key_path=r'C:\path\to\paypublic.txt',
        debug=True,
    )
    res = alipay.direct_pay(subject='Pear', out_trade_no=str(uuid.uuid4()), total_amount='0.1')
    url = f'https://openapi.alipaydev.com/gateway.do?{res}'
    return redirect(url)

def show(request):
    if request.method == 'GET':
        alipay = AliPay(
            appid="YOUR_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:\path\to\private2048.txt',
            alipay_public_key_path=r'C:\path\to\paypublic.txt',
            debug=True,
        )
        param = request.GET.dict()
        sign = param.pop('sign', None)
        status = alipay.verify(param, sign)
        msg = '支付成功' if status else '支付失败'
        return render(request, 'show.html', {'msg': msg})
    return render(request, 'show.html', {'msg': '只支持GET请求'})

def check(request):
    if request.method == 'POST':
        alipay = AliPay(
            appid="YOUR_APPID",
            app_notify_url='http://127.0.0.1:8000/paypay/check/',
            return_url='http://127.0.0.1:8000/show_msg/',
            app_private_key_path=r'C:\path\to\private2048.txt',
            alipay_public_key_path=r'C:\path\to\paypublic.txt',
            debug=True,
        )
        body = request.body.decode('utf-8')
        post_data = parse_qs(body)
        post_dict = {k: v[0] for k, v in post_data.items()}
        sign = post_dict.pop('sign', None)
        status = alipay.verify(post_dict, sign)
        return HttpResponse('支付成功' if status else '支付失败')
    return HttpResponse('只支持POST请求')

8. URL Configuration

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'),
]

9. Run the Project

After completing the above steps, run python manage.py migrate and python manage.py runserver. Open the browser, navigate to the index page, click the purchase link, and you will be redirected to the Alipay sandbox payment page.

10. Summary

The tutorial demonstrates a complete Alipay integration in a Django sandbox environment, covering key generation, API signing, front‑end templates, view logic, and URL routing. Replace placeholder APPID and key files with your own credentials before deploying to production.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythonDjangoWeb DevelopmentPayment IntegrationAlipay
Python Crawling & Data Mining
Written by

Python Crawling & Data Mining

Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.