1. 程式人生 > 實用技巧 >支付寶支付 (沙箱環境)

支付寶支付 (沙箱環境)

支付寶支付

  • 正式環境:營業執照等資訊。

    https://opendocs.alipay.com/open/270/105899
    
  • 沙箱環境,模擬真實的環境。

    https://opendocs.alipay.com/open/200/105311
    

1.申請開通沙箱環境

https://openhome.alipay.com/platform/appDaily.htm?tab=info

註冊成功之後會獲取兩個值:

2.生成祕鑰

祕鑰用於以後對URL中新增的引數進行加密和校驗。

2.1 下載祕鑰生成器

生成一對祕鑰:

  • 應用公鑰
  • 應用私鑰

2.2 上傳應用公鑰並獲得支付寶公鑰

本次操作中共獲取到三個祕鑰:

  • 應用公鑰
  • 應用私鑰,對以後URL中傳入的資料進行簽名加密用。
  • 支付寶公鑰(通過應用公鑰生成),在頁面支付成功後跳轉回來時候,對支付寶給我們傳的值進行校驗。

3.賬戶資訊和測試APP

  • 買家資訊

    買家賬號[email protected]
    登入密碼111111
    支付密碼111111
    使用者名稱稱沙箱環境
    證件型別身份證(IDENTITY_CARD)
    證件號碼939581196106136440
    賬戶餘額
    99999.00充值取現
    
  • 商家資訊

    商家賬號[email protected]
    商戶UID2088102180940005
    登入密碼111111
    賬戶餘額
    0.00充值取現
    
  • APP

