自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python項目實戰(zhàn)——手把手教你使用Django框架實現(xiàn)支付寶付款

開發(fā) 后端
今天小編心血來潮,為大家?guī)硪粋€很有趣的項目,那就是使用Python web框架Django來實現(xiàn)支付寶支付,廢話不多說,一起來看看如何實現(xiàn)吧。

 

 

一、前言

大家好,我是Python進階者。春節(jié)即將過去,大家過年期間肯定各種掏腰包花花花,小編相信大家在支付時候,微信、支付寶支付肯定是優(yōu)先選擇。今天小編心血來潮,為大家?guī)硪粋€很有趣的項目,那就是使用Python web框架Django來實現(xiàn)支付寶支付,廢話不多說,一起來看看如何實現(xiàn)吧。

二、建立django應用

我們來建立一個Django項目然后在里面創(chuàng)建一個應用,如圖:

 

三、配置并啟動

 

然后我們設(shè)置urls文件的內(nèi)容,如圖:

 

然后再在子應用中創(chuàng)建一個urls.py文件,當然你也可以直接將一些視圖函數(shù)寫在項目中的urls.py文件中。最后我們編寫視圖函數(shù)并把視圖函數(shù)添加到urls.py文件中,如圖:

 

最后我們需要提交更改,打開該項目manage.py文件所在的目錄并打開cmd,輸入如下命令:

python manage.py migrate

現(xiàn)在讓我們來本地跑跑這個項目,還是在該目錄中,如下:

python manage.py runserver

 

看到輸出的結(jié)果表明這個子應用已經(jīng)啟動并返回了結(jié)果。我們也可以不用經(jīng)過子應用直接在創(chuàng)建的項目根目錄下運行啟動Django應用,首先在pay目錄下新建一個view.py文件,然后將其添加到該目錄下的urls.py文件中,如下:

 

運行下看圖:

 

四、登錄支付寶并生成rsa密鑰

首先登錄咱們要收款的支付寶,地址:

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

然后進行登錄,如圖:

 

然后點擊RSA2(SHA256)后面的設(shè)置,點擊公鑰并下載支付寶密鑰生成器或者openssl來生成密鑰,這里我選擇支付寶密鑰生成器,如圖:

 

然后點擊它之后跳轉(zhuǎn)到下載界面下載,如圖:

 

下載好后打開該工具,選擇好密鑰長度和密鑰格式并生成密鑰,如圖:

 

然后進入公私鑰的目錄,將這個復制到我們的Django項目的子應用目錄中,并重命名,等下用的著,如圖:

 

緊接著我們進入自己的開發(fā)者中心控制臺,地址:

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

然后我們?nèi)?chuàng)建一個應用,如圖:

 

按照要求如實填寫即可。然后我們來設(shè)置它的接口加密方式,如圖:


 

 

驗證好了之后填寫剛剛生成的應用公鑰,如圖:

 

此時會出現(xiàn)應用公鑰和支付寶公鑰,將支付寶公鑰保存起來,如圖:

 

然后我們將產(chǎn)生的額應用公私鑰和支付寶公鑰保存為下列內(nèi)容形式的文件,如圖:

將這三個文件都保存在rsakey這個文件夾中?,F(xiàn)在準備工作都做好了,下面開始編寫支付寶支付接口。

 

注:項目審核通過后才可以使用密鑰調(diào)用支付寶接口噢!

四、PC端支付寶支付接口

