appid = $configValue['app_id']; $this->appsecret = $configValue['app_secret']; } public function getSignPackage($url) { $jsapiTicket = $this->getWechatJsApiTicket(); // 注意 URL 一定要动态获取,不能 hardcode. // $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; // $url = $this->url?$this->url:"$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; $timestamp = time(); $nonceStr = $this->getRandString(16); // 这里参数的顺序要按照 key 值 ASCII 码升序排序 $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url"; $signature = sha1($string); $signPackage = array( "appId" => $this->appid, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string ); return $signPackage; } /** * 获取微信基础access_token * @param bool $updatenow 是否立即刷新 * @return string */ public function getWechatBasicAccesstoken($updatenow = false) { //有效期一般为7200秒,开发者必须在自己的服务全局缓存access_token //此处保存的access_token为基础的,并非授权的(授权的需要实时获取) //读取缓存 $access_token = cache('access_token'); //过期或强制刷新时,需重新请求 if(!$access_token || $updatenow) { $rs = json_decode(curl_get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->appid.'&secret='.$this->appsecret), true); if(!empty($rs['errmsg'])) { abort(500, $rs['errmsg']); //请求失败 } //缓存存储 $access_token = $rs['access_token']; cache('access_token', $access_token, $rs['expires_in'] - 1000); } return $access_token; } /** * 获取微信jsapi_ticket * @param string $updatenow 是否立即更新 * @return string */ private function getWechatJsApiTicket($updatenow = false) { //有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket //读取缓存 $ticket = cache('jsapi_ticket'); //过期或强制刷新时,需重新请求 if(!$ticket || $updatenow) { //读取access_token $access_token = $this->getWechatBasicAccesstoken(); //请求ticket $rs = json_decode(curl_get('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$access_token.'&type=jsapi'), true); if($rs['errmsg'] != 'ok') { //失败时,强制刷新access_token,再次请求 $access_token = $this->getWechatBasicAccesstoken(true); $rs = json_decode(curl_get('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$access_token.'&type=jsapi'), true); if($rs['errmsg'] != 'ok') { abort(500, $rs['errmsg']); //请求失败 } } //缓存存储 $ticket = $rs['ticket']; cache('jsapi_ticket', $ticket, $rs['expires_in'] - 1000); } return $ticket; } /** * 获取随机字符串 * @param int $length 字符串长度 * @return null|string */ private function getRandString($length = 1) { $str = null; $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; $max = strlen($strPol) - 1; for($i = 0; $i < $length; $i++) { $str .= $strPol[rand(0, $max)]; } return $str; } /** * 获取微信分享配置 * @param integer $return_arr 是否返回数组格式 * @param string $url 分享地址 * @return string */ public function getShareConfig($return_arr = 0, $url = '') { //时间戳 $wx_timestamp = systemTime(); //随机字符串 $wx_nonceStr = $this->getRandString('16'); //签名 $json_jsapi_ticket = $this->getWechatJsApiTicket(); //$url = $url ?: HTTP_TYPE.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; //$url_arr = explode('#', $url); //$url = $url_arr[0] ?? ''; $url = request()->domain().'/wap/'; $wx_signature = sha1('jsapi_ticket='.$json_jsapi_ticket.'&noncestr='.$wx_nonceStr.'×tamp='.$wx_timestamp.'&url='.$url.''); //接口列表 $jsApiList = ['updateAppMessageShareData','updateTimelineShareData ','onMenuShareWeibo','openAddress','onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ']; if($return_arr) { $rt = []; $rt['appId'] = $this->appid; $rt['timestamp'] = $wx_timestamp; $rt['nonceStr'] = $wx_nonceStr; $rt['signature'] = $wx_signature; $rt['jsApiList'] = $jsApiList; return $rt; } else { $jsApiList = json_encode($jsApiList); return " "; } } /** * 设置公众号的模板消息所在行业(IT科技-互联网|电子商务, IT科技-IT软件与服务) * @return array */ public function setWxTplMsgIndustry() { $rt = ['status' => false, 'msg' => '']; //获取基础token $basic_token = $this->getWechatBasicAccesstoken(true); //获取当前行业 $url = 'https://api.weixin.qq.com/cgi-bin/template/get_industry?access_token='.$basic_token; $industry_cur = curl_get($url); $industry_cur = json_decode($industry_cur, true); if($industry_cur) { //是否是正确的行业 $is_valid = true; foreach($industry_cur as $_k => $_industry) { if($_industry['first_class'] !== 'IT科技' || !in_array($_industry['second_class'], ['互联网|电子商务', 'IT软件与服务'])) { $is_valid = false; } } if(!$is_valid) { //不正确要改行业 $url = 'https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token='.$basic_token; $data = []; $data['industry_id1'] = 1; //IT科技 互联网|电子商务 $data['industry_id2'] = 2; //IT科技 IT软件与服务 $rs = curl_post($url, json_encode($data)); $rs = json_decode($rs, true); if(!empty($rs['errcode'])) { $rt['msg'] = $rs['errmsg']; return $rt; } } } $rt['status'] = true; return $rt; } /** * 获取微信消息模板配置 * @param string $key 微信消息模板ID * @return array */ public function getWxMsgTplConf($key = '') { //获取基础token $basic_token = $this->getWechatBasicAccesstoken(true); //请求微信消息模板列表 $url = 'https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token='.$basic_token; $rs = curl_get($url); $rs = json_decode($rs, true); if(!empty($rs['template_list'])) { $rs = $rs['template_list']; if($key) { //若指定模板 foreach($rs as $_k => $_v) { if($_v['template_id'] === $key) { $rt = $rs[$_k]; break; } } } else { //返回所有模板 $rt = $rs; } } return $rt ?? []; } }