Django接入支付寶支付

Django接入支付寶支付

一、 申請沙盒賬號

  1. 進入沙盒環境

  2. 配置RSA2(SHA256)密鑰

    1. 生成後,需要把應用公鑰複製進去,獲取支付寶公鑰
    2. 保存好應用私鑰
    3. 主要好支付寶公鑰應用私鑰格式,以下爲舉例

    alipay_public_key.pem

    -----BEGIN PUBLIC KEY-----
    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAns4fKUa1T1dvJGJXPqESxsciOVdmC1MMvha3NIGrdYhWTXpS22klru9yPp2htIRE4TW5M2Hf/BZgsuVxj1xy/bdHGW1YyMAf0Xjcj4/UHomwC4yqrZrgAsJSrpP6RtSxPuYCfk0nNXhaJYznhm3HT7IYU7C3mdbOTdIQ/t8G4X2luQBHnZuY9kqaRf64TG+aH8121ZA5dsW+V77T3S9k0zfUFelVPHlvpsgCtPu0SGSjHSSpvLlKybZGWEnBviTa+jHtvkRYeztmjMapaYJY4F5INQaww4DzefVSkneHTYpb6KCZVNUChAmmpeUQKuObWPxGcPznF2zGwNwHptRTDwIDAQAB
    -----END PUBLIC KEY-----
    

    app_private_key.pem

    -----BEGIN RSA PRIVATE KEY-----
    MIIEpQIBAAKCAQEA6E+jr5AEmz5VHNpp4xkHhIOhA59bs5rc6glBTL34Uqj+rWxDL6EVle//LpKvuN3yU79avEBFYwSBP+BioWlq+vY1tDediGdRa060x4N3d/9/GvF8RNpZKZI+cwY9umRlm4NJbv+KZ4kHRRAbxOmL4xALvMQhgCmQwUgySL47oLXRuispzzGwqx5Eo77ei364/PxuQLwoIXxo4oWO0andXhSRNQCGTtwSPsfmdEsA11Xoa5y4uvshlIXpn9lE0BryXw9j6+k5hnPFoiXKmQJlIeYQEnYxSo2aycXJ7VyYSsGbdPFl4yNwigwIb0wnePw79Z4zV8/IQy3EylhF54ah7wIDAQABAoIBAQC1UtvvP1jpF0j1oWD+md2tR9RYcHzx/hEqNxkZ3jlBw5gtIpB6T5/6jP2/i0zO3aW0Smp2/y9pbu23PtudIxwWUDBwvuwduI7rU950z59jMTAzhoM5drgbY4OM4jUyFATe0iVyFtEfqOvcswsJskS2cSLILsn7L/ZFdqWQ87K051i+6ldp916m25+Xc+5TGKhfqFKmlgueRh4r4ZPn9v0pFCNTr2dH70LqZnrL9OMy3YLiw/K9U4vFh/P3HqNHPANvquh155/2zemGiGPZHJ5r1uaeXVxvIAEXpWL21BskpW546RObr0Do7Dmz3B0cZ6tDPsqn0mUn8kqWJSVr+htRAoGBAPoyfKqYwf2BjwBQjiqaZemFM7fbgHO1Kgf+2Bq2AbLfzM1SwUJpCA/Qlepe+rL1QvUJJJhCCrbXNS4tBgItww+cYC8z2+NdufXCtwlPOQ5D2EbiXPIUS8Jzea35lj10DoQppCkcMWp68fRAYdeyJ9Xz6iVs3SVTgELDvpk5Vl1nAoGBAO2y9Lb45+rIQkn60k6vBr8Z7zTOk5HFDK/xItt9f0r3vs6zGF6kAAFw9K/8ePNlcjHD+X46I9qKsLU1GwYwdlmzhhUhgith9sgEsoAUs05yh04eW4D1ucyRa09NpZ/7vua3xL6Y9XlPFHXnDNvFyOoiJJFyCBOF279o8mh8ubo5AoGABaKFdEIkfFUip1spGISJrwy08XscFX8LB0sSCuf2edTYg/dNKvW6nMCR38lr1AP6EhK2pEc4fo2yQOv6qqnlLsDS2b1NQn2l5ocQIEGMg2m7wTzv4vPaEPMQ1n48h/3JJejaLaLY6hECygF5MqZsh0ELEPS2tlR/GwHVlRXZgBkCgYEAziuGbp3+KnqAZMKVX4IYi/DmthrnjGwp0QGKhm6X1mKEsaxN2ujMyHM9CNgn4JWBMwEUihPLvWbGVqY1Rm0KektoZTOnQBG8h0jruoQ58jUMfwl9vKFmArWvKh3jJpyovF1w3RC2+f1JdepuEMHAvrPWnAEYWDamn6Nbfp2QSqECgYEA3Y8t+P1/zFUMZHr1FlHMXCk6UG96MUzE3KOFkFGqTfeFVXxwAVvHGhpJXGMO2um/oy+ASDVolxaHb5V6ptOn0CosXvgmipjM5n4pd2kKAhnWL0COx9ktcle4XsVvUgtxd8XbrFJuI+BpB9mKkmRlZCK5yr5y99npD2dJOig9Oh8=
    -----END RSA PRIVATE KEY-----
    
  3. 沙盒環境中配置授權回調地址

  4. 下載沙盒錢包,賬號和密碼都可在沙盒賬號找到

