说明:本教程是自己自学+自己的理解+扩展(包括学习过程中遇到的一些问题)
参考教程:麦子学院--李忠益--http://www.maiziedu.com/u/70409/
微盟:
用户名:****
密码:******
邮箱:*****
猪八戒(外包平台):
微信开发者平台:
http://www.henkuai.com/forum.php
微信公众号开发流程文档:
http://www.cnblogs.com/txw1958/p/wechat-tutorial.html
微信JS-SDK说明文档:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
方倍工作室:
http://www.fangbei.org/tool/menu
微信公众平台sdk命名空间版:
http://www.thinkphp.cn/extend/588.html
注:这个最新版本测试时有点问题(需要认证通过的服务号来进行测试),建议使用麦子学院李忠益老师教程里使用的旧版本的微信公众平台sdk来进行学习使用。
说明:
学习过程中需要将项目上传到第三方服务器(具体申请试用过程参见新浪云sae申请)来和微信服务器进行消息传递,为避免学习成本和将代码上传第三方服务器上带来的不便,此处也可以通过花生壳将本地项目访问的域名映射到公网,然后就可以在本地对微信公众平台进行开发测试(具体过程参见第七步(5))。
阿里云sae申请:
新浪云sae申请:
用户名:*********
密 码:********
第一步:创建应用
第二步:上传代码并配置token信息
http://sae.sina.com.cn/?m=sum&app_id=zouke1220&ver=1
第三步:实名认证
http://www.sinacloud.com/ucenter.html?from=topnav
第四步:右击index.php通过URL访问
跳转到地址:http://1.zouke1220.applinzi.com/index20170313/index.php
第五步:微信接口测试号申请:
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
AppID=wx031a699ff141a51a
Appsecret=6b68c41860ba3276a729986bbe5e3cc1
第五步:微信接口正式号申请:(未实名认证)
邮箱:*******
密码:*******
https://mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN
微信认证:
第六步:微信扫一扫
测试微信号:o_SDJ021hERjCHETOxO4j8KWWhdg
(1)index.php
<?php /* 方倍工作室 http://www.fangbei.org/ CopyRight 2011-2017 All Rights Reserved */ header('Content-type:text'); define("TOKEN", "zouke369189"); $wechatObj = new wechatCallbackapiTest(); if (!isset($_GET['echostr'])) { $wechatObj->responseMsg(); }else{ $wechatObj->valid(); } class wechatCallbackapiTest { public function valid() { $echoStr = $_GET["echostr"]; //验证消息的确来自微信服务器 if($this->checkSignature()){ echo $echoStr; exit; } } //验证消息的确来自微信服务器 private function checkSignature() { $signature = $_GET["signature"]; //加密签名 $timestamp = $_GET["timestamp"]; //时间戳 $nonce = $_GET["nonce"]; //随机数 $token = TOKEN; //token $tmpArr = array($token, $timestamp, $nonce); //组成新数组 sort($tmpArr); //重新排序 $tmpStr = implode($tmpArr); //数组转成字符串 $tmpStr = sha1($tmpStr); //将字符串进行加密 if($tmpStr == $signature){ return true; }else{ return false; } } public function responseMsg() { $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; if (!empty($postStr)){ $this->logger("R ".$postStr); $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $RX_TYPE = trim($postObj->MsgType); switch ($RX_TYPE) { case "event": $result = $this->receiveEvent($postObj); break; case "text": $result = $this->receiveText($postObj); break; } $this->logger("T ".$result); echo $result; }else { echo ""; exit; } } private function receiveEvent($object) { $content = ""; switch ($object->Event) { case "subscribe": $content = "欢迎关注方倍工作室"; break; case "unsubscribe": $content = "取消关注"; break; } $result = $this->transmitText($object, $content); return $result; } //接收文本消息 private function receiveText($object) { //去除空白 $keyword = trim($object->Content); //回复内容 //回复的文本内容 //$content = date("Y-m-d H:i:s",time())."\n技术支持 方倍工作室"; //回复的图文数组 /* $content=array( array( 'Title'=>'zouke1', 'Description'=>'zzzzzzzzzzzzzzz', 'PicUrl'=>'http://pic32.nipic.com/20130812/8977957_215354223000_2.jpg', 'Url'=>'http://www.baidu.com' ), array( 'Title'=>'zouke2', 'Description'=>'zzzzzzzzzzzzzzz', 'PicUrl'=>'http://pic32.nipic.com/20130812/8977957_215354223000_2.jpg', 'Url'=>'http://www.baidu.com' ), array( 'Title'=>'zouke3', 'Description'=>'zzzzzzzzzzzzzzz', 'PicUrl'=>'http://pic32.nipic.com/20130812/8977957_215354223000_2.jpg', 'Url'=>'http://www.baidu.com' ) ); */ //回复单图片 $content=array( 'MediaId'=>'q-hgbeHxuYyIkR3Tm9hbvLeFa-cM_LfNw6-tPZ3pf7SPEhdipTaWDZ-vAzlVv2HR', ); /* if(is_array($content)){ if (isset($content[0]['PicUrl'])){ //回复多图文消息 $result = $this->transmitNews($object, $content); }else if (isset($content['MusicUrl'])){ //回复音乐消息 $result = $this->transmitMusic($object, $content); } }else{ //回复文本消息 $result = $this->transmitText($object, $content); } */ if($keyword=='图文'){ if (isset($content[0]['PicUrl'])){ //回复多图文消息 $result = $this->transmitNews($object, $content); }else if (isset($content['MusicUrl'])){ //回复音乐消息 $result = $this->transmitMusic($object, $content); }else{ //回复单图片 $result = $this->transmitImage($object, $content); } }else{ //回复文本消息 $result = $this->transmitText($object, $content); } //$this->logger($result) return $result; } //回复文本消息 private function transmitText($object, $content) { $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[%s]]></Content> </xml>"; //sprintf把百分号(%)符号替换成一个作为参数进行传递的变量 $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content); return $result; } //回复多图文消息 private function transmitNews($object, $arr_item) { if(!is_array($arr_item)) return; $itemTpl = "<item> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> <PicUrl><![CDATA[%s]]></PicUrl> <Url><![CDATA[%s]]></Url> </item>"; $item_str = ""; foreach ($arr_item as $item) $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']); $newsTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[news]]></MsgType> <Content><![CDATA[]]></Content> <ArticleCount>%s</ArticleCount> <Articles>$item_str</Articles> </xml>"; $result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item)); return $result; } //回复音乐消息 private function transmitMusic($object, $musicArray) { $itemTpl = "<Music> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> <MusicUrl><![CDATA[%s]]></MusicUrl> <HQMusicUrl><![CDATA[%s]]></HQMusicUrl> </Music>"; $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']); $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[music]]></MsgType> $item_str </xml>"; $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time()); return $result; } //回复单图片 private function transmitImage($object, $imageArray) { $itemTpl = "<Image> <MediaId><![CDATA[%s]]></MediaId> </Image>"; $item_str = sprintf($itemTpl, $imageArray['MediaId']); $xmlTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[image]]></MsgType> $item_str </xml>"; $result = sprintf($xmlTpl, $object->FromUserName, $object->ToUserName, time()); return $result; } //日志记录 private function logger($log_content) { if(isset($_SERVER['HTTP_APPNAME'])){ //SAE sae_set_display_errors(false); sae_debug($log_content); sae_set_display_errors(true); }else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL $max_size = 10000; $log_filename = "log.xml"; if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);} file_put_contents($log_filename, date('H:i:s')." ".$log_content."\r\n", FILE_APPEND); } } } ?> |
(2)update.php
//微信上传素材之curl用法 function http_curl($url,$data=null){ //1.初始化,创建一个新cURL资源 $ch = curl_init(); curl_setopt ( $ch, CURLOPT_SAFE_UPLOAD, false); //2.设置URL和相应的选项 curl_setopt($ch, CURLOPT_URL, $url); //curl_setopt($ch, CURLOPT_HEADER, 0); if(!empty($data)){ curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,$data); } //禁止curl资源直接输出 curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); //3.抓取URL并把它传递给浏览器 $opt=curl_exec($ch); //4.关闭cURL资源,并且释放系统资源 curl_close($ch); return $opt; } //获取token function get_token(){ $appid="wx031a699ff141a51a"; $secret="6b68c41860ba3276a729986bbe5e3cc1"; $url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}"; $json=http_curl($url); $result=json_decode($json); return $result->access_token; } $token=get_token(); //上传图片到微信服务器上 第一步:将要上传到微信服务器上的图片先上传到新浪云服务器上 第二步:update.php处理 $type="image"; $url="http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={$token}&type={$type}"; $path=dirname(__FILE__)."/xiaotu.jpg"; //var_dump($path); // /data1/www/htdocs/950/zouke1220/1/index20170313/xiaotu.jpg $data["media"]='@'.$path; $arr=http_curl($url,$data); //var_dump($arr); //"{"type":"image","media_id":"q-hgbeHxuYyIkR3Tm9hbvLeFa-cM_LfNw6-tPZ3pf7SPEhdipTaWDZ-vAzlVv2HR","created_at":1501658024}" //上传临时素材到公众号遇到的问题:"errcode":41005,"errmsg":"media data missing /***********************解决方法***************************** http_curl 方法中增加 curl_setopt ( $ch, CURLOPT_SAFE_UPLOAD, false); ************************************************************/ //自定义菜单上传到服务器上 $url="https://api.weixin.qq.com/cgi-bin/menu/create?access_token={$token}"; $data='{ "button":[ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "name":"菜单", "sub_button":[ { "type":"view", "name":"搜索", "url":"http://www.soso.com/" }, { "type":"miniprogram", "name":"wxa", "url":"http://mp.weixin.qq.com", "appid":"wx286b93c14bbf93aa", "pagepath":"pages/lunar/index.html", }, { "type":"click", "name":"赞一下我们", "key":"V1001_GOOD" }] }] }'; $result=http_curl($url,$data); var_dump($result); //string(27) "{"errcode":0,"errmsg":"ok"}" //错误:string(71) "{"errcode":85005,"errmsg":"appid not bind weapp hint: [wuKL50493vr20]"}" /**********************解决方法********************************** //删除菜单中以下小程序菜单项 { "type":"miniprogram", "name":"wxa", "url":"http://mp.weixin.qq.com", "appid":"wx286b93c14bbf93aa", "pagepath":"pages/lunar/index.html", }, ****************************************************************/ //通过表单提交创建菜单json字符串 http://1.zouke1220.applinzi.com/admin/ 第一步:先接收提交过来的表单数据 //echo "<pre>"; //print_r($_POST); //echo "</pre>"; /******************************** Array ( [do_submit] => 提交查询 [menu0] => 1 [menu0_box] => click [menu0_0] => 1 [menu0_menu0] => 11 [menu0_menu1] => 22 [menu0_menu2] => 33 [menu0_menu3] => 44 [menu0_menu4] => 55 [menu0_menu0_box0] => view [menu0_menu0_name0] => www.baidu.com [menu0_menu0_box1] => view [menu0_menu0_name1] => www.baidu.com [menu0_menu0_box2] => view [menu0_menu0_name2] => www.baidu.com [menu0_menu0_box3] => view [menu0_menu0_name3] => www.baidu.com [menu0_menu0_box4] => view [menu0_menu0_name4] => www.baidu.com [menu1] => 2 [menu1_box] => click [menu1_1] => 2 [menu1_menu0] => 66 [menu1_menu1] => 77 [menu1_menu2] => [menu1_menu3] => [menu1_menu4] => [menu1_menu0_box0] => view [menu1_menu0_name0] => www.baidu.com [menu1_menu0_box1] => view [menu1_menu0_name1] => www.baidu.com [menu1_menu0_box2] => view [menu1_menu0_name2] => [menu1_menu0_box3] => view [menu1_menu0_name3] => [menu1_menu0_box4] => view [menu1_menu0_name4] => [menu2] => 3 [menu2_box] => click [menu2_2] => 3 [menu2_menu0] => [menu2_menu1] => [menu2_menu2] => [menu2_menu3] => [menu2_menu4] => [menu2_menu0_box0] => view [menu2_menu0_name0] => [menu2_menu0_box1] => view [menu2_menu0_name1] => [menu2_menu0_box2] => view [menu2_menu0_name2] => [menu2_menu0_box3] => view [menu2_menu0_name3] => [menu2_menu0_box4] => view [menu2_menu0_name4] => ) ********************************/ 第二步:拼接菜单 if(isset($_POST["do_submit"])){ for($i=0;$i<3;$i++){ //指定下标 //一级菜单的名字 $button="menu{$i}"; //一级菜单的类型 $type="menu{$i}_box"; //一级菜单的值 $key="menu{$i}_{$i}"; //二级菜单的名字 $sub_submit="menu{$i}_menu0"; //如果有子菜单 if(trim($_POST[$sub_submit]) !=""){ //组装二级菜单 for($j=0;$j<5;$j++){ //二级菜单名字 $sub_submit="menu{$i}_menu{$j}"; //二级菜单类型 $sub_type="menu{$i}_menu0_box{$j}"; //二级菜单的值 $sub_key="menu{$i}_menu0_name{$j}"; if(trim($_POST[$sub_submit]) !=""){ //一级菜单的名称 $menuarr['button'][$i]['name']=$_POST[$button]; if($_POST[$sub_type]=="click"){ $menuarr['button'][$i]['sub_button'][$j]['type']="click"; $menuarr['button'][$i]['sub_button'][$j]['name']=$_POST[$sub_submit]; $menuarr['button'][$i]['sub_button'][$j]['key']=$_POST[$sub_key]; }else if($_POST[$sub_type]=="view"){ $menuarr['button'][$i]['sub_button'][$j]['type']="view"; $menuarr['button'][$i]['sub_button'][$j]['name']=$_POST[$sub_submit]; $menuarr['button'][$i]['sub_button'][$j]['url']=$_POST[$sub_key]; } } } }else{ //组装一级菜单 if(trim($_POST[$button]) !=""){ if($_POST[$type]=="click"){ $menuarr['button'][$i]['type']="click"; $menuarr['button'][$i]['name']=$_POST[$button]; $menuarr['button'][$i]['key']=$_POST[$key]; }else if($_POST[$type]=="view"){ $menuarr['button'][$i]['type']="view"; $menuarr['button'][$i]['name']=$_POST[$button]; $menuarr['button'][$i]['url']=$_POST[$key]; } } } } } //echo "<pre>"; //print_r($menuarr); //echo "</pre>"; /*********************** Array ( [button] => Array ( [0] => Array ( [name] => 1 [sub_button] => Array ( [0] => Array ( [type] => view [name] => 11 [url] => www.baidu.com ) [1] => Array ( [type] => view [name] => 22 [url] => www.baidu.com ) [2] => Array ( [type] => view [name] => 33 [url] => www.baidu.com ) [3] => Array ( [type] => view [name] => 44 [url] => www.baidu.com ) [4] => Array ( [type] => view [name] => 55 [url] => www.baidu.com ) ) ) [1] => Array ( [name] => 2 [sub_button] => Array ( [0] => Array ( [type] => view [name] => 66 [url] => www.baidu.com ) [1] => Array ( [type] => view [name] => 77 [url] => www.baidu.com ) [2] => Array ( [type] => view [name] => 88 [url] => ) [3] => Array ( [type] => view [name] => 99 [url] => ) [4] => Array ( [type] => view [name] => 00 [url] => ) ) ) [2] => Array ( [type] => click [name] => 3 [key] => 3 ) ) ) ***********************/ 第三步:将菜单数组转json $data=json_encode($menuarr,JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); //print_r("'$data'"); /********************** $data='{ "button": [ { "name": "1", "sub_button": [ { "type": "view", "name": "11", "url": "http://www.baidu.com" }, { "type": "view", "name": "22", "url": "http://www.baidu.com" }, { "type": "view", "name": "33", "url": "http://www.baidu.com" }, { "type": "view", "name": "44", "url": "http://www.baidu.com" } ] }, { "name": "2", "sub_button": [ { "type": "view", "name": "66", "url": "http://www.baidu.com" }, { "type": "view", "name": "77", "url": "http://www.baidu.com" }, { "type": "view", "name": "88", "url": "http://www.soso.com/" }, { "type": "view", "name": "99", "url": "http://www.soso.com/" } ] }, { "type": "click", "name": "3", "key": "3" } ] }'; **********************/ 第四步:将拼接好的菜单提交到微信服务器上 $url="https://api.weixin.qq.com/cgi-bin/menu/create?access_token={$token}"; $result=http_curl($url,$data); //var_dump($result); $arr=json_decode($result,true); if($arr['errmsg']=="ok"){ echo "<script>alert('提交成功!');history.go(-1);</script>"; }else{ echo "<script>alert('提交失败!');history.go(-1);</script>"; } 错误:string(81) "{"errcode":40054,"errmsg":"invalid sub button url domain hint: [X6VYra0784vr19]"}" 解决方法:地址前面加http:// 错误:string(73) "{"errcode":40027,"errmsg":"invalid sub button url size hint: [0205vr23]"}" 解决方法:二级菜单有值的,其菜单类型对应的值也必须填 string(27) "{"errcode":0,"errmsg":"ok"}" 第五步:登录微信公众号,查看上面创建自定义菜单的效果 |
(3)index完整版+update完整版
第七步:引入Thinkphp5框架 此处测试的微信sdk有些问题 建议看tp3下的测试
(1)登录TP官网
用户名:*******
密 码:********
(2)下载Thinkphp5框架,解压并改名tp5
(3)微信公众平台API接口扩展包
Com放入D:\phpStudy\WWW\tp5\extend文件下
(4)控制器调用处理
D:\phpStudy\WWW\tp5\application\index\controller\Index.php
<?php namespace app\index\controller; use Com\Wechat; use Com\WechatAuth; class Index { public function index(){ $token="zouke369189"; $wechat=new Wechat($token); $data=$wechat->request(); if($data && is_array($data)){ switch($data['MsgType']){ case "text": $this->Text($wechat,$data); } } } //回复文本消息 private function Text($wechat,$data){ if(strstr($data['Content'],"文本")){ $text="我正在使用Thinkphp开发微信"; $this->logger("发送文本消息:\n".$text); $wechat->replyText($text); } } //写日志 private function logger($content){ $logSize=100000; $log="log.txt"; if(file_exists($log) && fileSize($log) >$logSize){ unlink($log); } file_put_contents($log,date('H:I:S')." ".$content."\n",FILE_APPEND); } } D:\phpStudy\WWW\tp5\application\config.php |
(5)上传tp5到新浪云服务器上
(6)修改测试微信公众号的配置信息
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
URL:http://1.zouke1220.applinzi.com/index20170313/index.php
Token:zouke1220
第七步:引入Thinkphp3框架
(1)下载Thinkphp3框架,解压并改名tp3
(2)下载微信sdk
(3)将sdk解压放到D:\phpStudy\WWW\wechat\tp3\ThinkPHP\Library\Com
(4)访问http://localhost:8071/wechat/tp3/index.php/Home/Index
(5)花生壳映射域名到公网
① 登录
用户名:*******
密 码:********
② 实名认证
③ 添加映射
④ 访问将localhost:8071换成zouke1220.oicp.net进行访问
http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Index
(6)微信测试号申请
https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
(7)网页授权获取用户基本信息
https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
注意:前面不要加http://
//网页授权获取用户基本信息 public function webUsers(){ $appid="wx031a699ff141a51a"; $appSecret="6b68c41860ba3276a729986bbe5e3cc1"; $WechatAuth=new WechatAuth($appid,$appSecret); if($_GET['iscode']){ $url="http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Index/webUsers"; $result=$WechatAuth->getRequestCodeURL($url); echo $result; } } |
打开:微信web开发者工具,输入下面的网址
访问:http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Index/webUsers/iscode/1
返回:
//网页授权获取用户基本信息 public function webUsers(){ $appid="wx031a699ff141a51a"; $appSecret="6b68c41860ba3276a729986bbe5e3cc1"; $WechatAuth=new WechatAuth($appid,$appSecret); if($_GET['iscode']){ $url="http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Index/webUsers"; $result=$WechatAuth->getRequestCodeURL($url); header("Location:{$result}"); } } |
再次访问:http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Index/webUsers/iscode/1
返回:
创建数据库tp3_wechat和表users:
配置数据库:D:\phpStudy\WWW\wechat\tp3\Application\Home\Conf\config.php
<?php return array( 'URL_MODEL' => 2, 'DB_TYPE' => 'mysql', // 数据库类型 'DB_HOST' => 'localhost', // 服务器地址 'DB_NAME' => 'tp3_wechat', // 数据库名 'DB_USER' => 'root', // 用户名 'DB_PWD' => 'root', // 密码 ); |
登录后获取用户信息
//网页授权获取用户基本信息 public function webUsers(){ $appid="wx031a699ff141a51a"; $appSecret="6b68c41860ba3276a729986bbe5e3cc1"; $WechatAuth=new WechatAuth($appid,$appSecret); if($_GET['iscode']){ $url="http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Index/webUsers"; $result=$WechatAuth->getRequestCodeURL($url); //echo $result; header("Location:{$result}"); }else if($_GET['code']){ header('Content-type:text/html;charset=utf-8'); $user=$WechatAuth->getAccessToken('code',$_GET['code']); //var_dump($user); /*************************** ***************************/ $openid=$user['openid']; $users=$WechatAuth->getUserInfo($openid); //var_dump($users); /*************************** ***************************/ //将获取的用户信息插入数据库 $m=M('users'); $data['openid']=$users['openid']; $data['nickname']=$users['nickname']; $result=$m->add($data); if($result){ $text="你的openid是:".$users['openid']."\n你的昵称是:".$users['nickname']."\n 你的性别是:".$users['sex']."\n你的城市是:".$users['city']."\n你所在国家是".$users['country']."\n 你在的省份是:".$users['province']; echo $text; } } } |
点击确认登录:跳转到下面地址
(8)用户分组接口的使用
1.效率
2.token有效期:2小时
3.调用限制:
4.缓存token
<?php namespace Home\Controller; use Think\Controller; use Com\Wechat; use Com\WechatAuth; class UserController extends Controller { private $appid="wx031a699ff141a51a"; private $appSecret="6b68c41860ba3276a729986bbe5e3cc1"; //初始化WechatAuth类 private $WechatAuth=""; //缓存token private $accsess_token=""; public function __construct(){ parent::__construct(); if(!session('token')){ //初始化WechatAuth类 $this->WechatAuth=new WechatAuth($this->appid,$this->appSecret); $WechatAuth=$this->WechatAuth; $token=$WechatAuth->getAccessToken(); //设置过期时间 session(array('expire'=>$token['expires_in'])); //缓存token session('token',$token['accsess_token']); $this->accsess_token=$token; }else{ $token=session('token'); //初始化WechatAuth类 $this->WechatAuth=new WechatAuth($this->appid,$this->appSecret,$token); //缓存token $this->accsess_token=$token; } } //获取所有用户组 public function selectGroupsGet(){ header('Content-type:text/html;charset=utf-8;'); $WechatAuth=$this->WechatAuth; $data=$WechatAuth->groupsGet(); var_dump($data); } http://zouke1220.oicp.net/wechat/tp3/index.php/Home/User/selectGroupsGet //创建一个分组 public function createGroup(){ $WechatAuth=$this->WechatAuth; $data=$WechatAuth->groupsCreate('我的分组'); var_dump($data); } http://zouke1220.oicp.net/wechat/tp3/index.php/Home/User/createGroup //查询一下指定用户的分组 public function GroupId(){ $m=M('users'); $user=$m->find(3); $openid=$user['openid']; $WechatAuth=$this->WechatAuth; $data=$WechatAuth->groupsGetid($openid); var_dump($data); } http://zouke1220.oicp.net/wechat/tp3/index.php/Home/User/GroupId } |
(9)群发消息接口的使用
由于sdk中未封装该方法,所以需要自己写。
D:\phpStudy\WWW\wechat\tp3\ThinkPHP\Library\Com\WechatAuth.class.php
/** *预览群发消息接口 */ public function messageMass($msgtype,$openid,$content){ $data=array( 'touser'=>$openid, $msgtype=>array("content"=>$content), 'msgtype'=>$msgtype ); //echo json_encode($data); /******************************************** { "touser":"o_SDJ021hERjCHETOxO4j8KWWhdg", "text":{"content":"\u4f60\u597d\uff0c\u6211\u5728\u9884\u89c8\u7fa4\u53d1\u6d88\u606f"}, "msgtype":"text" } *******************************************/ return $this->api("message/mass/preview",$data); } |
D:\phpStudy\WWW\wechat\tp3\Application\Home\Controller\MassController.class.php
<?php namespace Home\Controller; use Think\Controller; use Com\Wechat; use Com\WechatAuth; //群发消息接口的使用 class MassController extends Controller { private $appid="wx031a699ff141a51a"; private $appSecret="6b68c41860ba3276a729986bbe5e3cc1"; //初始化WechatAuth类 private $WechatAuth=""; //缓存token private $accsess_token=""; public function __construct(){ parent::__construct(); if(!session('token')){ //初始化WechatAuth类 $this->WechatAuth=new WechatAuth($this->appid,$this->appSecret); $WechatAuth=$this->WechatAuth; $token=$WechatAuth->getAccessToken(); //设置过期时间 session(array('expire'=>$token['expires_in'])); //缓存token session('token',$token['accsess_token']); $this->accsess_token=$token; }else{ $token=session('token'); //初始化WechatAuth类 $this->WechatAuth=new WechatAuth($this->appid,$this->appSecret,$token); //缓存token $this->accsess_token=$token; } } //预览群发消息 public function Send(){ header('Content-type:text/html;charset=utf-8;'); $WechatAuth=$this->WechatAuth; $msgtype="text"; $openid="o_SDJ021hERjCHETOxO4j8KWWhdg"; $content="你好,我在预览群发消息"; $arr=$WechatAuth->messageMass($msgtype,$openid,$content); var_dump($arr); } http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Mass/Send /** * 群发接口 * @param string $name API名称 * @param string $data POST请求数据 * @param string $method 请求方式 * @param string $param GET请求参数 * @return array api返回结果 */ public function sendAllMessage(){ $WechatAuth=$this->WechatAuth; $group_id=null; $msgtype='text'; $content="zz"; $data=array( 'filter'=>array('is_to_all'=>true,'group_id'=>$group_id), $msgtype=>array('content'=>$content), 'msgtype'=>$msgtype ); $arr=$WechatAuth->api("message/mass/sendall",$data); var_dump($arr); } } |
(10)生成带参数的二维码
<?php namespace Home\Controller; use Think\Controller; use Com\Wechat; use Com\WechatAuth; //创建二维码接口的使用 class UrlController extends Controller { private $appid="wx031a699ff141a51a"; private $appSecret="6b68c41860ba3276a729986bbe5e3cc1"; //初始化WechatAuth类 private $WechatAuth=""; //缓存token private $accsess_token=""; public function __construct(){ parent::__construct(); if(!session('token')){ //初始化WechatAuth类 $this->WechatAuth=new WechatAuth($this->appid,$this->appSecret); $WechatAuth=$this->WechatAuth; $token=$WechatAuth->getAccessToken(); //设置过期时间 session(array('expire'=>$token['expires_in'])); //缓存token session('token',$token['accsess_token']); $this->accsess_token=$token; }else{ $token=session('token'); //初始化WechatAuth类 $this->WechatAuth=new WechatAuth($this->appid,$this->appSecret,$token); //缓存token $this->accsess_token=$token; } } /** * 创建二维码,可创建指定有效期的二维码和永久二维码 * @param integer $scene_id 二维码参数 * @param integer $expire_seconds 二维码有效期,0-永久有效 */ //http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Url/CreateCode public function CreateCode(){ $WechatAuth=$this->WechatAuth; $ticket=$WechatAuth->qrcodeCreate("10086"); //var_dump($src); //var_dump($src); //string(147) "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQHU8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyc3FuSWRrWndmOWoxMDAwMDAwM24AAgRuxpJZAwQAAAAA" echo "<img width='70%' src='https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQHU8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyc3FuSWRrWndmOWoxMDAwMDAwM24AAgRuxpJZAwQAAAAA" />'; //长链接转短链接 接(10) public function Short(){ $WechatAuth=$this->WechatAuth; $url=$WechatAuth->shortUrl("http://pan.baidu.com/disk/home?errno=0&errmsg=Auth%20Login%20Sucess&&bduss=&ssnerror=0#list/path=%2F&vmode=list"); var_dump($url); } /******************************** array(3) { ["errcode"]=> int(0) ["errmsg"]=> string(2) "ok" ["short_url"]=> string(26) "https://w.url.cn/s/AhZBsc8" } ***********************/ } } |
(11)微信js-sdk的使用
微信-公众平台-企业号开发者中心:
http://qydev.weixin.qq.com/wiki/index.php?title=%CE%A2%D0%C5JS-SDK%BD%D3%BF%DA
微信js-sdk说明文档:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
① 下载js-sdk
② 打开sdk文件下的jssdk.php文件,复制getSignPackage、createNonceStr、httpGet、getJsApiTicket 4个方法,并改造getSignPackage、getJsApiTicket方法将getJsApiTicket下的代码放入__construct,并删除getJsApiTicket方法
D:\phpStudy\WWW\wechat\tp3\Application\Home\Controller\SdkController.class.php
<?php namespace Home\Controller; use Think\Controller; use Com\Wechat; use Com\WechatAuth; //微信js-sdk的使用 class SdkController extends Controller { private $appid="wx031a699ff141a51a"; private $appSecret="6b68c41860ba3276a729986bbe5e3cc1"; //初始化WechatAuth类 private $WechatAuth=""; //缓存token private $access_token=""; //缓存jsapi_ticket private $jsapi_ticket=""; public function __construct(){ parent::__construct(); if(!session('token')){ //初始化WechatAuth类 $this->WechatAuth=new WechatAuth($this->appid,$this->appSecret); $WechatAuth=$this->WechatAuth; $token=$WechatAuth->getAccessToken(); //设置过期时间 session(array('expire'=>$token['expires_in'])); //缓存token session('token',$token['access_token']); $this->access_token=$token['access_token']; }else{ $token=session('token'); //初始化WechatAuth类 $this->WechatAuth=new WechatAuth($this->appid,$this->appSecret,$token); //缓存token $this->access_token=$token; } // jsapi_ticket 应该全局存储与更新 if (!session('jsapi_ticket')) { $accessToken = $this->access_token; // 如果是企业号用以下 URL 获取 ticket // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken"; $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken"; $res = json_decode($this->httpGet($url)); $this->jsapi_ticket=$res->ticket; //设置过期时间 session(array('expire'=>7000)); session('jsapi_ticket',$this->jsapi_ticket); } else { $this->jsapi_ticket = session('jsapi_ticket'); } } //http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Sdk/index public function index(){ $data=$this->getSignPackage(); //var_dump($data); /******************************* array(6) { ["appId"]=> string(18) "wx031a699ff141a51a" ["nonceStr"]=> string(16) "mJ0NRQYoQkplFazN" ["timestamp"]=> int(1502868681) ["url"]=> string(61) "http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Sdk/index" ["signature"]=> string(40) "0a49a3088a29abb98126cf76020f790c2dbc7759" ["rawString"]=> string(126) "jsapi_ticket=&noncestr=mJ0NRQYoQkplFazN×tamp=1502868681&url=http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Sdk/index" } *******************************/ $this->assign('data',$data); $this->display(); } public function getSignPackage() { $jsapiTicket = $this->jsapi_ticket; // 注意 URL 一定要动态获取,不能 hardcode. $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; $timestamp = time(); $nonceStr = $this->createNonceStr(); // 这里参数的顺序要按照 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; } private function createNonceStr($length = 16) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } private function httpGet($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_TIMEOUT, 500); // 为保证第三方服务器与微信服务器之间数据传输的安全性,所有微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。 // 如果在部署过程中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true); curl_setopt($curl, CURLOPT_URL, $url); $res = curl_exec($curl); curl_close($curl); return $res; } } |
D:\phpStudy\WWW\wechat\tp3\Application\Home\View\Sdk\index.html
<html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> </body> <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script> /* * 注意: * 1. 所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。 * 2. 如果发现在 Android 不能分享自定义内容,请到官网下载最新的包覆盖安装,Android 自定义分享接口需升级至 6.0.2.58 版本及以上。 * 3. 常见问题及完整 JS-SDK 文档地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html * * 开发中遇到问题详见文档“附录5-常见错误及解决办法”解决,如仍未能解决可通过以下渠道反馈: * 邮箱地址:weixin-open@qq.com * 邮件主题:【微信JS-SDK反馈】具体问题 * 邮件内容说明:用简明的语言描述问题所在,并交代清楚遇到该问题的场景,可附上截屏图片,微信团队会尽快处理你的反馈。 */ wx.config({ debug: true, appId: '<?php echo $data["appId"];?>', timestamp: <?php echo $data["timestamp"];?>, nonceStr: '<?php echo $data["nonceStr"];?>', signature: '<?php echo $data["signature"];?>', jsApiList: [ // 所有要调用的 API 都要加到这个列表中 'checkJsApi' ] }); wx.ready(function () { // 在这里调用 API //https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 // 判断当前客户端版本是否支持指定JS接口 wx.checkJsApi({ jsApiList: ['chooseImage'], // 需要检测的JS接口列表,所有JS接口列表见附录2, success: function(res) { // 以键值对的形式返回,可用的api值true,不可用为false // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"} } }); }); </script> </html> |
③ 图像接口和扫一扫接口的使用
<html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <button id="btn1" style="width:80%;height:300px;font-size:100px;background:green;">图像接口的使用</button> <button id="btn2" style="width:80%;height:300px;font-size:100px;background:green;">扫一扫接口的使用</button> </body> <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script> /* * 注意: * 1. 所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。 * 2. 如果发现在 Android 不能分享自定义内容,请到官网下载最新的包覆盖安装,Android 自定义分享接口需升级至 6.0.2.58 版本及以上。 * 3. 常见问题及完整 JS-SDK 文档地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html * * 开发中遇到问题详见文档“附录5-常见错误及解决办法”解决,如仍未能解决可通过以下渠道反馈: * 邮箱地址:weixin-open@qq.com * 邮件主题:【微信JS-SDK反馈】具体问题 * 邮件内容说明:用简明的语言描述问题所在,并交代清楚遇到该问题的场景,可附上截屏图片,微信团队会尽快处理你的反馈。 */ wx.config({ debug: true, appId: '<?php echo $data["appId"];?>', timestamp: <?php echo $data["timestamp"];?>, nonceStr: '<?php echo $data["nonceStr"];?>', signature: '<?php echo $data["signature"];?>', jsApiList: [ // 所有要调用的 API 都要加到这个列表中 'checkJsApi', 'chooseImage', 'scanQRCode' ] }); var bnt1=document.getElementById("btn1"); bnt1.onclick=function(){ wx.chooseImage({ count: 1, // 默认9 sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有 sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有 success: function (res) { var localIds = res.localIds; // document.write("<img src="+localIds+">"); } }); } var bnt2=document.getElementById('btn2'); bnt2.onclick=function(){ wx.scanQRCode({ needResult: 0, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果, scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有 success: function (res) { var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果 } }); } wx.ready(function () { // 在这里调用 API // 判断当前客户端版本是否支持指定JS接口 wx.checkJsApi({ jsApiList: ['chooseImage'], // 需要检测的JS接口列表,所有JS接口列表见附录2, success: function(res) { // 以键值对的形式返回,可用的api值true,不可用为false // 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"} } }); }); </script> </html> |
微信中访问链接:
http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Sdk/index
首先出现 然后出现 当点击扫一扫或图像接口出现
解决方法:
打开微信测试号申请页面:
https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
将以下域名
修改为:
微信中再次访问链接:
http://zouke1220.oicp.net/wechat/tp3/index.php/Home/Sdk/index
首先出现 然后出现
点击图像接口的使用 点击扫一扫接口的使用
④ 微信js-sdk完整版demo
⑤ 微信支付接口的使用
a.微信公众平台文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115
b.微信支付开发文档:https://pay.weixin.qq.com/wiki/doc/api/index.html
c.下载微信支付DEMO
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
d.解压并改名为WxPay放到项目中
e.公众号支付:
配置支付授权访问目录
下载证书并将下载下来的证书放到D:\phpStudy\WWW\wechat\tp3\WxPay\cert目录下
配置支付信息
打开D:\phpStudy\WWW\wechat\tp3\WxPay\lib\WxPay.Config.php文件
配置以下几个参数:
说明:由于测试号没有开放微信支付的接口功能,所以此处的配置信息是拷贝公司原来项目GalmarSystem中F:\项目\GalmarSystem\Com.WeiPay\PayConfig.cs的相关微信配置
修改index.php文件中的访问路径
D:\phpStudy\WWW\wechat\tp3\WxPay\index.php
微信中访问:http://zouke1220.oicp.net/wechat/tp3/WxPay/index.php
f.扫码支付:
https://pay.weixin.qq.com/wiki/doc/api/index.html
授权回调访问路径
(12)微信商城
① 前台模板引入
a.引入微信商城模板的css+js+Images+img+bootstrap
b.引入微商城的首页index.html及详情页detail.html页面模板
注意:修改js/css/image等的引入路径
c.控制器添加显示页面的方法
D:\phpStudy\WWW\wechat\tp3\Application\Shop\Controller\IndexController.class.php
d.访问控制器中的方法查看显示效果
http://zouke1220.oicp.net/wechat/tp3/index.php/Shop/Index/index
http://zouke1220.oicp.net/wechat/tp3/index.php/Shop/Index/detail
② 后台模板引入(注意修改bootstrap的引入路径)
a.添加
² 引入产品添加页面
² 后台控制器添加方法
//显示添加商品页面 public function add(){ $this->display(); } |
² 访问控制器中的方法,查看显示效果
http://zouke1220.oicp.net/wechat/tp3/index.php/Shop/Admin/add
² 添加商品+图片上传
注意:配置好数据库连接D:\phpStudy\WWW\wechat\tp3\Application\Shop\Conf\config.php
//添加商品+图片上传 public function addgoods(){ //var_dump($_POST);exit; header("Content-type:text/html;charset=utf-8"); $m=M('goods'); $upload = new \Think\Upload();// 实例化上传类 $upload->maxSize =3145728 ; // 设置附件上传大小 $upload->exts =array('jpg', 'gif', 'png', 'jpeg'); // 设置附件上传类型 $upload->rootPath ='./Public/Uploads/'; // 设置附件上传目录 $info = $upload->upload(); // 上传文件 if(!$info) {// 上传错误提示错误信息 echo '<script type="text/javascript">alert("上传图片失败");</script>'; exit; }else{ // 上传成功 $_POST['img']=$info['img']['savepath'].$info['img']['savename']; //var_dump($_POST); /* array(4) { ["name"]=> string(3) "222" ["price"]=> string(3) "222" ["pex"]=> string(4) "A类" ["img"]=> string(28) "2017-08-17/59952ffbea896.png" } */ $arr=$m->add($_POST); if($arr){ echo '<script type="text/javascript">alert("添加成功");</script>'; }else{ echo '<script type="text/javascript">alert("添加失败");</script>'; } } } |
b.列表
² 引入展品列表显示页面
² 后台控制器列表方法
//商品列表页 public function lists(){ $m=M('goods'); $data=$m->select(); $this->assign("data",$data); $this->display(); } |
² 访问控制器中的方法,查看显示效果
http://zouke1220.oicp.net/wechat/tp3/index.php/Shop/Admin/lists
c.删除
² 后台控制器列表方法
//删除商品 public function del(){ header("Content-type:text/html;charset=utf-8"); $id=$_GET['id']; $m=M('goods'); $res=$m->delete($id); if($res){ echo '<script>alert("删除成功");history.go(-1);</script>'; }else{ echo '<script>alert("删除失败");history.go(-1);</script>'; } } |
² 点击删除按钮
③ 前台数据展示
a.控制器取数据
//首页 public function index(){ $m=M('goods'); $data=$m->select(); $this->assign('data',$data); $this->display(); } //详情页 public function detail(){ $m=M('goods'); $data=$m->find($_GET['id']); $this->assign('data',$data); $this->display(); } //订单页 public function order(){ $this->assign('data',$_POST); $this->display(); } |
b.页面展示
D:\phpStudy\WWW\wechat\tp3\Application\Shop\View\Index\index.html
http://zouke1220.oicp.net/wechat/tp3/index.php/Shop/Index/index
D:\phpStudy\WWW\wechat\tp3\Application\Shop\View\Index\detail.html
http://zouke1220.oicp.net/wechat/tp3/Shop/Index/detail/id/2.html
D:\phpStudy\WWW\wechat\tp3\Application\Shop\View\Index\order.html
http://zouke1220.oicp.net/wechat/tp3/Shop/Index/order.html
将wechat\选择城市插件文件下的js文件拷贝到D:\phpStudy\WWW\wechat\tp3\Public\js下
将wechat\选择城市插件文件下的css文件拷贝到D:\phpStudy\WWW\wechat\tp3\Public\css下
订单页面order.html引入刚才的css文件:area.css和js文件:area.js、jquery-3.2.1.js
访问查看效果
c.写入订单到数据库
//写入订单到数据库 public function addOrder(){ header('Content-type:text/html;charset=utf-8'); $data['gid']=$_POST['id']; $data['name']=$_POST['name']; $data['price']=$_POST['price']*$_POST['num']; $data['num']=$_POST['num']; $data['email']=$_POST['email']; $data['mobile']=$_POST['mobile']; $data['city']=$_POST['city']; $data['detail']=$_POST['detail']; $m=M('orders'); $res=$m->add($data); if($res){ echo '<script>alert("生成订单成功");history.go(-2)</script>'; }else{ echo '<script>alert("生成订单失败");history.go(-1)</script>'; } } |
④ 微信支付
同步:同步执行或跳转
异步:不管用户是否点击完成或跳转,微信服务器都会向我们的服务器推送数据
如果指定推送数据的地址:如果微信服务器没有收到返回参数,会一直向你的服务器推送数据,8次。
a.修改写订单方法
//写入订单到数据库 public function addOrder(){ header('Content-type:text/html;charset=utf-8'); //未支付成功 缓存订单数据 if(empty($_GET['isnull'])){ //去支付 header('Location:http://zouke1220.oicp.net/wechat/tp3/WxPay/example/jsapi.php'); //缓存订单数据 $data['gid']=$_POST['id']; $data['name']=$_POST['name']; $data['username']=$_POST['username']; $data['pirce']=$_POST['pirce']*$_POST['num']; $data['num']=$_POST['num']; $data['email']=$_POST['email']; $data['mobile']=$_POST['mobile']; $data['city']=$_POST['city']; $data['detail']=$_POST['detail']; session('data',$data); }else{ //支付成功 插入订单数据 $m=M('order'); $res=$m->add(session('data')); if($res){ echo '<script>alert("生成订单成功"); location.href="http://zouke1220.oicp.net/wechat/tp3/Shop/Index";</script>'; }else{ echo '<script>alert("生成订单失败");history.go(-2)</script>'; } } } |
- b.修改jsapi.php
D:\phpStudy\WWW\wechat\tp3\WxPay\example\jsapi.php
<?php /******************新增开始**********************/ session_start(); header('Content-type:text/html;charset=utf-8'); /******************新增结束**********************/ ini_set('date.timezone','Asia/Shanghai'); //error_reporting(E_ERROR); require_once "../lib/WxPay.Api.php"; require_once "WxPay.JsApiPay.php"; require_once 'log.php'; //初始化日志 $logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log'); $log = Log::Init($logHandler, 15); //打印输出数组信息 /***********注释开始******************** function printf_info($data) { foreach($data as $key=>$value){ echo "<font color='#00ff55;'>$key</font> : $value <br/>"; } } ************注释结束*******************/ //①、获取用户openid $tools = new JsApiPay(); $openId = $tools->GetOpenid(); //②、统一下单 $input = new WxPayUnifiedOrder(); $input->SetBody($_SESSION['data']['name']); //动态获取 $input->SetAttach($_SESSION['data']['name']); //动态获取 $input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis")); $input->SetTotal_fee($_SESSION['data']['price']); //动态获取 $input->SetTime_start(date("YmdHis")); $input->SetTime_expire(date("YmdHis", time() + 600)); $input->SetGoods_tag("test"); $input->SetNotify_url("http://zouke1220.oicp.net/wechat/tp3/WxPay/example/notify.php"); //异步回调 $input->SetTrade_type("JSAPI"); $input->SetOpenid($openId); $order = WxPayApi::unifiedOrder($input); /**************注释开始********************* echo '<font color="#f00"><b>统一下单支付单信息</b></font><br/>'; printf_info($order); ***************注释结束********************/ $jsApiParameters = $tools->GetJsApiParameters($order); //获取共享收货地址js函数参数 $editAddress = $tools->GetEditAddressParameters(); //③、在支持成功回调通知中处理成功之后的事宜,见 notify.php /** * 注意: * 1、当你的回调地址不可访问的时候,回调通知会失败,可以通过查询订单来确认支付是否成功 * 2、jsapi支付时需要填入用户openid,WxPay.JsApiPay.php中有获取openid流程 (文档可以参考微信公众平台“网页授权接口”, * 参考http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html) */ ?> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>微信支付样例-支付</title> <script type="text/javascript"> //调用微信JS api 支付 function jsApiCall() { WeixinJSBridge.invoke( 'getBrandWCPayRequest', <?php echo $jsApiParameters; ?>, function(res){ /**************注释开始**************** WeixinJSBridge.log(res.err_msg); alert(res.err_code+res.err_desc+res.err_msg); ***************注释结束***************/ /**************新增开始***********************/ if(res.err.msg == "get_brand_wcpay_request:ok"){ alert('支付成功'); location.href="http://zouke1220.oicp.net/wechat/tp3/Shop/Index/addOrder/isnull/1"; }else{ alert('支付失败'); location.href="http://zouke1220.oicp.net/wechat/tp3/Shop/Index/detail/id/<?php echo $_SESSION['data']['gid'];?>"; } /***************新增结束***********************/ } ); } function callpay() { if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall); } }else{ jsApiCall(); } } </script> <script type="text/javascript"> //获取共享地址 /**************注释开始************************* function editAddress() { WeixinJSBridge.invoke( 'editAddress', <?php echo $editAddress; ?>, function(res){ var value1 = res.proviceFirstStageName; var value2 = res.addressCitySecondStageName; var value3 = res.addressCountiesThirdStageName; var value4 = res.addressDetailInfo; var tel = res.telNumber; alert(value1 + value2 + value3 + value4 + ":" + tel); } ); } window.onload = function(){ if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', editAddress, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', editAddress); document.attachEvent('onWeixinJSBridgeReady', editAddress); } }else{ editAddress(); } }; *****************注释结束************************/ </script> </head> <body> <!----------------------------注释开始---------------------------------------- <br/> <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px">1分</span>钱</b></font><br/><br/> <div align="center"> <button style="width:210px; height:50px; border-radius: 15px; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" >立即支付</button> </div> ------------------------------注释结束---------------------------------------> </body> </html> |
说明:
微信支付测试号暂时还测试不了,有兴趣可以参考
http://download.csdn.net/download/gcfranklin/8362257
http://www.cnblogs.com/txw1958/p/wxpayv3-jsapi.html
http://blog.csdn.net/u014033756/article/details/52038114
http://www.cnblogs.com/txw1958/p/wxpayv3-signkey.html
另外:选择order.html表单中的收获地址城市插件调用不了,有时间可以再调
php 微信公众号+微商城开发 基于Thinkphp3.2框架开发的更多相关文章
-
上篇: php 微信公众号 基于Thinkphp3.2框架开发
说明:本教程是自己自学+自己的理解+扩展(包括学习过程中遇到的一些问题) 参考教程:麦子学院--李忠益--http://www.maiziedu.com/u/70409/ 微盟: http://www ...
-
微信公众号与HTML 5混合模式揭秘5——JSSDK开发技巧1
微信公众号与HTML 5混合模式揭秘1——如何部署JSSDK 微信公众号与HTML 5混合模式揭秘2——分享手机相册中照片 微信公众号与HTML 5混合模式揭秘3——JSSDK获取地理位置 微信公众号 ...
-
下篇: php 微商城 基于Thinkphp3.2框架开发
(12)微信商城 ① 前台模板引入 a.引入微信商城模板的css+js+Images+img+bootstrap b.引入微商城的首页index.html及详情页detail.html页面模板 注意: ...
-
微信公众号开发系列-13、基于RDIFramework.NET框架整合微信开发应用效果展示
1.前言 通过前面一系列文章的学习,我们对微信公众号开发已经有了一个比较深入和全面的了解. 微信公众号开发为企业解决那些问题呢? 我们经常看到微信公众号定制开发.微信公众平台定制开发,都不知道这些能给 ...
-
NodeJs 开发微信公众号(一)准备工作
前言 大概是一个月前,自己用业余时间做了一个微信公众号.微信开发,尤其是对后台不熟悉的人来说显得尤其困难.首先要克服的是后台语言(nodejs)的一些不熟悉困难,其次,也是最大的一点困难是在跟微信交互 ...
-
Java开发微信公众号(五)---微信开发中如何获取access_token以及缓存access_token
获取access_token是微信api最重要的一个部分,因为调用其他api很多都需要用到access_token.比如自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等在请求的时候 ...
-
Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理
在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...
-
Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装
在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装. ( ...
-
Java开发微信公众号(二)---开启开发者模式,接入微信公众平台开发
接入微信公众平台开发,开发者需要按照如下步骤完成: 1.填写服务器配置 2.验证服务器地址的有效性 3.依据接口文档实现业务逻辑 资料准备: 1.一个可以访问的外网,即80的访问端口,因为微信公众号接 ...
随机推荐
-
NET开发学习项目资源
最近在整理资料时发现自己当初学习NET的一些项目资源,一直放在硬盘里不如拿来分享给初学者学习还是不错的. 项目代码为<精通ASP.NET20+SQL Server2005项目开发>书中源码 ...
-
移动web开发—页面头部 META 总结
meta指元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词. 标签位于文档的头部,不包含任何内容. 标签的属性定义了与文档相关联的名称/值对. ...
-
【转】linux shell实现随机数多种方法(date,random,uuid)
在日常生活中,随机数实际上经常遇到,想丢骰子,抓阄,还有抽签.呵呵,非常简单就可以实现.那么在做程序设计,真的要通过自己程序设计出随机数那还真的不简单了.现在很多都是操作系统内核会提供相应的api,这 ...
-
分布式服务框架Zookeeper
协议介绍 zookeeper协议分为两种模式 崩溃恢复模式和消息广播模式 崩溃恢复协议是在集群中所选举的leader 宕机或者关闭 等现象出现 follower重新进行选举出新的leader 同时集群 ...
-
【leetcode】Bitwise AND of Numbers Range(middle)
Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND of all numbers ...
-
通过UIImagePickerController完成照相和相片的选取
UIImagePickerController是用于选取现有照片,或者用照相机现场照一张相片使用的 定义: @interface ShowViewController : UIViewControll ...
-
javascript variables 变量
一,调试方法: 1.document.write(); 直接在网页中显示. 2.alert(); 弹窗显示. 3.console. ...
-
xml与json的原理,区别,优缺点.
1.定义介绍 (1).XML定义扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许 ...
-
RSA加密算法验证(C#实现)
RSA算法简单原理介绍(节选于网络) 假设Alice想要通过一个不可靠的媒体接收Bob的一条私人讯息.她可以用以下的方式来产生一个公钥和一个私钥: 随意选择两个大的质数p和q,p不等于q,计算N=pq ...
-
webpack构建项目
webpack构建项目 案例代码戳这里 ps:每个案例对应相应的demo,例如"案例1"对应"demo1" 一.webpack基本功能及简单案例 安装webpa ...