這幾天在對接微信的退款接口,其中涉及到幾個麻煩的地方,坐下記錄,不是從頭開始的對接,隻是記錄難點的處理。
一、微信申請退款接口需要使用到證書,在curl請求中關于證書位址的填寫
之前寫的是相對位址,不可行,後來換成了絕對位址就成功的請求到了,因為我這邊是用的是TP5.1架構,由于項目架構的原因,證書放置在第三方支付子產品的檔案夾下,是以我這邊使用
1 //curl請求
2 public function curl($xmlData,$url, $cert = false){3 //第一種發送方式,也是推薦的方式:
4 $header[] = "Content-type: text/xml"; //定義content-type為xml,注意是數組
5 $ch = curl_init ($url);6 curl_setopt($ch, CURLOPT_URL, $url);7 curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);8 curl_setopt($ch, CURLOPT_HTTPHEADER,$header);9 curl_setopt($ch, CURLOPT_POST, 1);10 curl_setopt($ch,CURLOPT_POSTFIELDS, $xmlData);11 if ($cert) {12 //設定證書13 //使用證書:cert 與 key 分别屬于兩個.pem檔案14 //證書檔案請放入伺服器的非web目錄下
15
16 $sslCertPath = Env::get('app_path').'子產品/檔案夾名/apiclient_cert.pem';17 $sslKeyPath = Env::get('app_path').'子產品/檔案夾名/apiclient_key.pem';18 curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');19 curl_setopt($ch, CURLOPT_SSLCERT, $sslCertPath);20 curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');21 curl_setopt($ch, CURLOPT_SSLKEY, $sslKeyPath);22
23 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);24 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //嚴格校驗
25 }26 $response = curl_exec($ch);27 curl_close($ch);28 return $response;29 }
之前參照網上說的,證書檔案必須放在cert檔案夾下之類的,其實不對,并無影響。
二、接收微信退款通知如何解密
首先我也是在網上搜尋了,然後發現大部分是mcrypt,然而PHP7.0以上并不支援,是以對我無用,其實就老老實實根據微信的文檔就使用openssl就可以了。
先看微信的解密說明
解密步驟如下:
(1)對加密串A做base64解碼,得到加密串B
(2)對商戶key做md5,得到32位小寫key* ( key設定路徑:微信商戶平台(pay.weixin.qq.com)-->賬戶設定-->API安全-->密鑰設定 )
(3)用key*對加密串B做AES-256-ECB解密(PKCS7Padding)
網上很多不知道為何使用了 "aes-256-cbc" ,使用這個參數中需要設定向量iv,微信解密沒有說這種解密,不知為何網上很多人用這個,搞得很複雜。
下面貼上我的代碼
1 //退款的加密資訊
2 $req_info = $refund_notify_info['req_info'];3
4 $api_key = config('api_key');5 //對加密資訊進行解密,需要用到商戶秘鑰
6 $req_info_xml = openssl_decrypt(base64_decode($req_info), 'aes-256-ecb', md5($api_key),OPENSSL_RAW_DATA);7 $req_info_data = $wechat->xmlToArray($req_info_xml);
我當時測試的時候解密直接輸出是 String"767" ' ' ,我以為是我的解密不對,後來才發現不能直接var_dump($req_info_xml),轉化為數組後,發現是正确的。
希望看到這的小夥伴可以少走這個彎路。