UmfHttp.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <?php
  2. namespace LdzfPay\UmfPayService;
  3. use LdzfPay\Api\Common\Logger;
  4. use LdzfPay\Api\Common\SignUtil;
  5. //服务端返回数据格式
  6. /*
  7. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  8. <html>
  9. <head>
  10. <META NAME="MobilePayPlatform" CONTENT="amount=1&amt_type=RMB&bank_payurl=weixin://wxpay/bizpayurl?pr=MfufsFp&mer_date=20170830&mer_id=60000100&mer_priv=&order_id=493585&platDate=20170830&ret_code=0000&ret_msg=操作成功&sign_type=RSA&trade_state=WAIT_BUYER_PAY&version=4.0&sign=tHgG2DiuFlKc2ldVA/0KJ9iZSU9rRiebN0ogVQAO0AHijd+4uVwjrrIPIF+D12yrFTenrnycrAfPussrRl1UxXioxOHDISSuL6GcXjgp3VlhOB7vbYO+t1NC61tUj03C9AFXT0tq5XEhrSTtx2vjsXEaVIty2YQUjbml6Ux4LqY=">
  11. </head>
  12. <body>
  13. </body>
  14. </html>
  15. */
  16. //http://www.3mu.me/php%E7%9A%84curl%E9%80%89%E9%A1%B9curlopt_ssl_verifypeer%E8%AF%A6%E8%A7%A3/
  17. class UmfHttp {
  18. /**
  19. * @param string $urlStr 向服务端发起GET请求的url字符串
  20. */
  21. public function httpGet($urlStr=""){
  22. $log = new Logger();
  23. $log->logInfo("[UMF SDK]本次请求的URL地址 ".$urlStr);
  24. $ch = curl_init();
  25. curl_setopt($ch, CURLOPT_URL, $urlStr);
  26. // 对认证证书来源的检查
  27. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  28. // 从证书中检查SSL加密算法是否存在
  29. //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  30. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  31. // 设置超时限制防止死循环
  32. curl_setopt($ch, CURLOPT_TIMEOUT,90);
  33. curl_setopt($ch, CURLOPT_HEADER, 0);
  34. $output = curl_exec($ch);
  35. if (curl_errno($ch)){
  36. $log->logInfo('[UMF SDK 子商户入网]网络请求失败,错误信息 = '.curl_error($ch));
  37. $log->logInfo("--------------------log end---------------------");
  38. die('[UMF SDK]网络请求失败,错误信息 = '.curl_error($ch));//捕抓异常
  39. }
  40. curl_close($ch);
  41. $log->logInfo("[UMF SDK]本次请求原始响应数据 ".$output);
  42. //对账直接返回
  43. $searchStr = strstr($urlStr,"service=download_settle_file");
  44. if(!empty($searchStr)){
  45. $log->logInfo("[UMF SDK]对账接口返回原始响应数据 ".$output);
  46. return $output;
  47. }
  48. // 解析HTML返回 CONTENT
  49. $contentStr = self::parseHTMLStr($output);
  50. $contentArr = explode('&',$contentStr);
  51. $response = array();
  52. for($i=0;$i<count($contentArr);$i++){
  53. $str = $contentArr[$i];
  54. $arr = explode('=',$str,2);
  55. $response[$arr[0]] = $arr[1];
  56. }
  57. $log->logInfo("[UMF SDK]本次请求处理后返回的响应数据 ".$log->logArrToStr($response));
  58. $log->logInfo("--------------------log end---------------------");
  59. return $response;
  60. }
  61. /**
  62. * @param string $urlStr 向服务端发起POST请求的url字符串
  63. * @param $map
  64. */
  65. public function httpPost($urlStr="", $map){
  66. // 启动一个CURL会话
  67. $ch = curl_init();
  68. // 要访问的地址
  69. curl_setopt($ch, CURLOPT_URL, $urlStr);
  70. // 对认证证书来源的检查
  71. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  72. // 从证书中检查SSL加密算法是否存在
  73. //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
  74. // 模拟用户使用的浏览器
  75. //curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
  76. // 发送一个常规的Post请求
  77. curl_setopt($ch, CURLOPT_POST, 1);
  78. // Post提交的数据包
  79. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($map->getInnerArr()));
  80. // 获取的信息以文件流的形式返回
  81. curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  82. // 使用自动跳转
  83. curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
  84. // 自动设置Referer
  85. curl_setopt($ch, CURLOPT_AUTOREFERER,1);
  86. curl_setopt($ch, CURLOPT_MAXREDIRS,4);
  87. curl_setopt($ch, CURLOPT_ENCODING,""); //必须解压缩防止乱码
  88. // 设置超时限制防止死循环
  89. curl_setopt($ch, CURLOPT_TIMEOUT,90);
  90. // 显示返回的Header区域内容
  91. curl_setopt($ch, CURLOPT_HEADER, 0);
  92. $output = curl_exec($ch);
  93. $log = new Logger();
  94. if (curl_errno($ch)){
  95. $log->logInfo('[UMF SDK 子商户入网]网络请求失败,错误信息 = '.curl_error($ch));
  96. $log->logInfo("--------------------log end---------------------");
  97. die('[UMF SDK]网络请求失败,错误信息 = '.curl_error($ch));//捕抓异常
  98. }
  99. curl_close($ch);
  100. $log->logInfo("[UMF SDK]本次请求原始响应数据 ".$output);
  101. //对账直接返回
  102. if($map->get("service") == "download_settle_file"){
  103. $log->logInfo("[UMF SDK]对账接口返回原始响应数据 ".$output);
  104. return $output;
  105. }
  106. // 解析HTML返回 CONTENT
  107. $contentStr = self::parseHTMLStr($output);
  108. $contentArr = explode('&',$contentStr);
  109. $response = array();
  110. for($i=0;$i<count($contentArr);$i++){
  111. $str = $contentArr[$i];
  112. $arr = explode('=',$str,2);
  113. if($arr[0]=='sign' || $arr[0]=='sign_type' || $arr[0]=='version'){
  114. continue;
  115. }
  116. $response[$arr[0]] = $arr[1];
  117. }
  118. $log->logInfo("[UMF SDK]本次请求处理后返回的响应数据 ".$log->logArrToStr($response));
  119. $log->logInfo("--------------------log end---------------------");
  120. return $response;
  121. }
  122. private function parseHTMLStr($htmlStr) {
  123. $content = '';
  124. if (!empty($htmlStr)) {
  125. // MobilePayPlatform
  126. preg_match('/<META\s+name="MobilePayPlatform"\s+content="([\w\W]*?)"/si', $htmlStr, $matches);
  127. if (!empty($matches[1])) {
  128. $content = $matches[1];
  129. }
  130. $resParamsArr = explode('&',$content);
  131. $plain = "";
  132. $sign = "";
  133. for($i=0;$i<count($resParamsArr);$i++){
  134. $str = $resParamsArr[$i];
  135. $arr = explode('=',$str,2);
  136. if($arr[0]=="sign_type"){
  137. continue;
  138. }
  139. if($arr[0]=="sign"){
  140. $sign = $arr[1];
  141. continue;
  142. }
  143. $plain .= $resParamsArr[$i] . "&";
  144. }
  145. $plain = substr($plain,0,strlen($plain)-1);
  146. // 字符串的编码 从UTF-8 转到GBK
  147. $plain=iconv("UTF-8", "GBK", $plain);
  148. $verifyRet = SignUtil::verify($plain,$sign);
  149. if($verifyRet == true){
  150. // echo "[UMF SDK] 平台响应数据验签成功";
  151. return $content;
  152. }else{
  153. die("[UMF SDK] 平台响应数据验证签名发生异常");
  154. }
  155. }
  156. }
  157. /************************************************************/
  158. //子商户入网部分
  159. public function httpRequestWithJson($urlStr="",$isPost=true,$jsonParam,$headers=array()){
  160. $log = new Logger();
  161. $log->logInfo("[UMF SDK 子商户入网]本次请求对应的URL " .$urlStr);
  162. $log->logInfo($isPost==true? "[UMF SDK 子商户入网]本次请求方式 post" : "[UMF SDK 子商户入网]本次请求方式 get");
  163. if(strpos($urlStr, "https://pay.soopay.net/spay_restPay/uploadChildFile") !== false){
  164. //上传文件接口 由于文件的二进制数据过大 不写入log
  165. }else{
  166. $log->logInfo("[UMF SDK 子商户入网]本次请求对应的json " .$jsonParam);
  167. }
  168. $ch = curl_init();
  169. curl_setopt($ch, CURLOPT_URL, $urlStr);
  170. curl_setopt($ch, CURLOPT_POST, $isPost);
  171. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  172. if($jsonParam != ""){
  173. curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonParam);
  174. }
  175. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  176. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  177. curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
  178. curl_setopt($ch, CURLOPT_TIMEOUT, 90);
  179. $response = curl_exec($ch);
  180. if (curl_errno($ch)){
  181. $log->logInfo('[UMF SDK 子商户入网]网络请求失败,错误信息 = '.curl_error($ch));
  182. $log->logInfo("--------------------log end---------------------");
  183. die('[UMF SDK 子商户入网]网络请求失败,错误信息 = '.curl_error($ch));//捕抓异常
  184. }
  185. curl_close($ch);
  186. // 验签
  187. $arr = explode('&',$response,2);
  188. if(count($arr) == 2){
  189. $resPlain = $arr[0];
  190. $resSign = $arr[1];
  191. $verifyRet = SignUtil::verify256($resPlain,$resSign);
  192. if($verifyRet == true){
  193. $log->logInfo("[UMF SDK 子商户入网]本次请求原始响应数据 ".$response);
  194. $log->logInfo("--------------------log end---------------------");
  195. return json_decode($resPlain);
  196. }else{
  197. die("[UMF SDK 子商户入网] 平台响应数据验证签名发生异常");
  198. }
  199. }
  200. elseif($urlStr=="https://pay.soopay.net/spay_restPay/oauth/authorize") { // 获取token接口没有sign字段
  201. return json_decode($response);
  202. }
  203. }
  204. }
  205. ?>