PHP
微信支付v3版本PHP营销图片上传
微信支付v3版本PHP营销图片上传
昨晚又接到一个需求,依然是微信接口相关的,这一次是微信支付v3图片上传接口,由于也是第一次接触到,所以还是仔细阅读了下文档介绍以及相关流程,再加上前两天已经成功调试出微信支付V3签名验证,所以调试出来也没浪费多少时间,我还弄了一个前端上传图片,后端调用微信接口返回图片地址的功能。
其实调试主要难题是body体的构造,百度了查询相关的代码,最终还是成功调试出,下面是公共配置文件代码,命名为wxComm.php,代码如下:
#微信基础信息 $wxMerchantId = "商户号"; //商户号 $wxMerchantApiCertificate = __DIR__ . "/cert/apiclient_cert.pem"; //商户证书 $wxMerchantApiPrivateKey = __DIR__ . "/cert/apiclient_key.pem"; //商户私钥 $wxApiV3Key = "微信API v3密钥"; //微信API v3密钥 $wxApiSerialNo = "商户API证书序列号"; //商户API证书序列号 ######微信 API V3构造签名流程####### /** * 生成签名 * @param string $method 请求方法 POST 或者GET * @param string $url 请求URL * @param string $request 请求中的请求报文主体 * @param $wxMerchantId商户号 * @param $certKey商户私钥 * @param $wxApiSerialNo商户API证书序列号 * @return string */ function RequestSign($method = "POST", $url = "", $request = "", $wxMerchantId, $certKey, $wxApiSerialNo) { #截取获取当前请求地址【去除域名】 $url_parts = parse_url($url); $path = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : "")); #获取当前时间戳 $timeStamp = time(); #生成一个随机字符串 $nonceStr = getNonceStr(); #构造签名串 $requestSign = sprintf("%s\n%s\n%s\n%s\n%s\n", $method, $path, $timeStamp, $nonceStr, $request); #计算计算签名值 $sign = calculateSignatureValue($requestSign, $certKey); #设置HTTP头获取Authorization $token = createToken($wxMerchantId, $nonceStr, $timeStamp, $wxApiSerialNo, $sign); #返回 return $token; } /** * 计算签名值 * @param $requestSign * @param $certKey * @return string * 使用商户私钥对待签名串进行SHA256 with RSA签名,并对签名结果进行Base64编码得到签名值 */ function calculateSignatureValue($requestSign, $certKey) { $certKey = file_get_contents($certKey); openssl_sign($requestSign, $raw_sign, $certKey, 'sha256WithRSAEncryption'); $sign = base64_encode($raw_sign); return $sign; } /** * 获取token * @param $merchant_id * @param $nonce * @param $timestamp * @param $serial_no * @param $sign * @return string */ function createToken($merchant_id, $nonce, $timestamp, $serial_no, $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; } /** * 产生随机字符串,不长于32位 * @param int $length * @return string */ function getNonceStr($length = 32) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } /** * POST发送图片数据源 * @param $url * @param $data * @param array $header * @param string $referer * @param int $timeout * @return mixed */ function curlPostToImage($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); //json转数组 $result = json_decode($response,true); //返回 return $result; }
然后是调用文件代码,我们先提前创建好一个images的文件夹,并给777权限,用来存放图片,代码如下:
#引入微信公共配置文件 require __DIR__ . "/wxComm.php"; #头部响应设置 header('Access-Control-Allow-Origin:*'); // 响应类型 header('Access-Control-Allow-Methods:GET'); // 响应头设置 header('Access-Control-Allow-Headers:x-requested-with,content-type'); header('Content-Type:application/json; charset=utf-8'); #获取上传图片 $file = $_FILES["file"]; #判断上传的是否为图片格式 if ((($_FILES["file"]["type"] != "image/gif") && ($_FILES["file"]["type"] != "image/jpeg") && ($_FILES["file"]["type"] != "image/jpg") && ($_FILES["file"]["type"] != "image/pjpeg") && ($_FILES["file"]["type"] != "image/x-png") && ($_FILES["file"]["type"] != "image/png")) ) { $json = json_encode(array( 'status' => '-1', 'msg' => "请上传图片" )); echo($json); exit(); } #重新设置文件名 $fileType = str_replace("image/", "", $_FILES["file"]["type"]); $saveName = time() . rand(1, 1000); $fileName = $saveName . "." . $fileType; #保存图片 move_uploaded_file($_FILES["file"]["tmp_name"], "images/" . $fileName); #拼接当前地址 $src = "images/" . $fileName; $imageUrl = __DIR__ . "/images/" . $fileName; #请求地址 $url = "https://api.mch.weixin.qq.com/v3/marketing/favor/media/image-upload"; #请求参数 $params = array( "filename" => $fileName, //文件名 'sha256' => hash_file('sha256', $imageUrl) //图片文件的二进制内容进行sha256 ); #获取authorization $authorization = RequestSign("POST", $url, json_encode($params), $wxMerchantId, $wxMerchantApiPrivateKey, $wxApiSerialNo); #组合body请求体 $boundary = uniqid(); //分割符号 $boundaryStr = "--{$boundary}\r\n"; $out = $boundaryStr; $out .= 'Content-Disposition: form-data; name="meta"' . "\r\n"; $out .= 'Content-Type: application/json' . "\r\n"; $out .= "\r\n"; $out .= json_encode($params) . "\r\n"; $out .= $boundaryStr; $out .= 'Content-Disposition: form-data; name="file"; filename="' . $params['filename'] . '"' . "\r\n"; $out .= 'Content-Type: ' . $fileType . ';' . "\r\n"; $out .= "\r\n"; $out .= file_get_contents($imageUrl) . "\r\n"; $out .= "--{$boundary}--\r\n"; #组合请求头 $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 ' . $authorization; $header[] = 'Content-Type:multipart/form-data;boundary=' . $boundary; #请求发送文件 $result = curlPostToImage($url, $out, $header); #删除本地图片 unlink($imageUrl); #判断是否成功 if (!isset($result["media_url"])) { $json = json_encode(array( 'status' => '-1', 'msg' => "上传失败" )); echo($json); exit(); } #返回请求结果 $json = json_encode(array( 'status' => '1', 'msg' => $result["media_url"] )); echo($json); exit();
附上效果图
这样我们就成功的将图片上传至微信,并获得图片地址。
0条评论