Django中對接第三方支付(支付寶)實現支付的流程


1. 業務邏輯
准備

  1. 使用沙箱提供的商家環境

    沙箱環境:是支付寶提供給開發者的模擬支付的環境

    沙箱應用: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.m

    API列表:https://docs.open.alipay.com/270/105900/
  2.. 生成密鑰對
  3. 將公鑰加到商品環境中
  4. 將Alipay提供的公鑰加入項目中
    支付功能
  5. 根據order_id查詢訂單對象
  6. 創建alipay對象
  7. 調用方法,生成url
  8. 返回url
    保存支付狀態
  9. 根據返回的url請求支付寶
  10. 支付成功后返回商家回調頁面--------->會傳回很多Alipay傳回來的參數,很多明文,防止別人攻擊
  11. 返回商家的同時請求后台服務器------>發送這些參數給后台
  12. 接收參數並且驗證,成功則創建訂單支付對象返回訂單號,否則提示支付失敗

2.安裝包

pip install python-alipay-sdk --upgrade

3.新建一個payments的app應用

python ../../manage.py startapp payments

4.定義一個模型類,繼承自BaseModel(創建時間與修改時間)

 class Payment(BaseModel):
        """
        支付信息
        """
        order = models.ForeignKey(
            OrderInfo, on_delete=models.CASCADE, verbose_name='訂單')
        trade_id = models.CharField(
            max_length=100, verbose_name="支付流水號")

    class Meta:
        db_table = 'tb_payment'
        verbose_name = '支付信息'
        verbose_name_plural = verbose_name

5.配置密鑰

  5.1.登錄沙箱

    在payments應用中新建keys目錄,用來保存秘鑰文件。

     將應用私鑰文件app_private_key.pem復制到payment/keys目錄下。

  5.1.1生成應用的私鑰和公鑰 

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

  5.2 保存應用私鑰文件

  5.3 查看公鑰

cat app_publict_key.pem
# 將公鑰內容復制給支付寶沙箱的<應用私鑰>,得到支付寶的<支付寶公鑰>

  5.4 保存支付寶公鑰

  在payments/keys目錄下新建alipay_public_key.pem文件,用於保存支付寶的公鑰文件。

  將支付寶的公鑰內容復制到alipay_public_key.pem文件中

6.配置路由

GET /orders/(?P<order_id>\d+)/payment/

7.在配置文件中配置ailipay的信息

 # 支付寶支付的配置
ALIPAY_APPID = 'xxxxxxxxxxxxx'
ALIPAY_PRIVATE_KEY_PATH = os.path.join(BASE_DIR, 'apps/payments/alipay/app_private_key.pem')
ALIPAY_PUBLIC_KEY_PATH = os.path.join(BASE_DIR, 'apps/payments/alipay/alipay_public_key.pem')
ALIPAY_DEBUG = True
ALIPAY_SUBJECT = '智學客-訂單支付'
ALIPAY_RETURN_URL = 'http://www.xxx.com/pay_success.html'
ALIPAY_GATE = 'https://openapi.alipaydev.com/gateway.do?'

8.定義視圖

兩個參數: 

      order_id: 訂單編號

      alipay_uel: 支付寶支付鏈接

代碼如下:

 class AliPayURLView(APIView):
    def get(self, request, order_id):
        # 1.根據order_id查詢訂單對象
        try:
            order_obj = OrderInfo.objects.get(pk=order_id)
        except:
            raise Exception("訂單號無效")

        # 2.創建alipay對象
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,
            app_private_key_path=settings.ALIPAY_PRIVATE_KEY_PATH,
            alipay_public_key_path=settings.ALIPAY_PUBLIC_KEY_PATH,
            debug=settings.ALIPAY_DEBUG
        )

        # 3.調用方法,生成url
        # 電腦網站支付,需要跳轉到https://openapi.alipay.com/gateway.do? + order_string
        order_string = alipay.api_alipay_trade_page_pay(
            subject=settings.ALIPAY_SUBJECT,
            out_trade_no=order_id,  # 訂單編號
            total_amount=str(order_obj.total_amount),  # 支付總金額,類型為Decimal(),不支持序列化,需要強轉成str
            return_url=settings.ALIPAY_RETURN_URL  # 支付成功后的回調地址

        )
        # 4.返回url
        return Response({"alipay_url": settings.ALIPAY_GATE + order_string})

  8.1 在payments/urls.py中定義路由規則 

 url('^orders/(?P<order_id>\d+)/payment/$',views.PaymentView.as_view()),

9.保存支付狀態

請求方式:PUT /payment/status/?支付寶參數

參數:trade_id:支付寶流水賬號

代碼實現:

class OrderStatusView(APIView):
    """驗證用戶是否登錄成功"""

    def put(self, request):
        # 1.接收支付寶返回的數據
        data = request.query_params.dict()

        # 2.驗證是否支付成功
        # 2.1刪除簽名,不參與驗證
        signature = data.pop("sign")

        # 2.2 創建alipay對象
        alipay = AliPay(
            appid=settings.ALIPAY_APPID,
            app_notify_url=None,
            app_private_key_path=settings.ALIPAY_PRIVATE_KEY_PATH,
            alipay_public_key_path=settings.ALIPAY_PUBLIC_KEY_PATH,
            debug=settings.ALIPAY_DEBUG
        )

        # 2.3 調用verify(字典,簽名)
        success = alipay.verify(data, signature)
        if success:
            # 支付成功
            '''
            {
                'total_amount': '11388.00', 支付金額
                'auth_app_id': '2016082100304973', 應用編號
                'method': 'alipay.trade.page.pay.return',
                'trade_no': '2018110722001420410500545016',流水號
                'timestamp': '2018-11-07 16:59:20',時間
                'app_id': '2016082100304973',應用編號
               'out_trade_no': '20181107160224000000001',商城的訂單編號
               'charset': 'utf-8',編碼
               'seller_id': '2088102172415825',商家編號
               'version': '1.0'版本
            }
            '''
            # 1 獲取訂單號
            order_id = data["out_trade_no"]
            # 2 修改訂單狀態
            try:
                order_obj = OrderInfo.objects.get(pk=order_id)
            except:
                raise Exception("訂單號無效")
            order_obj.status = 2
            order_obj.save()

            # 3.創建訂單支付對象
            trade_no = data.get('trade_no')  # 獲取流水號
            Payment.objects.create(
                order_id=order_id,
                trade_no=trade_no
            )

            # 4.響應
            return Response({"trade_id": trade_no})
        else:
            raise Exception("支付失敗")

  9.1 定義路由規則 

   url('^payment/status/$',views.PaymentStatusView.as_view()),

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM