zoukankan      html  css  js  c++  java
  • 微信支付v3版本PHP v3/merchant/media/upload 图片上传

    最近对接微信wechatpay-api-v3商户通图片上传遇见“错误的签名,验签失败”的问题,发现有不少遇到同样问题的伙伴。希望下面的代码能帮到你们

    <?php
    
    class Test
    {
    
        public function run()
        {
            $url = 'https://api.mch.weixin.qq.com/v3/merchant/media/upload';
            $filename = __DIR__.'/1.png';
            $merchant_id='商户号';
            $serial_no='API证书序列号';
            $mch_private_key=$this->getPrivateKey(ROOT_PATH.'cert/wxpay_shoufutong/apiclient_key.pem');       //商户私钥
            $fi = new finfo(FILEINFO_MIME_TYPE);
            $mime_type = $fi->file($filename);
            $data['filename'] = '1.png';
            $meta['filename'] = '1.png';
            $meta['sha256'] = hash_file('sha256',$filename);
            $boundary = uniqid(); //分割符号
            $date = time();
            $nonce = $this->nonce_str();
            $sign = $this->sign($url,'POST',$date,$nonce,json_encode($meta),$mch_private_key,$merchant_id,$serial_no);//$http_method要大写
            $header[] = 'User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36';
            $header[] = 'Accept:application/json';
            $header[] = 'Authorization:WECHATPAY2-SHA256-RSA2048 '.$sign;
            $header[] = 'Content-Type:multipart/form-data;boundary='.$boundary;
    
            $boundaryStr = "--{$boundary}
    ";
            $out = $boundaryStr;
            $out .= 'Content-Disposition: form-data; name="meta"'."
    ";
            $out .= 'Content-Type: application/json'."
    ";
            $out .= "
    ";
            $out .= json_encode($meta)."
    ";
            $out .=  $boundaryStr;
            $out .= 'Content-Disposition: form-data; name="file"; filename="'.$data['filename'].'"'."
    ";
            $out .= 'Content-Type: '.$mime_type.';'."
    ";
            $out .= "
    ";
            $out .= file_get_contents($filename)."
    ";
            $out .= "--{$boundary}--
    ";
            $r = $this->doCurl($url,$out,$header);
            var_dump($r);die;
        }
    
        private function nonce_str()
        {
            return date('YmdHis', time()) . rand(10000, 99999);
        }
        public function doCurl($url, $data , $header = array(), $referer = '', $timeout = 30)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
            //避免https 的ssl验证
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_SSLVERSION, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
            // 模拟来源
            curl_setopt($ch, CURLOPT_REFERER, $referer);
            $response = curl_exec($ch);
            if ($error = curl_error($ch)) {
                die($error);
            }
            curl_close($ch);
            return $response;
        }
    
        //获取私钥
        public static function getPrivateKey($filepath) {
            return openssl_get_privatekey(file_get_contents($filepath));
        }
    
        //签名
        private function sign($url,$http_method,$timestamp,$nonce,$body,$mch_private_key,$merchant_id,$serial_no)
        {
    
            $url_parts = parse_url($url);
            $canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
            $message =
                $http_method."
    ".
                $canonical_url."
    ".
                $timestamp."
    ".
                $nonce."
    ".
                $body."
    ";
            openssl_sign($message, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
            $sign = base64_encode($raw_sign);
            $schema = 'WECHATPAY2-SHA256-RSA2048 ';
            $token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
                $merchant_id, $nonce, $timestamp, $serial_no, $sign);
            return $token;
        }
    
    }

    版权声明:本文为CSDN博主「umedier」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/umedier/article/details/103698092

  • 相关阅读:
    C# 高效字符串连接 StringBuilder介绍
    C#图解教程
    C#中string类型是值类型还是引用类型?
    UML类图10分钟快速入门
    C#设计模式--单例模式
    计算机是如何启动的?
    2018年计划
    转:SQL进阶之变量、事务、存储过程与触发器
    2020/02/06,武汉
    2020/02/06,渐渐,from eason for you for her
  • 原文地址:https://www.cnblogs.com/guanzelin/p/12674161.html
Copyright © 2011-2022 走看看