1. 程式人生 > >支付寶第三方支付(Django框架)

支付寶第三方支付(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
快速接入:

https://docs.open.alipay.com/270/105899/
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

執行完之後會在你的檔案下面出現下面兩個(密匙和公鑰):
在這裡11片描述
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

繼續編寫檢視函式views.py

 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})