零基礎(chǔ)實(shí)踐Python調(diào)用支付寶沙箱生成收款二維碼并掃碼支付
一、概述
本文將引導(dǎo)您一步步實(shí)現(xiàn)使用Python語言,通過支付寶開放平臺(tái)的 alipay.trade.precreateAPI,在沙箱環(huán)境中生成一個(gè)收款二維碼,并使用沙箱買家賬號(hào)進(jìn)行掃碼支付的全過程。這非常適合初次接觸第三方支付集成的開發(fā)者,幫助您理解支付流程的核心步驟。
二、準(zhǔn)備工作
在開始編碼之前,您需要完成以下準(zhǔn)備工作:
1.注冊(cè)支付寶開放平臺(tái)賬號(hào):使用您的手機(jī)號(hào)注冊(cè)一個(gè)開發(fā)者賬號(hào)。
2.創(chuàng)建應(yīng)用:登錄后,在控制臺(tái)創(chuàng)建一個(gè)應(yīng)用。在“開發(fā)信息”或“沙箱應(yīng)用”頁(yè)面,您可以找到該應(yīng)用對(duì)應(yīng)的沙箱APPID、沙箱買家賬號(hào)(通常是一個(gè)郵箱或ID)和固定登錄密碼。

3.獲取密鑰:在應(yīng)用的“開發(fā)設(shè)置”中,按照指引生成 RSA2 密鑰對(duì)。您需要將應(yīng)用私鑰保存好,并將應(yīng)用公鑰上傳到平臺(tái)。同時(shí),從平臺(tái)獲取支付寶公鑰。


