支付寶第三方支付(Django框架)
下面是針對使用Django框架專案接入第三方支付寶支付的相關連結:
支付寶開發平臺登入:
https://open.alipay.com/platform/home.htm
沙箱環境:
沙箱應用:https://docs.open.alipay.com/200/105311
沙箱賬號:https://openhome.alipay.com/platform/appDaily.htm?tab=account
支付寶開發者文件
文件主頁:https://openhome.alipay.com/developmentDocument.htm
產品介紹:https://docs.open.alipay.com/270
快速接入:
SDK:https://docs.open.alipay.com/270/106291/
python對接支付寶SDK:https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
python對接支付寶SDK安裝:pip install python-alipay-sdk --upgrade
API列表:https://docs.open.alipay.com/270/105900/
第一項:
接入步驟::
1.建立應用
2.配置金鑰
3.搭建和配置開發環境
4.介面呼叫
接下來是接入支付寶支付的詳細講解:
1.首先我們需要在自己的工程目錄下建立一個pay的包,然後再建立一個keys的資料夾,keys檔案裡面用來存放應用的祕鑰和公匙。
2. 生成應用的私鑰和公鑰
進入終端
切換目錄
cd pay/keys/
輸入下面的命令:
openssl
openssl> genrsa -out app_private_key.pem 2048 # 私鑰RSA2
openssl> rsa -in app_private_key.pem -pubout -out app_public_key.pem # 匯出公鑰
openssl> exit
執行完之後會在你的檔案下面出現下面兩個(密匙和公鑰):
3.修改公匙
首先你需要進入支付寶的開發平臺選擇
建立你的應用,然後進入沙箱開發環境:
什麼是沙箱環境尼?
螞蟻沙箱環境(Beta)是協助開發者進行介面功能開發及主要功能聯調的輔助環境。沙箱環境模擬了開放平臺部分產品的主要功能和主要邏輯(當前沙箱支援產品請參考“沙箱支援產品列表”)。
在開發者應用上線稽核前,開發者可以根據自身需求,先在沙箱環境中瞭解、組合和除錯各種開放介面,進行開發調通工作,從而幫助開發者在應用上線稽核完成後,能更快速、更順利的進行線上除錯和驗收工作。
選擇檢視專案應用公匙
cat app_public_key.pem
把上面專案生成的公匙複製到支付寶的的應用公匙裡面:
再選擇將支付寶的公鑰內容複製到alipay_public_key.pem檔案中
注意,還需要在公鑰檔案中補充開始與結束標誌:
-----BEGIN PUBLIC KEY-----
此處是公鑰內容
-----END PUBLIC KEY-----
然後到這裡就配置好應用程式的密匙和公鑰。
第二項:
發起支付
下面檢視函式的編寫參考(感謝github開發者提供的文件)
https://github.com/fzlee/alipay/blob/master/README.zh-hans.md
1.首先需要安裝python對接支付寶SDK:
pip install python-alipay-sdk --upgrade
接下來是後端的介面說明:
請求方式:Get
請求的路徑:orders/(?P<order_id>\d+)/payment/
引數說明:
order_id 訂單編號 str
alipay_url 支付寶支付連結 str
2.開始編寫檢視函式
需要匯入的類
from rest_framework.views import APIView #REST framework 提供的一級檢視
from rest_framework.response import Response
from orders.models import OrderInfo
from rest_framework import status
from alipay import AliPay #阿里支付
from mall import settings
檢視思路的分析:
當用戶點選支付按鈕的時候,我們需要讓前端傳送一個ajax請求,將 訂單id傳送給我們
必須是登入使用者才可以訪問此介面
1 我們接收引數, 校驗引數
2. 根據訂單id查詢資料
3. 建立支付寶物件
4. 呼叫支付寶的方法生成order_string
5. 拼接url,並且返回
class PaymentView(APIView):
permission_classes = [IsAuthenticated] #請求頭判斷是否的請求的許可權
def get(self,request,order_id):
# 1. 我們接收引數, 校驗引數
# 2. 根據訂單id查詢資料
try:
# 為了讓我們查詢的更準確,我們需要再新增幾個查詢條件
# 查詢未支付的訂單
# 查詢這個使用者的訂單
order = OrderInfo.objects.get(order_id=order_id, #訂單的id
user=request.user,
status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
except OrderInfo.DoesNotExist:
return Response(status.HTTP_400_BAD_REQUEST)
# 3. 建立支付寶物件
app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read() #app的密匙
alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read() #app的公匙
alipay = AliPay(
appid=settings.ALIPAY_APPID, #就是一大串數字類似2016081903467
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 = settings.ALIPAY_DEBUG # 預設False 如果使用debug的除錯模式設定為True
)
# 4. 呼叫支付寶的方法生成order_string
# 如果你是 Python 3的使用者,使用預設的字串即可
subject = "測試訂單"
# 電腦網站支付,需要跳轉到https://openapi.alipay.com/gateway.do? + order_string
order_string = alipay.api_alipay_trade_page_pay(
out_trade_no=order_id,
total_amount=str(order.total_amount), # 這裡型別我們要由 decimal轉換為 str
subject=subject,
return_url="http://ip地址:埠號/pay_success.html",
notify_url=None # 可選, 不填則使用預設notify url
)
# 5. 拼接url,並且返回
url = settings.ALIPAY_URL + '?' + order_string
return Response({'alipay_url':url})
在配置檔案中編輯支付寶的配置資訊
ALIPAY_APPID = "2016091567523030"
ALIPAY_URL = "https://openapi.alipaydev.com/gateway.do"
ALIPAY_DEBUG = True
APP_PRIVATE_KEY_PATH = os.path.join(BASE_DIR, 'apps/pay/keys/app_private_key.pem')
ALIPAY_PUBLIC_KEY_PATH = os.path.join(BASE_DIR, 'apps/pay/keys/alipay_public_key.pem')
在pay/urls.py中設定url資訊
from django.conf.urls import url
from . import views
urlpatterns = [
#/pay/orders/(?P<order_id>)\d+/
url(r'^orders/(?P<order_id>\d+)/$',views.PaymentView.as_view(),name='pay'),
]
在專案名/urls.py中設定url資訊
urlpatterns = [
url(r'^pay/',include('pay.urls',namespace='pay')),
]
檢視的執行首先是從專案的url尋找路徑,然後再連線到應用pay的url裡面,當接受到前端的請求時候,便會執行相對應的檢視功能函式。
第三步
儲存支付結果
使用者支付成功後,支付寶會將使用者重定向到 pay_success.html,並攜帶支付結果資料
後端介面設計:
請求方式: PUT
路徑:/pay/status/?支付寶引數
請求引數: 在查詢字串中攜帶支付寶引數
返回資料:
trade_id 支付寶流水號 str
class PayStatusAPIView(APIView):
def put(self,request):
# 1. 建立alipay物件
app_private_key_string = open(settings.APP_PRIVATE_KEY_PATH).read()
alipay_public_key_string = open(settings.ALIPAY_PUBLIC_KEY_PATH).read()
alipay = AliPay(
appid=settings.ALIPAY_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=settings.ALIPAY_DEBUG # 預設False
)
# 2.驗證資料
data = request.query_params.dict()
# sign 不能參與簽名驗證
signature = data.pop("sign")
# verify確認是否成功
success = alipay.verify(data, signature)
if success:
# 3.驗證成功之後,可以從 data中獲取 支付寶的訂單id和 我們的訂單id
# 支付寶的交易id
trade_id = data.get('trade_no')
# 商家id
out_trade_no = data.get('out_trade_no')
#1. 把支付寶的訂單id和 我們的訂單id 儲存起來
Payment.objects.create(
order_id=out_trade_no,
trade_id=trade_id
)
# 2. 更新訂單的狀態
OrderInfo.objects.filter(order_id=out_trade_no).update(status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'])
#3. 返回 支付寶的訂單id
return Response({'trade_id':trade_id})