Django學習記錄10——Django使用支付寶付款(電腦支付,手機網頁支付,面對面掃碼)

目錄

零之前言

一.註冊支付寶開放平臺賬號

1.註冊

2.創建公私祕鑰

2.項目中添加公私密鑰

二.生成二維碼

1.安裝模塊等

2.模塊的結構

3.電腦支付

4.手機支付

5.面對面掃碼(真二維碼支付)

三.無情開源我的一個小項目代碼

1.urls

2.views

3.模板文件

4.訪問效果


零之前言

網上雖然有很多的Django接入支付寶付款,但是很少看到有面對面掃碼的支付寶教程,所以整合了一下。

主要使用到的模塊Python-Alipay-SDK的樣例等信息:https://github.com/fzlee/alipay/blob/master/README.zh-hans.md

注意此SDK非官方SDK

一.註冊支付寶開放平臺賬號

因爲這一步我已經註冊過了,所以過程可能不會非常詳細。

1.註冊

這過程可能不會太詳細,如果看我的不明白,還是找一找其他大佬的文章吧QAQ

在支付寶開放平臺的開發者中心控制檯裏註冊“研發服務”(開通沙箱功能),你可以把沙箱理解成一個獨立的支付寶,使用獨立的網關、賬號。我們只需要在這上面調試通後,稍微改改配置,就可以上線了!

 

2.創建公私祕鑰

下載我們的 "支付寶開放平臺開發助手"https://opensupport.alipay.com/support/knowledge/20069/201602111105?ant_source=zsearch

創建我們的密鑰

然後我們把我們的公鑰複製到我們的沙箱應用裏:

創建好就是這個亞子:

2.項目中添加公私密鑰

我們在項目裏創建一個文件夾吧,且創兩個文本文件來存放我們的密鑰吧,當然它是有格式的

支付寶公鑰/私鑰格式:

-----BEGIN PUBLIC KEY-----
中間放公鑰(剛纔在網頁生成的下面的那個)
-----END PUBLIC KEY-----
-----BEGIN RSA2 PRIVATE KEY-----
這裏放私鑰(剛纔用軟件生成的那個)
-----END RSA2 PRIVATE KEY-----

然後在Django中寫代碼讀入我們的密鑰文件:我是寫在了Django中的settings裏:

APP_PRIVATE_KEY = open(os.path.join(BASE_DIR, 'Alipay/ali_private_key.pem'),'r').read()
APP_PUBLIC_KEY = open(os.path.join(BASE_DIR, 'Alipay/ali_public_key.pem'),'r').read()

然後我的結構就像這樣

當然,創建文件這一步你可以省略,直接讓這兩個值 = 我們的公私鑰文本。看個人習慣吧

二.生成二維碼

1.安裝模塊等

重申這是非官方SDK

安裝模塊:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple python-alipay-sdk

項目地址:https://github.com/fzlee/alipay

2.模塊的結構

模塊的結構是:
創建一個阿里客戶端實例    ->    調用實例的函數(創建實例的時候基本上已經把我們要配置的東西配置好了)

我們先來看看創建實例的例子吧,作者文檔解釋:

alipay = AliPay(
    appid="", #這個是剛纔你創建的時候保存的appid
    app_notify_url=None,  # 默認回調url
    app_private_key_string=app_private_key_string,
    # 支付寶的公鑰,驗證支付寶回傳消息使用,不是你自己的公鑰,
    alipay_public_key_string=alipay_public_key_string,
    sign_type="RSA2" # RSA 或者 RSA2
    debug=True  # 默認False
)

尤其要說一下我們的debug模式:在Pycharm中選中Alipay,ctrl+alt+b跳轉去看看他的代碼,網上找,找到和debug模式有關的:

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

這有兩個網關,這是什麼意思呢?仔細對比支付寶的文檔,我們就可以知道帶dev的是沙箱模式的網關。所以我們Debug==True的時候用的是沙箱模式,我們先調試,等要發佈的時候改成False就行了。注意此處設置錯誤,後面會出現奇怪的錯誤。

3.電腦支付

支付寶開發者文檔:https://docs.open.alipay.com/270/105898/

作者樣例:

# 如果你是Python 2用戶(考慮考慮升級到Python 3吧),請確保非ascii的字符串爲utf8編碼:
subject = u"測試訂單".encode("utf8")
# 如果你是 Python 3的用戶,使用默認的字符串即可
subject = "測試訂單"

# 電腦網站支付,需要跳轉到https://openapi.alipay.com/gateway.do? + order_string
order_string = alipay.api_alipay_trade_page_pay(
    out_trade_no="20161112",
    total_amount=0.01,
    subject=subject,
    return_url="https://example.com",
    notify_url="https://example.com/notify" # 可選, 不填則使用默認notify url
)

我的代碼:

        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=payid,  #交易單號
            total_amount=paysum, #共付金額
            subject=payname, #項目名稱
            return_url="https://baidu.com", #支付成功後默認跳轉的界面
            notify_url="http://your_web/app/callback_post/"  # 這個用於接收回調的POST信息,具體返回值可在官方API列表查詢
        )
        return redirect("https://openapi.alipaydev.com/gateway.do?" + order_string) #這是沙箱鏈接

訪問結果:

4.手機支付

手機支付就是彈出一個手機網頁,然後點擊它後自動拉取支付寶應用

支付寶開發者文檔:https://docs.open.alipay.com/60/104790

作者樣例:(參數基本上同電腦支付)

# 手機網站支付,需要跳轉到https://openapi.alipay.com/gateway.do? + order_string
order_string = alipay.api_alipay_trade_wap_pay(
    out_trade_no="20161112",
    total_amount=0.01,
    subject=subject,
    return_url="https://example.com",
    notify_url="https://example.com/notify" # 可選, 不填則使用默認notify url
)