4.安裝必要的 Python 庫(kù):在您的開發(fā)環(huán)境中安裝 alipay-sdk-python 和 qrcode[pil] 庫(kù)。
pip install alipay-sdk-python qrcode[pil]
三、核心代碼實(shí)現(xiàn)
我們將使用支付寶官方推薦的 alipay.aop.api 模塊來實(shí)現(xiàn)。以下是完整的 Python 代碼,包含了生成二維碼、保存圖片和查詢支付狀態(tài)的功能。
import qrcode
# 注意:根據(jù)源碼路徑導(dǎo)入 DefaultAlipayClient 類
from alipay.aop.api.DefaultAlipayClient import DefaultAlipayClient
from alipay.aop.api.AlipayClientConfig import AlipayClientConfig
from alipay.aop.api.domain.AlipayTradePrecreateModel import AlipayTradePrecreateModel
from alipay.aop.api.request.AlipayTradePrecreateRequest import AlipayTradePrecreateRequest
import json
# ====================== 配置沙箱環(huán)境參數(shù) ======================
# 線上應(yīng)用同步到沙箱后的APPID,該APPID跟線上應(yīng)用一致
APP_ID = "YOUR_SANDBOX_APP_ID" # <--- 請(qǐng)?zhí)鎿Q為你的沙箱APPID
# 沙箱分配的默認(rèn)應(yīng)用私鑰(完整字符串,無需額外格式轉(zhuǎn)換)
APP_PRIVATE_KEY = """-----BEGIN RSA PRIVATE KEY-----
YOUR_PRIVATE_KEY_HERE
-----END RSA PRIVATE KEY-----""" # <--- 請(qǐng)?zhí)鎿Q為你的應(yīng)用私鑰
# 沙箱分配的默認(rèn)支付寶公鑰
ALIPAY_PUBLIC_KEY = """-----BEGIN PUBLIC KEY-----
YOUR_ALIPAY_PUBLIC_KEY_HERE
-----END PUBLIC KEY-----""" # <--- 請(qǐng)?zhí)鎿Q為你的支付寶公鑰
# 全局變量,用于存儲(chǔ)訂單號(hào)
OUT_TRADE_NO = "qr_test_order_" + str(int(time.time())) # 使用時(shí)間戳生成唯一訂單號(hào),避免重復(fù)
def get_client():
"""
初始化 Alipay 客戶端
"""
# ====================== 初始化支付寶客戶端配置 ======================
# 創(chuàng)建客戶端配置對(duì)象
client_config = AlipayClientConfig()
# 設(shè)置沙箱環(huán)境網(wǎng)關(guān)
client_config.server_url = "https://openapi-sandbox.dl.alipaydev.com/gateway.do"
client_config.app_id = APP_ID
client_config.app_private_key = APP_PRIVATE_KEY
client_config.alipay_public_key = ALIPAY_PUBLIC_KEY
client_config.charset = "utf-8" # 建議使用 utf-8
client_config.sign_type = "RSA2" # 簽名方式
# ====================== 初始化支付寶客戶端 ======================
# 創(chuàng)建DefaultAlipayClient實(shí)例
alipay = DefaultAlipayClient(client_config)
return alipay
def generate_qr_code_for_payment():
"""
使用 alipay.trade.precreate 接口生成收款二維碼
"""
alipay = get_client()
# ====================== 構(gòu)造交易創(chuàng)建請(qǐng)求 ======================
# 創(chuàng)建請(qǐng)求對(duì)象
request = AlipayTradePrecreateRequest()
# 設(shè)置異步通知地址(可選)
request.notify_url = None # 或者設(shè)置你的服務(wù)器地址
# 創(chuàng)建業(yè)務(wù)參數(shù)模型對(duì)象
biz_model = AlipayTradePrecreateModel()
# 設(shè)置訂單號(hào)
biz_model.out_trade_no = OUT_TRADE_NO
# 設(shè)置訂單金額
biz_model.total_amount = "0.01" # 字符串格式,單位元
# 設(shè)置訂單標(biāo)題
biz_model.subject = "沙箱測(cè)試商品-掃碼支付"
# 設(shè)置訂單超時(shí)時(shí)間 (可選)
biz_model.timeout_express = "5m" # 例如 5分鐘
# 將業(yè)務(wù)模型綁定到請(qǐng)求對(duì)象
request.biz_model = biz_model
try:
# 執(zhí)行請(qǐng)求,獲取響應(yīng)對(duì)象
response = alipay.execute(request)
print("--- API 響應(yīng) ---")
print(response)
# 解析 JSON 響應(yīng)
response_dict = json.loads(response)
# 檢查響應(yīng)是否成功
if response_dict.get('code') == '10000':
qr_code_str = response_dict['qr_code']
print(f"\n獲取到的 QR Code 字符串:\n{qr_code_str}")
# --- 生成二維碼圖片 ---
# 1. 創(chuàng)建二維碼實(shí)例
qr = qrcode.QRCode(
version=1, # 控制大小,1是最小的
error_correction=qrcode.constants.ERROR_CORRECT_L, # 錯(cuò)誤糾正級(jí)別
box_size=4, # 每個(gè)小格子包含的像素?cái)?shù)
border=4, # 邊框的格子厚度
)
# 2. 添加數(shù)據(jù)
qr.add_data(qr_code_str)
qr.make(fit=True)
# 3. 創(chuàng)建圖像
img = qr.make_image(fill_color="black", back_color="white")
# 4. 保存圖片到本地
qr_filename = f"payment_qr_{biz_model.out_trade_no}.png"
img.save(qr_filename)
print(f"\n二維碼已生成并保存為: {qr_filename}")
print("請(qǐng)使用支付寶手機(jī) App 掃描此二維碼進(jìn)行支付測(cè)試。")
return qr_filename # 返回文件名以供后續(xù)使用
else:
# 如果 API 返回失敗
sub_code = response_dict.get('sub_code')
sub_msg = response_dict.get('sub_msg')
print(f"\nAPI 調(diào)用失敗。子錯(cuò)誤碼: {sub_code}, 子錯(cuò)誤信息: {sub_msg}")
return None
except Exception as e:
# 捕獲其他可能的異常
print(f"\n調(diào)用 API 時(shí)發(fā)生異常: {e}")
return None
def query_payment_status(out_trade_no):
"""
查詢交易狀態(tài)
:param out_trade_no: 商戶訂單號(hào)
"""
# 注意:新版 aop api 可能沒有直接封裝 api_alipay_trade_query
# 我們需要手動(dòng)構(gòu)造請(qǐng)求
alipay = get_client()
from alipay.aop.api.request.AlipayTradeQueryRequest import AlipayTradeQueryRequest
from alipay.aop.api.domain.AlipayTradeQueryModel import AlipayTradeQueryModel
request = AlipayTradeQueryRequest()
biz_model = AlipayTradeQueryModel()
biz_model.out_trade_no = out_trade_no
# 或者使用支付寶交易號(hào) (trade_no) 查詢
# biz_model.trade_no = "2021030122001234567890"
request.biz_model = biz_model
try:
result = alipay.execute(request)
print("\n--- 查詢結(jié)果 ---")
print(result)
result_dict = json.loads(result)
if result_dict.get('code') == '10000':
trade_status = result_dict.get('trade_status')
if trade_status:
print(f"訂單狀態(tài): {trade_status}")
if trade_status in ['TRADE_SUCCESS', 'TRADE_FINISHED']:
print("支付成功!")
return True
elif trade_status == 'WAIT_BUYER_PAY':
print("等待買家付款...")
return False
else:
print(f"其他狀態(tài): {trade_status},請(qǐng)查閱文檔。")
return False
else:
print("未找到交易狀態(tài)。")
return False
else:
sub_code = result_dict.get('sub_code')
sub_msg = result_dict.get('sub_msg')
print(f"查詢失敗: {sub_msg} ({sub_code})")
return False
except Exception as e:
print(f"\n查詢失敗: {e}")
return False
if __name__ == "__main__":
import time # 引入time模塊用于生成唯一訂單號(hào)和延時(shí)
print("--- 開始支付寶沙箱掃碼支付API調(diào)用示例 (使用 aop.api) ---")
# 生成收款二維碼
qr_file = generate_qr_code_for_payment()
if not qr_file:
print("二維碼生成失敗,程序退出。")
exit()
# 提示用戶支付后,可以手動(dòng)查詢狀態(tài)
print("\n請(qǐng)掃描生成的二維碼完成支付,支付完成后按 Enter 鍵查詢支付結(jié)果...")
input() # 等待用戶按鍵
# 查詢剛剛生成的訂單狀態(tài) (需要將訂單號(hào)傳入)
query_payment_status(OUT_TRADE_NO)
print("\n--- 示例結(jié)束 ---")
四、代碼詳解
- 配置參數(shù):
APP_ID,APP_PRIVATE_KEY,ALIPAY_PUBLIC_KEY必須替換為你自己應(yīng)用的實(shí)際值。OUT_TRADE_NO使用時(shí)間戳生成,確保每次運(yùn)行都是一個(gè)新訂單。 get_client():該函數(shù)負(fù)責(zé)創(chuàng)建一個(gè)AlipayClientConfig對(duì)象,配置沙箱網(wǎng)關(guān)地址、應(yīng)用ID、密鑰等信息,然后用它初始化DefaultAlipayClient實(shí)例。這是后續(xù)所有 API 調(diào)用的基礎(chǔ)。generate_qr_code_for_payment():- 創(chuàng)建
AlipayTradePrecreateRequest和AlipayTradePrecreateModel對(duì)象。 - 在
model中設(shè)置out_trade_no(商戶訂單號(hào)),total_amount(金額),subject(商品標(biāo)題) 等必要參數(shù)。 - 調(diào)用
alipay.execute(request)發(fā)送請(qǐng)求。 - 成功后 (
code == '10000'),從響應(yīng)中提取qr_code字符串。 - 使用
qrcode庫(kù)將該字符串生成二維碼圖片,并保存到本地。
- 創(chuàng)建
query_payment_status(out_trade_no):- 類似地,創(chuàng)建
AlipayTradeQueryRequest和AlipayTradeQueryModel。 - 設(shè)置
out_trade_no來查詢特定訂單的狀態(tài)。 - 調(diào)用
execute并解析結(jié)果,判斷訂單是成功、失敗還是仍在等待支付。
- 類似地,創(chuàng)建
- 主程序 (
if __name__ == "__main__":):按順序執(zhí)行生成二維碼、等待用戶操作、查詢結(jié)果的邏輯。
五、測(cè)試流程
運(yùn)行代碼:在你的 Python 環(huán)境中運(yùn)行上述腳本。
生成二維碼:腳本會(huì)成功調(diào)用 API,并在當(dāng)前目錄下生成一個(gè)名為 payment_qr_*.png 的二維碼圖片文件。
掃碼支付:
下載沙箱版 App:強(qiáng)烈建議下載并安裝支付寶沙箱版 App。