二、 編寫代碼

首先需要執行命令pip install python-alipay-sdk

  1. 生成支付寶支付鏈接方法

    import os
    import uuid
    from alipay import AliPay
    from django.http import JsonResponse
    from django.shortcuts import render
    from django.views.generic import View
    
    class OrderPayView(View):
    	def post(self,request):
    	    #接收參數
    	    order_id = str(uuid.uuid1())
    	    merchant_private_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/app_private_key.pem")).read()
    	    alipay_public_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/alipay_public_key.pem")).read()
    	    # print(x,'eeeee')
    	    #業務處理:使用Python sdk調用支付寶的支付接口
    	    alipay = AliPay(
    	        appid="2016102200736331",   #APPID
    	        app_notify_url=None,  # 默認回調url,可以傳也可以不傳
    	        app_private_key_string=merchant_private_key_path, #私鑰的路徑
    	        alipay_public_key_string=alipay_public_key_path,#支付寶公鑰的路徑
    	        sign_type="RSA2",  # RSA 或者 RSA2,簽名的算法
    	        debug = True  # 默認False,沙箱環境改成True
    	    )
    	    #藉助alipay對象,向支付寶發起支付請求
    	    #電腦網站支付,需要跳轉到https://openapi.alipaydev.com/gateway.do?+order_string
    	    total_pay = 5 #訂單總金額
    	    order_string = alipay.api_alipay_trade_page_pay(
    	        out_trade_no=order_id,  #訂單id
    	        total_amount=str(total_pay), #支付寶總金額
    	        subject="測試支付", #訂單標題
    	        return_url="http://127.0.0.1:8000/success/",
    	        notify_url=None
    	    )
    	    #返回應答
    	    pay_url = "https://openapi.alipaydev.com/gateway.do?"+order_string
    	    return JsonResponse({"pay_url":pay_url})
    

    注意事項

    1. 問題:私鑰會出現不支持的情況,解決方法:使用open讀取值再傳送即可。
    2. 問題:return_url方法爲get請求回調時間,回答:當支付成功後,並且按照正常操作等待支付寶調用纔會進行調用,即出現支付完成時不會快速點擊關閉
    3. 問題:notify_url方法爲post請求回調時間,回答:當支付成功後,會直接調用這個接口。
  2. 回調函數方法(同步回調和異步回調)

    # 處理支付寶回調
    class AlipayView(APIView):
        def get(self, request):
            """
            處理支付寶的return_url返回
            """
            processed_dict = {}
            # 1. 獲取GET中參數
            for key, value in request.GET.items():
                processed_dict[key] = value
            # 2. 取出sign
            sign = processed_dict.pop("sign", None)
            merchant_private_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/app_private_key.pem")).read()
            alipay_public_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/alipay_public_key.pem")).read()
            # 3. 生成ALipay對象
            alipay = AliPay(
                appid="2016102200736331", #APPID
    	        app_notify_url=None, # 默認回調url,可以傳也可以不傳
    	        app_private_key_string=merchant_private_key_path, # 應用私鑰
    	        alipay_public_key_string=alipay_public_key_path, # 支付寶公鑰
    	        sign_type="RSA2", # RSA 或者 RSA2,簽名的算法
    	        debug = True # 默認False,沙箱環境改成True
            )
    
            verify_re = alipay.verify(processed_dict, sign)
    
            # 這裏可以不做操作。因爲不管發不發return url。notify url都會修改訂單狀態。
            if verify_re is True:
                order_sn = processed_dict.get('out_trade_no', None) # 商戶訂單號
                trade_no = processed_dict.get('trade_no', None) # 支付寶交易號
                return render(request,'pay_success.html')
            else:
                return render(request,'demo.html')
    
        def post(self, request):
            """
            處理支付寶的notify_url
            """
            # 1. 先將sign剔除掉
            processed_dict = {}
            for key, value in request.POST.items():
                processed_dict[key] = value
    
            sign = processed_dict.pop("sign", None)
    
            merchant_private_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/app_private_key.pem")).read()
            alipay_public_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/alipay_public_key.pem")).read()
            # 2. 生成ALipay對象
            alipay = AliPay(
                appid="2016102200736331",   #APPID
    	        app_notify_url=None,  # 默認回調url,可以傳也可以不傳
    	        app_private_key_string=merchant_private_key_path, #私鑰的路徑
    	        alipay_public_key_string=alipay_public_key_path,#支付寶公鑰的路徑
    	        sign_type="RSA2",  # RSA 或者 RSA2,簽名的算法
    	        debug = True  # 默認False,沙箱環境改成True
            )
    
            # 3. 進行驗籤,確保這是支付寶給我們的
            verify_re = alipay.verify(processed_dict, sign)
    
            # 如果驗籤成功
            if verify_re is True:
                order_sn = processed_dict.get('out_trade_no', None) # 商戶訂單號
                trade_no = processed_dict.get('trade_no', None) # 支付寶交易號
                trade_status = processed_dict.get('trade_status', None) # 交易狀態
                # 將success返回給支付寶,支付寶就不會一直不停的繼續發消息了。
                return Response("success")
    
  3. 查詢支付狀態

    # 查詢支付狀態
    class CheckPayView(View):
        def post(self,request):
            # 初始化
            merchant_private_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/app_private_key.pem")).read()
            alipay_public_key_path = open(os.path.join("D:/gitee/Alipy_WX/payments/keys/alipay_public_key.pem")).read()
            # 業務處理:使用Python sdk調用支付寶的支付接口
            alipay = AliPay(
                appid="2016102200736331", # APPID
                app_notify_url=None, # 默認回調url,可以傳也可以不傳
                app_private_key_string=merchant_private_key_path, # 私鑰的路徑
                alipay_public_key_string=alipay_public_key_path, # 支付寶公鑰的路徑
                sign_type="RSA2", # RSA 或者 RSA2,簽名的算法
                debug = True # 默認False,沙箱環境改成True
            )
            order_id = str(uuid.uuid1()) # 前端傳入,目前是隨機生成
            while True:
                response = alipay.api_alipay_trade_query(out_trade_no=order_id)
                # out_trade_no和trade_no兩個至少有一個存在
                code = response.get("code")
                # 如果返回碼爲10000和交易狀態爲交易支付成功
                if code == "10000" and response.get("trade_status") == "TRADE_SUCCESS":
                    # 獲取支付寶交易號
                    trade_no = response.get("trade_no")
                    return JsonResponse({"status":"ok","message":"支付成功"})
                # 返回碼爲40004 或 交易狀態爲等待買家付款
                elif code == "40004" or (response.get("trade_status") == "WAIT_BUYER_PAY"):
                    # 等待買家付款
                    import time
                    time.sleep(5)
                    continue
                else:
                    # 支付出錯
                    return JsonResponse({"status":"error","message":"支付失敗"})
    

三、 聲明

本博客僅供參考,如商用出現不可控問題,概不負責

源碼: Django-Extended-App,該倉庫裏Alipy_WX文件夾

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章