支付寶支付 (沙箱環境)
阿新 • • 發佈:2020-12-22
支付寶支付
-
正式環境:營業執照等資訊。
https://opendocs.alipay.com/open/270/105899
-
沙箱環境,模擬真實的環境。
https://opendocs.alipay.com/open/200/105311
1.申請開通沙箱環境
https://openhome.alipay.com/platform/appDaily.htm?tab=info
註冊成功之後會獲取兩個值:
- APPID,2016102400754054
- 支付寶閘道器
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/1034191. 安裝模組 2. 基於模組實現想要的功能
pip install alipay-sdk-python==3.3.398 # 不推薦
-
API,就是給你提供的一個URL
https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay1. 自己手動會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.常見報錯:釣魚網站
(測試時退出支付寶就好了)