4.兩種支援

  • SDK,寫好一個Python模組
    https://opendocs.alipay.com/open/54/103419

    1. 安裝模組
    2. 基於模組實現想要的功能
    
    pip install alipay-sdk-python==3.3.398
    
    # 不推薦
    
  • API,就是給你提供的一個URL
    https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay

    1. 自己手動會URL進行處理和加密
    
    讓你跳轉到這個地址:【閘道器?參與】 組成
    閘道器 = https://openapi.alipaydev.com/gateway.do
    引數 = {
    	app_id:"2016102400754054",
    	method:"alipay.trade.page.pay"
    	format:"JSON",
    	return_url:"支付成功之後跳轉GET到的那個頁面地址",
    	notify_url:"同時偷偷想這個地址傳送一個POST請求",
    	charset:"utf-8",
    	sign_type:"RSA2",
    	sign:"簽名",
    	timestamp:"2014-07-24 03:07:50",
    	version:'1.0',
    	biz_content:{
    		out_trade_no:"訂單號",
    		product_code:"FAST_INSTANT_TRADE_PAY",
    		total_amount:11.68,
    		subject:"訂單標題"
    	}
    }
    
    如果支付成功之後,伺服器宕機,如何處理?
    偷偷向notify_url發請求,說支付成功了,你更改下狀態。
    	伺服器宕機,支付寶訪問不到,則會在24小時以內傳送:支付寶伺服器會不斷重發通知,直到超過24小時22分鐘。一般情況下,25小時以內完成8次通知(通知的間隔頻率一般是:4m,10m,10m,1h,2h,6h,15h)
    	我的網站接收到支付寶請求之後,返回資料不正確,同上。
    	返回一個字串 "success"
    	
    https://opendocs.alipay.com/open/270/105902/
    
    支付寶簽名的過程:對引數進行處理,處理完之後再讓他和閘道器拼接起來。 
    閘道器 = https://openapi.alipaydev.com/gateway.do
    params = {
    	app_id:"2016102400754054",
    	method:"alipay.trade.page.pay"
    	format:"JSON",
    	return_url:"支付成功之後跳轉GET到的那個頁面地址",
    	notify_url:"同時偷偷想這個地址傳送一個POST請求",
    	charset:"utf-8",
    	sign_type:"RSA2",
    	sign:"簽名",
    	timestamp:"2014-07-24 03:07:50",
    	version:'1.0',
    	biz_content:{
    		out_trade_no:"訂單號",
    		product_code:"FAST_INSTANT_TRADE_PAY",
    		total_amount:11.68,
    		subject:"訂單標題"
    	}
    }
    
    1. 將引數中 空、檔案、位元組、sign 踢出。 
       params.pop(sign)
    
    2. 排序,對引數中所有的key進行從小大大排序 sort(params)
       並按照第一個字元的鍵值ASCII碼遞增排序(字母升序排序),如果遇到相同字元則按照第二個字元的鍵值ASCII碼遞增排序,以此類推。
    
    3. 將排序後的引數與其對應值,組合成“引數=引數值”的格式,並且把這些引數用&字元連線起來,此時生成的字串為待簽名字串。
       待簽名的字串 = "app_id=2016102400754054&method=alipay.trade.page.pay"
    
       注意:1.有字典應該轉換為字串; 2.字串中間不能有空格。
       json.dumps(info,separators=(",",":"))
    4.使用各自語言對應的SHA256WithRSA簽名函式並利用商戶(應用)私鑰對待簽名字串進行簽名,並進行Base64編碼。
       result = 使用 SHA256WithRSA 函式和私鑰對簽名字串進行簽名
       簽名 = 在對result進行Base64編碼
    
       把簽名再新增到會params字典中 params[sign] = 簽名
    	注意:base64編碼之後之後,內部不能有換行符 簽名.replace("\n","")
    	
    5.再講所有的引數拼接起來。
    	
    	注意:在拼接URL時候不能出現 ;,(等字元, 提前將特殊字元轉換URL轉義的字元。
    		from urllib.parse import quote_plus
    
    https://opendocs.alipay.com/open/291/105974
    https://opendocs.alipay.com/open/291/106118
    
    # pip3 install pycrypto
    # 如果是 pycryptodom.xxxx.whl  下載到本地,pip install pycryptodom.xxxx.whl
    
    # 構造字典
    params = {
        'app_id': "2016102400754054",
        'method': 'alipay.trade.page.pay',
        'format': 'JSON',
        'return_url': "http://127.0.0.1:8001/pay/notify/",
        'notify_url': "http://127.0.0.1:8001/pay/notify/",
        'charset': 'utf-8',
        'sign_type': 'RSA2',
        'timestamp': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        'version': '1.0',
        'biz_content': json.dumps({
            'out_trade_no': order_id,
            'product_code': 'FAST_INSTANT_TRADE_PAY',
            'total_amount': 1.11,
            'subject': "x1"
        }, separators=(',', ':'))
    }
    
    # 獲取待簽名的字串
    unsigned_string = "&".join(["{0}={1}".format(k, params[k]) for k in sorted(params)])
    print(unsigned_string)
    
    # 簽名 SHA256WithRSA(對應sign_type為RSA2)
    from Crypto.PublicKey import RSA
    from Crypto.Signature import PKCS1_v1_5
    from Crypto.Hash import SHA256
    from base64 import decodebytes, encodebytes
    
    # SHA256WithRSA + 應用私鑰 對待簽名的字串 進行簽名
    private_key = RSA.importKey(open("files/skd/應用私鑰2048.txt").read())
    signer = PKCS1_v1_5.new(private_key)
    signature = signer.sign(SHA256.new(unsigned_string.encode('utf-8')))
    
    # 對簽名之後的執行進行base64 編碼,轉換為字串
    sign_string = encodebytes(signature).decode("utf8").replace('\n', '')
    
    # 把生成的簽名賦值給sign引數,拼接到請求引數中。
    
    from urllib.parse import quote_plus
    result = "&".join(["{0}={1}".format(k, quote_plus(params[k])) for k in sorted(params)])
    result = result + "&sign=" + quote_plus(sign_string)
    
    gateway = "https://openapi.alipaydev.com/gateway.do"
    pay_url = "{}?{}".format(gateway, result)
    
    

5.常見報錯:祕鑰

祕鑰格式問題。

6.常見報錯:釣魚網站

(測試時退出支付寶就好了)