WechatMediaUploadService.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: yunzhong
  5. * Date: 2020/1/9
  6. * Time: 15:47
  7. */
  8. namespace app\common\services\wechat;
  9. use app\common\services\wechat\lib\WxPayConfig;
  10. use app\common\services\wechat\lib\WxPayException;
  11. use GuzzleHttp\HandlerStack;
  12. use WechatPay\GuzzleMiddleware\WechatPayMiddleware;
  13. use WechatPay\GuzzleMiddleware\Util\PemUtil;
  14. class WechatMediaUploadService
  15. {
  16. /**
  17. * @param $config
  18. * @param $file
  19. * @param $fileName
  20. * @return mixed
  21. * @throws WxPayException
  22. */
  23. public function postCurlV3($config, $file, $fileName, $second = 30)
  24. {
  25. $url ='https://api.mch.weixin.qq.com/v3/merchant/media/upload';
  26. $boundary ='yunzmall';//分割符号
  27. $sign = hash('sha256',$file);
  28. $strdata = [
  29. 'filename' => $fileName,
  30. 'sha256' => $sign,
  31. ];
  32. $filestr = json_encode($strdata);
  33. $body = $this->getBody($filestr, $file, $fileName, $boundary);
  34. $header = $this->getHeader($config, $url, $filestr, $boundary);
  35. $ch = curl_init();
  36. //设置超时
  37. curl_setopt($ch, CURLOPT_TIMEOUT, $second);
  38. curl_setopt($ch,CURLOPT_URL, $url);
  39. if(stripos($url,"https://")!==FALSE){
  40. curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
  41. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  42. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  43. } else{
  44. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
  45. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
  46. }
  47. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  48. curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
  49. //要求结果为字符串且输出到屏幕上
  50. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  51. //post提交方式
  52. curl_setopt($ch, CURLOPT_POST, TRUE);
  53. curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
  54. //运行curl
  55. $data = curl_exec($ch);
  56. //返回结果
  57. if($data){
  58. curl_close($ch);
  59. return json_decode($data, true);
  60. } else {
  61. $error = curl_errno($ch);
  62. curl_close($ch);
  63. throw new WxPayException("curl出错,错误码:$error");
  64. }
  65. }
  66. public function getHeader($config, $url, $filestr, $boundary)
  67. {
  68. $method ='POST';
  69. $http_method =$method;
  70. $timestamp = time();
  71. $nonce = $this->getNonceStr();
  72. $mch_private_key = PemUtil::loadPrivateKey($config->getKeyPath());
  73. $merchant_id = $config->GetMerchantId();
  74. $serial_no = '19D4A2191AE6688A8213E248C35457A3E4E85A17';
  75. $url_parts = parse_url($url);
  76. $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ?"?${url_parts['query']}" :""));
  77. $message =$http_method."\n".
  78. $canonical_url."\n".
  79. $timestamp."\n".
  80. $nonce."\n".
  81. $filestr.
  82. "\n";
  83. openssl_sign($message,$raw_sign,$mch_private_key,'sha256WithRSAEncryption');
  84. $sign =base64_encode($raw_sign);
  85. $schema ='WECHATPAY2-SHA256-RSA2048';
  86. $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
  87. $merchant_id,$nonce,$timestamp,$serial_no,$sign);
  88. $header = [
  89. 'Authorization: '.$schema.' '.$token,
  90. 'Accept: application/json',
  91. "Content-Type: multipart/form-data;boundary=".$boundary,
  92. 'User-Agent: Fangbc',
  93. ];
  94. return $header;
  95. }
  96. /**
  97. * @param $filestr
  98. * @param $file
  99. * @param $fileName
  100. * @param $boundary
  101. * @return string
  102. */
  103. public function getBody($filestr, $file, $fileName, $boundary)
  104. {
  105. $out = "--{$boundary}\r\n";
  106. $out .= 'Content-Disposition: form-data; name="meta"'."\r\n";
  107. $out .= 'Content-Type: application/json; charset=UTF-8'."\r\n";
  108. $out .= "\r\n";
  109. $out .= "".$filestr."\r\n";
  110. $out .= "--{$boundary}\r\n";
  111. $out .= 'Content-Disposition: form-data; name="file"; filename="'.$fileName.'"'."\n";
  112. $out .= 'Content-Type: image/jpeg;'."\r\n";
  113. $out .= "\r\n";
  114. $out .= $file."\r\n";
  115. $out .= "--{$boundary}--\r\n";
  116. return $out;
  117. }
  118. /**
  119. *
  120. * 产生随机字符串,不长于32位
  121. * @param int $length
  122. * @return string
  123. */
  124. public static function getNonceStr($length = 32)
  125. {
  126. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  127. $str ="";
  128. for ( $i = 0; $i < $length; $i++ ) {
  129. $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
  130. }
  131. return $str;
  132. }
  133. }