我的代碼:

        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=payid,
            total_amount=paysum,
            subject=payname,
            return_url="https://example.com",
            notify_url="http://your_web/app/callback_post/"
        )
        return redirect("https://openapi.alipaydev.com/gateway.do?" + order_string)

訪問結果:

如此小節開篇所示。

5.面對面掃碼(真二維碼支付)

支付寶開發者文檔:https://docs.open.alipay.com/194/106078/

作者樣例:

alipay = AliPay(appid="", ...)

# create an order
alipay.api_alipay_trade_precreate    (
    subject="test subject",
    out_trade_no="out_trade_no",
    total_amount=100
)

# check order status
paid = False
for i in range(10):
    # check every 3s, and 10 times in all
    print("now sleep 3s")
    time.sleep(3)
    result = alipay.api_alipay_trade_query(out_trade_no="out_trade_no")
    if result.get("trade_status", "") == "TRADE_SUCCESS":
        paid = True
        break
    print("not paid...")

# order is not paid in 30s , cancel this order
if paid is False:
    alipay.api_alipay_trade_cancel(out_trade_no=out_trade_no)

我的代碼:

由於這個模型和前兩個不一樣,它是創建一個請求,然後返回一堆參數,至於用戶是否真的支付了,我們需要再用循環然後使用一個API查詢是否交易成功,我只寫了生成二維碼的代碼:因爲使用了生成二維碼的部分代碼,所以要用到qrcode和image兩個包,而IO包python自帶

先下載包:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple qrcode
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple image
#注意BytesIO()Pycharm是不能搜到的我們自己導入模塊
#from io import *
data = alipay.api_alipay_trade_precreate(
            subject=payname,
            # 這個必須確保不同,所以我們需要加一些前綴才行
            out_trade_no="face" + payid,
            total_amount= int(paysum)
        )
        if data["code"] == "10000": #這個是API調用成功
            img = qrcode.make(data["qr_code"])
            buf = BytesIO()
            img.save(buf)
            image_stream = buf.getvalue()
            response = HttpResponse(image_stream, content_type="image/png")
            return response
        else:
            return HttpResponse("<a href=""/app/alipay"">創建失敗,點此返回</a>")

對於代碼裏的data的返回值,我們可以參考官方的API參考文檔:https://docs.open.alipay.com/api_1/alipay.trade.create

對於生成二維碼的代碼,自己百度其意思。

訪問結果:

三.無情開源我的一個小項目代碼

真的很垃圾,別噴我,但是夠看了。

1.urls

說明:通過訪問/app/alipay來進行我們的支付選擇,然後通過/app/pay_post/返回顯示

    re_path(r"alipay/", views.alipay, name='alipay'),
    re_path(r"pay_post/", views.pay_post, name='pay_post'),
    re_path(r"callback_post/", views.repay_post, name='callback_post'),

2.views

def alipay(request):
    return render(request, 'creatalipay.html') #返回支付的界面

def pay_post(request):
    payid = request.POST.get('payid')
    paysum = request.POST.get('paysum')
    payname = request.POST.get('payname')
    payway = request.POST.get('payway')
    alipay = AliPay(
        appid="your appid",
        app_notify_url=None,
        app_private_key_string=APP_PRIVATE_KEY,
        alipay_public_key_string=APP_PUBLIC_KEY,
        sign_type="RSA2",
    debug = True  # True就是沙箱環境 False就是正式環境
    )
    if payway == "phone":
        order_string = alipay.api_alipay_trade_wap_pay(
            out_trade_no=payid,
            total_amount=paysum,
            subject=payname,
            return_url="https://example.com",
            notify_url="http://your web/app/callback_post/"
        )
        return redirect("https://openapi.alipaydev.com/gateway.do?" + order_string)
    elif payway == "pc":
        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=payid,
            total_amount=paysum,
            subject=payname,
            return_url="https://example.com",
            notify_url="http://your web/app/callback_post/"
        )
        return redirect("https://openapi.alipaydev.com/gateway.do?" + order_string)
    elif payway == "face":
        data = alipay.api_alipay_trade_precreate(
            subject=payname,
            out_trade_no="face" + payid,
            total_amount= int(paysum)
        )
        if data["code"] == "10000":
            img = qrcode.make(data["qr_code"])
            buf = BytesIO()
            img.save(buf)
            image_stream = buf.getvalue()
            response = HttpResponse(image_stream, content_type="image/png")
            return response
        else:
            return HttpResponse("<a href=""/app/alipay"">創建失敗,點此返回</a>")
    else:
        return HttpResponse("<a href=""/app/alipay"">創建失敗,點此返回</a>")

def repay_post(request): #這只是一個簡單的驗證
    data = request.POST.get('total_amount')
    print("成功支付" + data)
    return HttpResponse("1")

3.模板文件

creatalipay.html

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>創建訂單</title>
</head>
<body>
<div style ="text-align: center;">
    <form action="{% url 'app:pay_post' %}" method ="post">
        <span>訂單號:</span> <input type="text" name ="payid">
        <br>
        <span>金  額:</span> <input type = "text" name ="paysum">
        <br>
        <span>項目名:</span> <input type = "text" name ="payname">
        <br>
        <select name ="payway">
            <option value="face">掃碼</option>
            <option value="phone" >手機支付</option>
            <option value="pc">電腦支付</option>
        </select>
        <br>
        <button>提交</button>
    </form>
</div>
</body>
</html>

4.訪問效果

剩下的就和剛纔演示的一模一樣。

發佈了54 篇原創文章 · 獲贊 30 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章