微信支付獲取 prepay id 偶爾失敗問題【轉】


文章來源:http://www.liuhaihua.cn/archives/159332.html

微信支付會要求先從微信服務器獲取 prepay id (https://api.mch.weixin.qq.com/pay/unifiedorder)。我們開發完成后(語言是PHP,使用微信的支付SDK,請求時使用curl),在測試環境的機器上,基本沒有發現請求失敗的情況,上線后,卻發現經常出現錯誤,概率1/5甚至更高。開始沒有深究原因,采用重試的方式,不過發現,只要失敗了,重試也會失敗。

記錄下 curl 的錯誤是:errno:35, error: SSL Connect Error。

網上查相關資料,沒有找到解決方案。聯系微信技術支持,他們沒有任何建議,覺得是我們的問題,讓我們自己查。

在我們服務器上通過 tcpdump 抓包: tcpdump -i eth1 ip host 140.207.69.102 -w wxpay.cap ,對比成功和失敗的包(使用wireshark分析):

成功的數據包:

curl https 返回 errno 35(ssl connect error) 錯誤

失敗的數據包:

curl https 返回 errno 35(ssl connect error) 錯誤

可以看到,失敗的時候,TCP 3次握手后馬上進行4次揮手操作 沒有任何內容交互,而且 close 是客戶端(我們這邊)發起的。

推論:與remote服務端應該無關,還沒開始https內容部分的交換,應該是本地在進行某些工作的時候發現異常,close了連接(但程序如果讓我寫會考慮先本地工作結束后再connect,不清楚為什么先connect然后再獲取本地資源)。

可以通過 strace curl -X POST https://api.mch.weixin.qq.com/pay/unifiedorder 查看整個系統調用過程,是先 connect,然后從 系統本地etc目錄下加載一些CA相關文件。

也可以通過 curl -v -X POST https://api.mch.weixin.qq.com/pay/unifiedorder 查看相關信息。對於 PHP 中,可以設置:curl_setopt($ch, CURLOPT_VERBOSE, true) 。

失敗時是類似這樣的輸出:

* About to connect() to api.mch.weixin.qq.com port 443 (#0)

* Trying 140.207.69.102… connected

* Connected to api.mch.weixin.qq.com (140.207.69.102) port 443 (#0)

* Initializing NSS with certpath: sql:/etc/pki/nssdb

* CAfile: /etc/pki/tls/certs/ca-bundle.crt

CApath: none

* NSS error -5990

* Closing connection #0

* SSL connect error

curl: (35) SSL connect error

 

成功時輸出如下(省略了response):

* About to connect() to api.mch.weixin.qq.com port 443 (#0)

* Trying 140.207.69.102… connected

* Connected to api.mch.weixin.qq.com (140.207.69.102) port 443 (#0)

* Initializing NSS with certpath: sql:/etc/pki/nssdb

* CAfile: /etc/pki/tls/certs/ca-bundle.crt

CApath: none

* NSS: client certificate not found (nickname not specified)

* SSL connection using TLS_DHE_RSA_WITH_AES_256_CBC_SHA

* Server certificate:

* subject: CN=payapp.weixin.qq.com,OU=R&D,O=Tencent Technology (Shenzhen) Company Limited,L=shenzhen,ST=guangdong,C=CN

* start date: 4月 28 00:00:00 2015 GMT

* expire date: 4月 27 23:59:59 2016 GMT

* common name: payapp.weixin.qq.com

* issuer: CN=GeoTrust SSL CA – G2,O=GeoTrust Inc.,C=US

> POST /pay/unifiedorder HTTP/1.1

> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.16.2.3 Basic ECC zlib/1.2.3 libidn/1.18 libssh2/1.4.2

> Host: api.mch.weixin.qq.com

> Accept: */*

 

在網上找到了一個帖子: http://serverfault.com/questions/606135/curl-35-ssl-connect-error , 問題和我們遇到的一樣,雖然操作系統版本和NSS版本不一樣。按上面的提示,升級 nss(Mozilla Network Security Services 網絡安全服務): yum updatenss , 然后重啟 php,問題解決。

總結:

1、從現象:有些機器有問題,有些沒有問題;有些概率大,有些概率小;可大體上推斷,跟機器有關系,可能機器環境不一樣導致的;

2、抓包分析原因,進一步確認不是服務端(微信支付)的問題;

3、根據錯誤描述在網絡上尋求幫助;

4、學習 curl 相關選項的使用;strace 的使用;


免責聲明!

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



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