PayUtils.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. /**
  3. * 支付处理类
  4. * User: Ocean
  5. * Date: 2018/4/23
  6. * Time: 10:29
  7. */
  8. namespace common\pay\sand;
  9. class PayUtils
  10. {
  11. /**
  12. *获取公钥
  13. *@param [$path]
  14. *@return [mixed]
  15. *@throws [\Exception]
  16. */
  17. function loadX509Cert($path){
  18. try{
  19. $file = file_get_contents($path);
  20. if(!$file){
  21. throw new \Exception('loadx509Cert::file_get_contents ERROR');
  22. }
  23. $cert = chunk_split(base64_encode($file),64,"\n");
  24. $cert = "-----BEGIN CERTIFICATE-----\n".$cert."-----END CERTIFICATE-----\n";
  25. $res = openssl_pkey_get_public($cert);
  26. $detail = openssl_pkey_get_details($res);
  27. openssl_free_key($res);
  28. if(!$detail){
  29. throw new \Exception('loadX509Cert::openssl_pkey_get_details ERROR');
  30. }
  31. return $detail['key'];
  32. } catch(\Exception $e){
  33. throw $e;
  34. }
  35. }
  36. /**
  37. * 获取私钥
  38. * @param [$path]
  39. * @param [$pwd]
  40. * @return [mixed]
  41. * @throws [\Exception]
  42. */
  43. function loadPk12Cert($path,$pwd){
  44. try{
  45. $file = file_get_contents($path);
  46. if(!$file){
  47. throw new \Exception('loadPk12Cert::file_get_contents');
  48. }
  49. if(!openssl_pkcs12_read($file,$cert,$pwd)){
  50. throw new \Exception('loadPk12Cert::openssl_pkcs12_read ERROR');
  51. }
  52. return $cert['pkey'];
  53. } catch(\Exception $e){
  54. throw $e;
  55. }
  56. }
  57. /**
  58. * 私钥签名
  59. * @param [$plainText]
  60. * @param [$path]
  61. * @return [string]
  62. * @throws [\Exception]
  63. */
  64. function sign($plainText,$path){
  65. $plainText = json_encode($plainText);
  66. try{
  67. $resource = openssl_pkey_get_private($path);
  68. $result = openssl_sign($plainText,$sign,$resource);
  69. openssl_free_key($resource);
  70. if(!$result){
  71. throw new \Exception('签名出错'.$plainText);
  72. }
  73. return base64_encode($sign);
  74. } catch (\Exception $e){
  75. throw $e;
  76. }
  77. }
  78. /**
  79. * 发送post请求
  80. * @param string $url 请求地址
  81. * @param array $post_data post键值对数据
  82. * @return string
  83. */
  84. function send_post($url, $post_data) {
  85. $postdata = http_build_query($post_data);
  86. $options = array(
  87. 'http' => array(
  88. 'method' => 'POST',
  89. 'header' => 'Content-type:application/x-www-form-urlencoded',
  90. 'content' => $postdata,
  91. 'timeout' => 15 * 60 // 超时时间(单位:s)
  92. )
  93. );
  94. $context = stream_context_create($options);
  95. $result = file_get_contents($url, false, $context);
  96. return $result;
  97. }
  98. /**
  99. * PHP发送Json对象数据
  100. *
  101. * @param $url 请求url
  102. * @param $jsonStr 发送的json字符串
  103. * @return string
  104. */
  105. function http_post_json($url, $param)
  106. {
  107. if (empty($url) || empty($param)) {
  108. return false;
  109. }
  110. $param = http_build_query($param);
  111. try {
  112. $ch = curl_init();//初始化curl
  113. curl_setopt($ch, CURLOPT_URL, $url);
  114. curl_setopt($ch, CURLOPT_POST, 1);
  115. curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
  116. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
  117. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  118. //正式环境时解开注释
  119. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
  120. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);
  121. $data = curl_exec($ch);//运行curl
  122. curl_close($ch);
  123. if (!$data) {
  124. throw new \Exception('请求出错');
  125. }
  126. return $data;
  127. } catch (\Exception $e) {
  128. throw $e;
  129. }
  130. }
  131. /**
  132. * 公钥验签
  133. *@param [$plainText[]
  134. *@param [$sign[]
  135. *@return [int]
  136. *@throws [\Exception]
  137. */
  138. function verify($plainText,$sign,$path){
  139. $file = file_get_contents($path);
  140. if(!$file){
  141. throw new \Exception('verify::file_get_contents ERROR');
  142. }
  143. $cert = chunk_split(base64_encode($file),64,"\n");
  144. $cert = "-----BEGIN CERTIFICATE-----\n".$cert."-----END CERTIFICATE-----\n";
  145. $resource = openssl_pkey_get_public($cert);
  146. $result = openssl_verify($plainText,base64_decode($sign),$resource);
  147. openssl_free_key($resource);
  148. if(!$result){
  149. throw new \Exception('签名验证未通过,plainText:'.$plainText.'。sign:'.$sign,'02002');
  150. }
  151. return $result;
  152. }
  153. /**
  154. * 对数组变量进行JSON编码,为了(本系统的PHP版本为5.3.0)解决PHP5.4.0以上才支持的JSON_UNESCAPED_UNICODE参数
  155. *@param mixed array 待编码的 array (除了resource 类型之外,可以为任何数据类型,改函数只能接受 UTF-8 编码的数据)
  156. *@return string (返回 array 值的 JSON 形式)
  157. *@author
  158. * @d/t 2017-07-17
  159. */
  160. function json_encodes( $array ){
  161. if(version_compare(PHP_VERSION,'5.4.0','<')){
  162. $str = json_encode($array);
  163. $str = preg_replace_callback("#\\\u([0-9a-f]{4})#i",function($matchs){
  164. return iconv('UCS-2BE','UTF-8',pack('H4',$matchs[1]));
  165. },$str);
  166. return $str;
  167. }else{
  168. return json_encode($array,320);
  169. }
  170. }
  171. /**
  172. * 分割字符串
  173. * @param String $str 要分割的字符串
  174. * @param int $length 指定的长度
  175. * @param String $end 在分割后的字符串块追加的内容
  176. */
  177. function mb_chunk_split($string, $length, $end, $once = false){
  178. $string = iconv('gb2312', 'utf-8//ignore', $string);
  179. $array = array();
  180. $strlen = mb_strlen($string);
  181. while($strlen){
  182. $array[] = mb_substr($string, 0, $length, "utf-8");
  183. if($once)
  184. return $array[0] . $end;
  185. $string = mb_substr($string, $length, $strlen, "utf-8");
  186. $strlen = mb_strlen($string);
  187. }
  188. $str = implode($end, $array);
  189. return $str.'%0A';
  190. }
  191. function mb_array_chunk($arr)
  192. {
  193. $credential = json_decode($arr['body']['credential'],true);
  194. $credential['params']['orig'] = $this->mb_chunk_split($credential['params']['orig'],76,'%0A');
  195. $credential['params']['sign'] = $this->mb_chunk_split($credential['params']['sign'],76,'%0A');
  196. $arr['body']['credential'] = str_replace(array('==','+','='),array('%3D%3D','%2B','%3D'),$this->json_encodes($credential));
  197. return $this->json_encodes($arr);
  198. }
  199. }