已經不是第一次做支付介面開發了,每次做支付介面開發其實都會遇到一些麻煩。最主要的地方還是在驗簽(驗證簽名)部分。
驗簽的作用是判別支付結果的回調(同步返回,get方式)或者通知(非同步post方式)是否真的是由支付寶的伺服器發出的。
在這裡有2個目的:1是記錄一下這個通知的返回內容,2是列舉一下目前支付寶介面開發過程中遇到的,可能影響驗簽通過的原因。
1.同步回調(get方式)返回的資料
以php為例,var_dump($_GET)得到的數組如下:
array 'body' => string '使用者賬戶儲值' (length=18) 'is_success' => string 'T' (length=1) 'notify_id' => string '一長串balabalbabab的東西' (length=70) 'notify_time' => string '2016-12-26 16:37:47' (length=19) 'notify_type' => string 'trade_status_sync' (length=17) 'out_trade_no' => string '20161226163712111782' (length=20) 'payment_type' => string '1' (length=1) 'seller_id' => string '2088521242126500' (length=16) 'service' => string 'alipay.wap.create.direct.pay.by.user' (length=36) 'subject' => string '使用者賬戶儲值' (length=18) 'total_fee' => string '0.01' (length=4) 'trade_no' => string '2016122621001004720297207882' (length=28) 'trade_status' => string 'TRADE_SUCCESS' (length=13) 'sign' => string '簽名' (length=172) 'sign_type' => string 'RSA' (length=3)
同步通知驗簽不能通過的原因:
1.產生密鑰的方式不對,上傳密鑰的方式也不對,這點請按照開發文檔的說明仔細檢查。
2.返回的參數不乾淨,比如thinkphp的$_GET數組實際上會在數組結尾加上一個'_URL_'=>array(0=>'分組',1=>'控制器',2=>'方法')的數組項,所以在驗簽之前,要先unset($_GET['_URL_'])。
非同步介面驗簽不通過的原因:
1.密鑰產生和上傳方式不對,請按照文檔仔細檢查。
2.防火牆原因,攔截了支付寶伺服器的post請求,導致無法收到非同步結果
3.非同步結果的調試務必放到公網可以訪問的伺服器上進行調試,否則你是無法收到非同步通知的,原因自己去想。
4.你的開發過程中,傳遞過去的非同步通知url不能帶有類似pay.php?id=1這樣的參數,必須是到一個最終的處理指令碼的地址,比如:http://www.xyservice.com/pay/ 或者 http://www.xyservice.com/pay.php
5.確保你的非同步通知路徑是可以訪問的,如果訪問不了,比如你的介面可能有許可權驗證,但支付寶介面直接post過來資料你認為沒有登入,程式直接拒絕了而且302跳轉到登入頁面去了,或者有些主機商攔截了支付寶的post請求。
還有一點,有人說cacert.pem的路徑不對也會影響驗簽,其實筆者在調試的時候因為需要刻意注釋掉了cacert.pem的路徑,結果在demo示範的時候,demo內容已經換成了筆者的pid和密鑰資訊之後,居然可以驗簽通過,所以就目前來看,這個ca認證的路徑問題可能不是影響支付寶介面驗簽不通過的主要原因,當然,即便是這樣您在開發過程中也要確保ca認證的路徑正確,萬一哪天介面開始驗證ca認證了呢。
這是目前筆者在實際的開發過程中遇到的情況,記錄下來,一是給遇到同樣麻煩的朋友一個參考,二是給自己做個筆記。