登錄:使用在沙箱應(yīng)用頁(yè)面獲取的 沙箱買家賬號(hào) 和 固定登錄密碼 登錄沙箱版 App。
掃描:在沙箱版 App 中點(diǎn)擊“掃一掃”,掃描電腦上生成的二維碼圖片。
確認(rèn)支付:在手機(jī)上確認(rèn)支付信息并完成支付流程。
查詢結(jié)果:回到電腦端,按回車鍵,腳本會(huì)調(diào)用查詢接口,打印出該筆訂單的最終狀態(tài)(通常是 TRADE_SUCCESS)。
六、常見問題與注意事項(xiàng)
- 字符編碼:務(wù)必設(shè)置
client_config.charset = "utf-8",以避免因中文字符導(dǎo)致的簽名錯(cuò)誤。 - 訂單號(hào) (
out_trade_no):必須在你的應(yīng)用內(nèi)保持唯一,不能重復(fù)提交相同訂單號(hào)。 - 二維碼有效期:
precreate接口生成的二維碼有有效期(如timeout_express所設(shè),默認(rèn)2分鐘,最長(zhǎng)15分鐘)。如果提示“二維碼失效”,很可能是超過了有效期。 - 沙箱環(huán)境:確保所有參數(shù)(APPID, 密鑰, 網(wǎng)關(guān)地址)都指向沙箱環(huán)境,不要與生產(chǎn)環(huán)境混淆。
到此這篇關(guān)于零基礎(chǔ)實(shí)踐Python調(diào)用支付寶沙箱生成收款二維碼并掃碼支付的文章就介紹到這了,更多相關(guān)Python調(diào)用支付寶沙箱內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python中pandas庫(kù)的iloc函數(shù)用法解析
在 Pandas 中,.iloc 是一種用于基于整數(shù)位置進(jìn)行索引的屬性,可以用于獲取 DataFrame 或 Series 中的數(shù)據(jù),這篇文章主要介紹了python中pandas庫(kù)的iloc函數(shù)用法,需要的朋友可以參考下2023-05-05
Python實(shí)現(xiàn)批量提取word文件中文本框內(nèi)容
在日常的辦公中,有時(shí)需要提取多個(gè)word文件中的文字框的內(nèi)容,這篇文章主要為大家介紹了三種常見的方法來提取文本框的內(nèi)容,希望對(duì)大家有一定的幫助2024-02-02
Python2.7實(shí)現(xiàn)多進(jìn)程下開發(fā)多線程示例
這篇文章主要為大家詳細(xì)介紹了Python2.7實(shí)現(xiàn)多進(jìn)程下開發(fā)多線程示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-05-05
Python pandas dataframe之重命名相同列名
這篇文章主要介紹了Python pandas dataframe之重命名相同列名方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09
淺談Django學(xué)習(xí)migrate和makemigrations的差別
這篇文章主要介紹了淺談Django學(xué)習(xí)migrate和makemigrations的差別,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01
基于Python實(shí)現(xiàn)個(gè)人手機(jī)定位分析
TransBigData是一個(gè)為交通時(shí)空大數(shù)據(jù)處理、分析和可視化而開發(fā)的Python包。本文就來用它實(shí)現(xiàn)個(gè)人手機(jī)定位分析,感興趣的小伙伴可以了解一下2023-04-04
numpy ndarray 按條件篩選數(shù)組,關(guān)聯(lián)篩選的例子
今天小編就為大家分享一篇numpy ndarray 按條件篩選數(shù)組,關(guān)聯(lián)篩選的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-11-11
python實(shí)現(xiàn)探測(cè)socket和web服務(wù)示例
這篇文章主要介紹了python實(shí)現(xiàn)探測(cè)socket和web服務(wù)示例,需要的朋友可以參考下2014-03-03
人工智能學(xué)習(xí)Pytorch梯度下降優(yōu)化示例詳解
這篇文章主要為大家介紹了人工智能學(xué)習(xí)Pytorch梯度下降優(yōu)化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2021-11-11

