mch_id=env('WX_MCH_ID',''); // $this->private_key=env('WX_PRIVATE_KEY',''); // $this->appid=env('WX_APPID',''); // $this->appsecret=env('WX_APPSECRET',''); // $this->cert_file=env('WX_CERT_FILE',''); // $this->key_file=env('WX_KEY_FILE',''); // $this->appletId=env('APPLET_ID',''); // $this->appletKey=env('APPLET_KEY',''); $this->mch_id=config('weixin.mch_id',''); $this->private_key=config('weixin.private_key',''); $this->appid=config('weixin.app_id',''); $this->appsecret=config('weixin.app_secret',''); $this->cert_file=config('weixin.cert_file',''); $this->key_file=config('weixin.key_file',''); $this->appletId=config('weixin.applet_id',''); $this->appletKey=config('weixin.applet_key',''); } /** * 创建对象 * @return WeixinServer */ static function creatServer() { if (empty(self::$server)) self::$server = new WeixinServer(); return self::$server; } /** * 小程序code获取openid等信息 * @param $code * @param $invite_code * @return array|false */ function getAppletsOpenId($code){ $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$this->appletId}&secret={$this->appletKey}&js_code={$code}&grant_type=authorization_code"; $result = $this->sendRequest($url); $result = json_decode($result, true); if ( !isset($result['openid'])) {//成功返回信息 return ['code'=>0,'msg'=>$result['errmsg']]; } else { return $result; } } /** * 获取小程序码 * @param $page //页面路径 * @param $scene //携带参数 */ function getAppletCode($page,$scene){ $access_token = $this->getAccessToken(2); $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$access_token}"; $data['page'] = $page; $data['scene'] = $scene; $data['check_path'] = false; $data['width'] = 300; // $data['env_version'] = 'trial';//要打开的小程序版本。正式版为 "release",体验版为 "trial",开发版为 "develop"。默认是正式版。 $result = $this->sendRequest($url,'post',$data); return $result; } /** * 获取 access_token * @return bool */ protected function getAccessToken($type = 1) { if($type == 1){ $key = 'vouchername'; $appId = $this->appid; $appsecret = $this->appsecret; }else{ $key = 'applet_voucher'; $appId = $this->appletId; $appsecret = $this->appletKey; } $data = RedisDataServer::creatServer()->getData($key, 'json'); if (empty($data) || $data['endtime'] < time()) { $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appsecret}"; $result = $this->sendRequest($url); $result = json_decode($result, true); // $bey = Cache::set('vouchername', array('access_token' => $result['access_token'], 'endtime' => time() + 7000), 7000); if ( isset($result['access_token'])) { RedisDataServer::creatServer()->setData($key, array('access_token' => $result['access_token'], 'endtime' => time() + 1800), 'json',1800); return $result['access_token']; } else { return false; } } else { return $data['access_token']; } } /** * 获取js授权信息 * @return mixed */ function getJsConfig($url = '') { $hash = ''; $chars = 'ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz'; $max = strlen($chars) - 1; for ($i = 0; $i < 16; $i++) { $hash .= $chars[mt_rand(0, $max)]; } $data['noncestr'] = $hash; $data['jsapi_ticket'] = $this->getJsTicket(); $data['timestamp'] = time(); if (empty($url)) { $data['url'] = $this->getServerUrl(); } else { $data['url'] = $url; } ksort($data); $str = ''; foreach ($data as $key => $val) { $str .= '&'; $str .= $key . '=' . $val; } $str = mb_substr($str, 1); $data['appId'] = $this->appid; $data['signature'] = sha1($str); unset($data['jsapi_ticket']); return $data; } /** * 获取当前连接 * @return string */ function getServerUrl() { // $http_host=request()->header('host'); // $data=request()->all(); return urlencode('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); // return 'http://'.$http_host. '?' . http_build_query($data);; } /** * 获取Js调用凭证 * @return bool */ function getJsTicket() { // $data = Cache::get('js_ticket'); $data = RedisDataServer::creatServer()->getData('js_ticket', 'json'); if (empty($data) || $data['endtime'] < time()) { $access_token = $this->getAccessToken(); $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$access_token}&type=jsapi"; $result = $this->sendRequest($url); $result = json_decode($result, true); if ($result['errcode'] == 0) { //file_put_contents($this->js_ticket,serialize(array('access_token'=>$result['access_token'],'endtime'=>time()+7000))); // Cache::set('js_ticket', array('access_token' => $result['ticket'], 'endtime' => time() + 7000), 7000); RedisDataServer::creatServer()->setData('js_ticket', array('access_token' => $result['ticket'], 'endtime' => time() + 7000), 'json',7000); return $result['ticket']; } return false; } else { return $data['access_token']; } } /** * 文本内容安全识别 * @param $openid * @param $content * @return bool */ function msgSecCheck($openid,$content) { $access_token = $this->getAccessToken(2); $url = 'https://api.weixin.qq.com/wxa/msg_sec_check?access_token='.$access_token; $conf = array( 'content' => $content, 'version' => 2, 'openid' => $openid, 'scene' => 2, ); // var_dump($conf); $result = $this->http_post_request($url,json_encode($conf, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); // $result = json_decode($result, true); //var_dump($result); if ($result['errcode'] != 0) { return false; }elseif ($result['result']['label'] != 100) { return false; } else { return true; } } /** * 图片和视频内容安全识别 * @param $openid * @param $media_url * @param $media_type * @return false|mixed */ function mediaCheckAsync($openid,$media_url,$media_type=1) { $access_token = $this->getAccessToken(2); // var_dump($access_token); $url = 'https://api.weixin.qq.com/wxa/media_check_async?access_token='.$access_token; $conf = array( 'media_url' => $media_url, 'media_type' => $media_type, 'version' => 2, 'openid' => $openid, 'scene' => 1, ); $result = $this->http_post_request($url,json_encode($conf, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); // var_dump($result); if ($result['errcode'] != 0) { return false; }else{ return $result['trace_id']; } } /** * 微信签名 */ function wxSign($data, $keys) { ksort($data); $str = ''; foreach ($data as $key => $val) { if ($val) { if ($str != '') $str .= '&'; $str .= "{$key}={$val}"; } } $str .= '&key=' . $keys; $sign = strtoupper(MD5($str)); return $sign; } /** * @param $url * @param string $type 请求方式 * @param string $data 数据 数组格式 * @return mixed */ protected function sendRequest($url, $type = 'get', $data = '') { $ch = curl_init(); if ($type == 'get' && $data) { $url = $url . '?' . http_build_query($data); } curl_setopt($ch, CURLOPT_URL, $url); //设置访问路径 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //设置可以返回字符串 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $head = array('User-Agent:Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36'); curl_setopt($ch, CURLOPT_HTTPHEADER, $head); if ($type == 'post') { curl_setopt($ch, CURLOPT_POST, TRUE);//post请求 $data = json_encode($data, JSON_UNESCAPED_UNICODE); curl_setopt($ch, CURLOPT_POSTFIELDS, $data);//设置传递的参数 } $request = curl_exec($ch); curl_close($ch); return $request; } public function http_post_request($url, $jsonStr) { $ch = curl_init(); curl_setopt($ch, CURLOPT_POST, 1);// 发送一个常规的Post请求 curl_setopt($ch, CURLOPT_URL, $url);// 要访问的地址 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检测 curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循 curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json;charset=UTF-8', 'Content-Length: ' . strlen($jsonStr) ) ); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $http_error = curl_error($ch); curl_close($ch); $response = json_decode($response, 1); //var_dump($response); return $response; } /** * JS支付签名 * @param $order_sn * @param $total_fee * @param $notify_url * @param $body * @param $wx_openid * @return bool */ public function wxJsPay($order_sn, $total_fee, $notify_url, $body, $wx_openid = '') { // $is_test=env('TEST_SERVE',false); $is_test=config('weixin.test_serve',false); if($is_test) { // PayServer::creatServer()->NotifyPay($order_sn, '147258369', $total_fee, ['data'=>'测试']);//暂时测试直接走回调 $total_fee = 0.01; } $conf = array( 'appid' => $this->appletId, 'mch_id' => $this->mch_id, 'notify_url' => $notify_url, 'openid' => $wx_openid, 'out_trade_no' => $order_sn, 'total_fee' => $total_fee * 100, 'trade_type' => 'JSAPI', 'body' => $body, ); // var_dump($conf); $order = new Unifiedorder($conf); $request = $order->getOrder($this->private_key); var_dump($request); if ($request['code'] == 1) { $datas["appId"] = $request['data']['appid']; $datas["nonceStr"] = $order->getNonceStr(); $datas["package"] = "prepay_id={$request['data']['prepay_id']}"; $datas["signType"] = 'MD5'; $datas["timeStamp"] = time(); $s = $order->wxSign($datas, $this->private_key); $datas["paySign"] = $s; return $datas; } else { return false; } } /** * 微信验签 * @param $data * @return string */ function verifyCer($data) { if (isset($data['sign'])) unset($data['sign']); $conf = array( 'appid' => $this->appletId, 'mch_id' => $this->mch_id, ); $order = new Unifiedorder($conf); $sign = $order->wxSign($data, $this->private_key); return $sign; } /** * 微信退款 * @param $total_fee * @param $out_trade_no * @param string $body * @param int $order_money * @return array */ function wxPayRefund($out_trade_no, $total_fee, $body = '',$order_money=0) { // $is_test=env('TEST_SERVE',false); $is_test=config('weixin.test_serve',false); // dd($is_test); if($is_test){ $total_fee = 0.01; $order_money = 0.01; } $conf = array( 'appid' => $this->appletId, 'mch_id' => $this->mch_id, 'out_trade_no' => $out_trade_no, 'out_refund_no' => 'T'.$out_trade_no.time(), 'total_fee' => $order_money * 100, 'refund_fee' => $total_fee * 100, 'refund_desc' => $body ); $order = new Unifiedorder($conf, ['cert_file' => base_path($this->cert_file), 'key_file' => base_path($this->key_file)]); $request = $order->wxPayRefund($this->private_key); // var_dump($request); if ($request['code'] == 1) { return ['code' => 1, 'msg' => '退款成功', 'data' => ['ret_sn' => $request['data']['refund_id']]]; } else { ErrorRecord::create(['m_id' =>0, 'msg' => '微信退款失败', 'data' => json_encode($request)]); return ['code' => 0, 'msg' => '微信退款失败', 'data' => ['ret_sn' => '']]; } } /** * 微信付款到零钱 * @param $order_sn * @param $total_fee * @param $openid * @param $body * @return array */ function setVerified($order_sn, $total_fee, $openid, $body) { $cert_file=base_path($this->cert_file); $key_file=base_path($this->key_file); $private_key=$this->private_key; $conf = array( 'mch_appid' => $this->appletId, 'mchid' => $this->mch_id, 'openid' => $openid, 'partner_trade_no' => $order_sn, 'amount' => $total_fee * 100, 'check_name' => 'NO_CHECK', 'desc' => $body, ); $order = new Unifiedorder($conf, ['cert_file' => $cert_file, 'key_file' => $key_file]); $request = $order->setVerified($private_key); ErrorRecord::create(['m_id' =>0, 'msg' => '微信提现记录', 'data' => json_encode($request)]); return $request; } }