這幾天在對接微信的退款接口,其中涉及到幾個麻煩的地方,坐下記錄,不是從頭開始的對接,只是記錄難點的處理。
一、微信申請退款接口需要使用到證書,在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),轉化為數組后,發現是正確的。
希望看到這的小伙伴可以少走這個彎路。