這里我們使用一個類將它封裝起來,如下:

  1. from datetime import datetime 
  2. from Crypto.PublicKey import RSA 
  3. from Crypto.Signature import PKCS1_v1_5 
  4. from Crypto.Hash import SHA256 
  5. from urllib.parse import quote_plus 
  6. from urllib.parse import urlparse, parse_qs 
  7. from base64 import decodebytes, encodebytes 
  8. import json 
  9.  
  10.  
  11. class AliPay(object): 
  12.     ""
  13.     支付寶支付接口(PC端支付接口) 
  14.     ""
  15.  
  16.     def __init__(self, appid, app_notify_url, app_private_key_path, 
  17.                  alipay_public_key_path, return_url, debug=False): 
  18.         self.appid = appid 
  19.         self.app_notify_url = app_notify_url 
  20.         self.app_private_key_path = app_private_key_path 
  21.         self.app_private_key = None 
  22.         self.return_url = return_url 
  23.         with open(self.app_private_key_path) as fp: 
  24.             self.app_private_key = RSA.importKey(fp.read()) 
  25.         self.alipay_public_key_path = alipay_public_key_path 
  26.         with open(self.alipay_public_key_path) as fp: 
  27.             self.alipay_public_key = RSA.importKey(fp.read()) 
  28.  
  29.         if debug is True
  30.             self.__gateway = "https://openapi.alipaydev.com/gateway.do" 
  31.         else
  32.             self.__gateway = "https://openapi.alipay.com/gateway.do" 
  33.  
  34.     def direct_pay(self, subject, out_trade_no, total_amount, return_url=None, **kwargs): 
  35.         biz_content = { 
  36.             "subject": subject, 
  37.             "out_trade_no": out_trade_no, 
  38.             "total_amount": total_amount, 
  39.             "product_code""FAST_INSTANT_TRADE_PAY"
  40.             # "qr_pay_mode":4 
  41.         } 
  42.  
  43.         biz_content.update(kwargs) 
  44.         data = self.build_body("alipay.trade.page.pay", biz_content, self.return_url) 
  45.         return self.sign_data(data) 
  46.  
  47.     def build_body(self, method, biz_content, return_url=None): 
  48.         data = { 
  49.             "app_id": self.appid, 
  50.             "method": method, 
  51.             "charset""utf-8"
  52.             "sign_type""RSA2"
  53.             "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), 
  54.             "version""1.0"
  55.             "biz_content": biz_content 
  56.         } 
  57.  
  58.         if return_url is not None: 
  59.             data["notify_url"] = self.app_notify_url 
  60.             data["return_url"] = self.return_url 
  61.  
  62.         return data 
  63.  
  64.     def sign_data(self, data): 
  65.         data.pop("sign", None) 
  66.         # 排序后的字符串 
  67.         unsigned_items = self.ordered_data(data) 
  68.         unsigned_string = "&".join("{0}={1}".format(k, v) for k, v in unsigned_items) 
  69.         sign = self.sign(unsigned_string.encode("utf-8")) 
  70.         # ordered_items = self.ordered_data(data) 
  71.         quoted_string = "&".join("{0}={1}".format(k, quote_plus(v)) for k, v in unsigned_items) 
  72.  
  73.         # 獲得最終的訂單信息字符串 
  74.         signed_string = quoted_string + "&sign=" + quote_plus(sign) 
  75.         return signed_string 
  76.  
  77.     def ordered_data(self, data): 
  78.         complex_keys = [] 
  79.         for key, value in data.items(): 
  80.             if isinstance(value, dict): 
  81.                 complex_keys.append(key
  82.  
  83.         # 將字典類型的數(shù)據(jù)dump出來 
  84.         for key in complex_keys: 
  85.             data[key] = json.dumps(data[key], separators=(','':')) 
  86.  
  87.         return sorted([(k, v) for k, v in data.items()]) 
  88.  
  89.     def sign(self, unsigned_string): 
  90.         # 開始計算簽名 
  91.         key = self.app_private_key 
  92.         signer = PKCS1_v1_5.new(key
  93.         signature = signer.sign(SHA256.new(unsigned_string)) 
  94.         # base64 編碼,轉(zhuǎn)換為unicode表示并移除回車 
  95.         sign = encodebytes(signature).decode("utf8").replace("\n"""
  96.         return sign 
  97.  
  98.     def _verify(self, raw_content, signature): 
  99.         # 開始計算簽名 
  100.         key = self.alipay_public_key 
  101.         signer = PKCS1_v1_5.new(key
  102.         digest = SHA256.new() 
  103.         digest.update(raw_content.encode("utf8")) 
  104.         if signer.verify(digest, decodebytes(signature.encode("utf8"))): 
  105.             return True 
  106.         return False 
  107.  
  108.     def verify(self, data, signature): 
  109.         if "sign_type" in data: 
  110.             sign_type = data.pop("sign_type"
  111.         # 排序后的字符串 
  112.         unsigned_items = self.ordered_data(data) 
  113.         message = "&".join(u"{}={}".format(k, v) for k, v in unsigned_items) 
  114.         return self._verify(message, signature) 

為了便于調(diào)用,我們將這個Python文件放在子應用的目錄中,命名為pay.py。

五、編寫前端頁面

我們通過前端的商品的名稱和價格來生成對應的商品信息并發(fā)起付款請求,如下:

index.html(商品主頁)

  1. <!DOCTYPE html> 
  2. <html lang="en"
  3. <head> 
  4.     <meta charset="UTF-8"
  5.     <title>Document</title> 
  6.      <style> 
  7.   table,table tr th, table tr td { border:1px solid #0094ff; } 
  8.         table { width:300px; min-height: 25px; line-height: 25px; text-align: center; border-collapse: collapse; padding:2px;}    
  9.         a{ 
  10.             text-decoration: none; 
  11.         } 
  12. </style> 
  13. </head> 
  14. <body> 
  15.     <h1>歡迎來到購物商場</h1> 
  16.     <table border="1"
  17.     <thead>商品目錄</thead> 
  18.     <tr> 
  19.         <td>商品名</td> 
  20.         <td>商品單價</td> 
  21.         <td>商品數(shù)量</td> 
  22.         <td>是否購買</td> 
  23.     </tr> 
  24.     <tr> 
  25.         <td>梨子</td> 
  26.         <td>0.1</td> 
  27.         <td>1</td> 
  28.         <td><a href="{% url 'dingdan' %}">購買</a></td> 
  29.     </table
  30. </body> 
  31. </html> 

show.html(支付結(jié)果顯示頁)

  1. <!DOCTYPE html> 
  2. <html lang="en"
  3. <head> 
  4.     <meta charset="UTF-8"
  5.     <title>Document</title> 
  6. </head> 
  7. <body> 
  8.     <h1>支付結(jié)果:{{msg}}</h1> 
  9. </body> 
  10. </html> 

 

六、編寫視圖函數(shù)處理渲染

  1. from django.shortcuts import render,redirect 
  2. from django.http import HttpResponse,JsonResponse 
  3. from .pay import AliPay 
  4. import uuid 
  5. from urllib.parse import parse_qs 
  6. Create your views here. 
  7. def index(request): 
  8.      return render(request,'index.html'
  9.  
  10. def dingdan(request): 
  11.     # 實例化AliPay 
  12.     alipay = AliPay( 
  13.         appid="自己的APPID"
  14.         app_notify_url='http://127.0.0.1:8000/paypay/check/',#支付寶會向這個地址發(fā)送post請求 
  15.         return_url='http://127.0.0.1:8000/paypay/show/',#支付寶會向這個地址發(fā)送get請求 
  16.         app_private_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\private2048.txt',  # 應用私鑰 
  17.         alipay_public_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\paypublic.txt',  # 支付寶公鑰 
  18.         debug=True,  # 默認是False 
  19.     ) 
  20.     # 定義請求地址傳入的參數(shù) 
  21.     res=alipay.direct_pay( 
  22.         subject='梨子',  # 商品描述 
  23.         out_trade_no=str(uuid.uuid4()),  # 訂單號 
  24.         total_amount='0.1',  # 交易金額(單位是元,保留兩位小數(shù)) 
  25.     ) 
  26.     #生成跳轉(zhuǎn)到支付寶支付頁面的url 
  27.     url='https://openapi.alipaydev.com/gateway.do?{0}'.format(res) 
  28.     return redirect(url) 
  29.  
  30.  
  31.  
  32. def show(request): 
  33.     if request.method == 'GET'
  34.         alipay = AliPay( 
  35.             appid="自己的APPID",   
  36.             app_notify_url='http://127.0.0.1:8000/paypay/check/'
  37.             return_url='http://127.0.0.1:8000/paypay/show/'
  38.             app_private_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\private2048.txt',  # 應用私鑰 
  39.             alipay_public_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\paypublic.txt',  # 支付寶公鑰 
  40.             debug=True,  # 默認是False 
  41.         ) 
  42.         param=request.GET.dict()  # 獲取請求攜帶的參數(shù)并轉(zhuǎn)換成字典類型 
  43.         sign=param.pop('sign', None)  # 獲取sign的值 
  44.         # 對sign參數(shù)進行驗證 
  45.         statu = alipay.verify(param,sign) 
  46.         if statu: 
  47.             return render(request, 'show.html', {'msg''支付成功'}) 
  48.         else
  49.             return render(request, 'show.html', {'msg''支付失敗'}) 
  50.     else
  51.         return render(request, 'show.html', {'msg''只支持GET請求,不支持其它請求'}) 
  52.  
  53. def check(request): 
  54.     if request.method=='POST'
  55.         alipay=AliPay(appid="自己的APPID"
  56.             app_notify_url='http://127.0.0.1:8000/paypay/check/',  # 支付寶會向這個地址發(fā)送post請求 
  57.             return_url='http://127.0.0.1:8000/show_msg/',  # 支付寶會向這個地址發(fā)送get請求 
  58.             app_private_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\private2048.txt',  # 應用私鑰 
  59.             alipay_public_key_path=r'C:\Users\Administrator\Desktop\pay\paypay\rsakey\paypublic.txt',  # 支付寶公鑰 
  60.             debug=True
  61.         ) 
  62.         body=request.body.decode('utf-8')  # 轉(zhuǎn)成字符串 
  63.         post_data = parse_qs(body)  # 根據(jù)&符號分割 
  64.         post_dict = {} 
  65.         for k, v in post_data.items(): 
  66.             post_dict[k] = v[0] 
  67.         sign = post_dict.pop('sign', None) 
  68.         status = alipay.verify(post_dict, sign) 
  69.         if status:  # 支付成功 
  70.             return HttpResponse('支付成功'
  71.         else
  72.             return HttpResponse('支付失敗'
  73.     else
  74.         return HttpResponse('只支持POST請求'

七、添加路由函數(shù)到url規(guī)則中

  1. from django.urls import path 
  2. from . import views 
  3. urlpatterns=[ 
  4.   path('',views.index,name='index'), 
  5.   path('dingdan/',views.dingdan,name='dingdan'), 
  6.   path('show/',views.show,name='show'), 
  7.   path('check/',views.check,name='check'), 

八、運行項目

所有準備工作都做好了,我們趕緊來試著運行下項目吧,如下:

 

可以看到我們購買商品后鏈接成功跳轉(zhuǎn)到支付界面。

九、總結(jié)

該支付寶支付環(huán)境在沙箱中實現(xiàn),因此安全性毋庸置疑,代碼小編已經(jīng)打包好了,不過里面的appid還有公私鑰需要大家自行填寫噢。

最后需要本文項目代碼的小伙伴,請在公眾號后臺回復“支付寶”關(guān)鍵字進行獲取,如果在運行過程中有遇到任何問題,請隨時留言或者加小編好友,小編看到會幫助大家解決bug噢!

本文轉(zhuǎn)載自微信公眾號「Python爬蟲與數(shù)據(jù)挖掘」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Python爬蟲與數(shù)據(jù)挖掘公眾號。

 

責任編輯:武曉燕 來源: Python爬蟲與數(shù)據(jù)挖掘
相關(guān)推薦

2021-02-08 09:07:12

Python項目Django

2021-01-19 09:06:21

MysqlDjango數(shù)據(jù)庫

2021-07-14 09:00:00

JavaFX開發(fā)應用

2021-06-02 11:55:55

微信支付公眾號Java

2020-05-15 08:07:33

JWT登錄單點

2021-03-12 10:01:24

JavaScript 前端表單驗證

2023-04-26 12:46:43

DockerSpringKubernetes

2021-05-27 11:10:42

Python開源包代碼

2022-12-07 08:42:35

2009-11-23 10:02:22

PHP支付寶接口

2021-02-04 09:00:57

SQLDjango原生

2009-11-09 14:57:37

WCF上傳文件

2011-01-06 10:39:25

.NET程序打包

2023-05-15 08:32:45

2021-08-02 07:35:19

Nacos配置中心namespace

2022-06-30 08:13:44

PythonWeb編程語言

2020-12-08 10:32:15

Python郵件tcp

2020-08-12 09:07:53

Python開發(fā)爬蟲

2011-01-10 14:41:26

2011-05-03 15:59:00

黑盒打印機
點贊
收藏

51CTO技術(shù)棧公眾號