博客列表 >ThinkPHP5 微信接口对接公共类

ThinkPHP5 微信接口对接公共类

弘德誉曦的博客
弘德誉曦的博客原创
2021年07月14日 10:32:57549浏览
  1. <?php
  2. // .-----------------------------------------------------------------------------------
  3. // | Software: [wechat framework]
  4. // | Version: 2017.7
  5. // | Site:
  6. // |-----------------------------------------------------------------------------------
  7. // | Author: bug <3164145970@qq.com>
  8. // | Copyright (c) 2017, . All Rights Reserved.
  9. // |-----------------------------------------------------------------------------------
  10. /**
  11. * 基于thinkphp5的微信自定义接口开发
  12. * @package wechat
  13. * @author bug <3164145970@qq.com>
  14. * @createtime 2017-07-26 10:48:30
  15. * @description
  16. */
  17. // |-----------------------------------------------------------------------------------
  18. namespace util;
  19. use think\Exception;
  20. /**
  21. * 微信公共类文件
  22. * @package util
  23. * @author bug <3164145970@qq.com>
  24. * @createtime 2017-07-26 11:10:14
  25. *
  26. */
  27. class WeChat
  28. {
  29. /**********************基础配置 开始********/
  30. /**
  31. * 微信公众号AppId
  32. * @var string
  33. */
  34. private $appid;
  35. /**
  36. * 微信公众号AppSecret
  37. * @var string
  38. */
  39. private $appsecret;
  40. /**
  41. * 微信公众号验证服务器token
  42. * @var string
  43. */
  44. private $token;
  45. /**
  46. * 微信公众号EncodingAESKey
  47. * @var string
  48. */
  49. private $encoding_aeskey;
  50. /**
  51. * 微信公众号商户号
  52. * @var string
  53. */
  54. private $mch_id;
  55. /**
  56. * 微信公众号商户支付密钥
  57. * @var string
  58. */
  59. private $key;
  60. //=======【证书路径设置】=====================================
  61. /**
  62. * TODO:设置商户证书路径
  63. * 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,
  64. * API证书下载地址:https://pay.weixin.qq.com/index.php/account/api_cert,下载之前需要安装商户操作证书)
  65. * @var path
  66. */
  67. const SSLCERT_PATH = "\cert\apiclient_cert.pem";
  68. const SSLKEY_PATH = "\cert\apiclient_key.pem";
  69. //=======【curl代理设置】===================================
  70. /**
  71. * TODO:这里设置代理机器,只有需要代理的时候才设置,不需要代理,请设置为0.0.0.0和0
  72. * 本例程通过curl使用HTTP POST方法,此处可修改代理服务器,
  73. * 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0,此时不开启代理(如有需要才设置)
  74. * @var unknown_type
  75. */
  76. const CURL_PROXY_HOST = "0.0.0.0";//"10.152.18.220";
  77. const CURL_PROXY_PORT = 0;//8080;
  78. //=======【上报信息配置】===================================
  79. /**
  80. * TODO:接口调用上报等级,默认紧错误上报(注意:上报超时间为【1s】,上报无论成败【永不抛出异常】,
  81. * 不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少
  82. * 开启错误上报。
  83. * 上报等级,0.关闭上报; 1.仅错误出错上报; 2.全量上报
  84. * @var int
  85. */
  86. const REPORT_LEVENL = 1;
  87. /**
  88. * 微信公共类构造方法
  89. * @author bug <3164145970@qq.com>
  90. * @createtime 2017-07-26 11:10:14
  91. * @param string $appid 微信公众号AppId
  92. * @param string $appsecret 微信公众号AppSecret
  93. * @param string $token 微信公众号验证服务器token
  94. * @param string $encoding_aeskey 微信公众号EncodingAESKey
  95. * @param string $mch_id 微信公众号商户号
  96. * @param string $key 微信公众号商户支付密钥
  97. */
  98. public function __construct(){
  99. $this->appid = config('crm_config.wechat_appid');//获取配置文件中的微信公众号AppId
  100. $this->appsecret = config('crm_config.wechat_secret');//获取配置文件中的微信公众号AppSecret
  101. $this->token = config('crm_config.token');//获取配置文件中的微信公众号验证服务器token
  102. $this->encoding_aeskey = config('crm_config.encoding_aeskey');//获取配置文件中的微信公众号EncodingAESKey
  103. $this->mch_id = config('crm_config.wechat_mch_id');//获取配置文件中的微信公众号商户号
  104. $this->key = config('crm_config.wechat_key');//获取配置文件中的微信公众号商户支付密钥
  105. }
  106. /**********************基础配置 结束********/
  107. /**********************开始开发 开始********/
  108. /**
  109. * token验证服务器
  110. * @author bug <3164145970@qq.com>
  111. * @createtime 2017-07-26 11:10:14
  112. * @param string $nonce 随机数
  113. * @param string $timestamp 时间戳
  114. * @param string $echostr 随机字符串
  115. * @param string $signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
  116. * @return echostr参数内容或false
  117. */
  118. public function token($nonce,$timestamp,$echostr,$signature){
  119. //参数字典序排序
  120. $array = array();
  121. $array = array($nonce, $timestamp, $this->token);
  122. sort($array);
  123. //验证
  124. $str = sha1( implode( $array ) );//sha1加密
  125. //对比验证处理好的str与signature,若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
  126. if( $str == $signature && $echostr ){
  127. return $echostr;
  128. }
  129. else{
  130. return false;
  131. }
  132. }
  133. /**
  134. * 通过appid和appsecret获取access_token 或从缓存获取基础支持access_token
  135. * @author bug <3164145970@qq.com>
  136. * @createtime 2017-07-26 11:07:24
  137. * @param type true强制获取access_token,用于本地存储的access_token在微信服务器已过期,但在本地服务器未过期时
  138. * @return string 获取到的凭证
  139. */
  140. private function access_token($type){
  141. // //session开始
  142. // if(!isset($_SESSION)){
  143. // session_start();
  144. // }
  145. // //判断缓存中是否存在access_token,如果存在取出来返回
  146. // if(!$type&&isset($_SESSION['access_token'])&&$_SESSION['access_token']['endtime']>time()){
  147. // $result = array('status'=>1,'data'=>$_SESSION['access_token']['val']);
  148. // return $result;
  149. // }
  150. // //配置请求url,加入appid和appsecret参数
  151. // $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->appid.'&secret='.$this->appsecret;
  152. // //获取请求结果,并将请求结果转换成json
  153. // $data = string_json($url);
  154. // if(array_key_exists('errcode', $data)){
  155. // $result = array('status'=>40014,'data'=>$data);
  156. // return $result;
  157. // }
  158. // /**将新获取的access_token缓存到服务器 开始**/
  159. // session_set_cookie_params($data['expires_in']); //设置access_token在服务器session中缓存时间
  160. // $access_token['val'] = $data['access_token'];
  161. // $access_token['endtime'] = time()+$data['expires_in'];
  162. // $_SESSION['access_token']= $access_token;
  163. // /**将新获取的access_token缓存到服务器 结束**/
  164. // //返回结果
  165. // $result = array('status'=>2,'data'=>$data['access_token']);
  166. // return $result;
  167. // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
  168. $datas = json_decode(file_get_contents(dirname(__FILE__)."/json/access_token.json"));
  169. if (!$type && $datas->expire_time > time()) {
  170. $result = array('status'=>1,'data'=>$datas->access_token);
  171. return $result;
  172. }
  173. //配置请求url,加入appid和appsecret参数
  174. // 如果是企业号用以下URL获取access_token
  175. // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";
  176. $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->appid.'&secret='.$this->appsecret;
  177. //获取请求结果,并将请求结果转换成json
  178. $data = string_json($url);
  179. if(array_key_exists('errcode', $data)){
  180. $result = array('status'=>40014,'data'=>$data);
  181. return $result;
  182. }
  183. //将access_token 写入文件
  184. $datas->expire_time = time()+$data['expires_in'];
  185. $datas->access_token = $data['access_token'];
  186. $fp = fopen(dirname(__FILE__)."/json/access_token.json", "w");
  187. fwrite($fp, json_encode($datas));
  188. fclose($fp);
  189. //返回结果
  190. $result = array('status'=>2,'data'=>$data['access_token']);
  191. return $result;
  192. }
  193. /**
  194. * 接口调用上限清零
  195. * @author bug <3164145970@qq.com>
  196. * @createtime 2017-08-30 13:44:55
  197. * @param post_data 请求数据
  198. * @return json 请求结果
  199. */
  200. public function clear_quota(){
  201. //获取access_token
  202. $access_token= $this->access_token(false);
  203. if($access_token['status']!=1 && $access_token['status']!=2){
  204. return $access_token;
  205. }
  206. $post_data['appid'] = $this->appid;
  207. //配置请求url,加入access_token参数
  208. $url = 'https://api.weixin.qq.com/cgi-bin/clear_quota?access_token='.$access_token['data'];
  209. //将json数组转换成字符串数组
  210. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  211. //获取请求结果,并将请求结果转换成json
  212. $data = json_decode(https_request($url,$post_data),true);
  213. //access_token 过期重新获取并重新回调当前函数
  214. if($data['errcode']==42001 || $data['errcode']==40001){
  215. $access_token = $this->access_token(true);
  216. return $this->clear_quota();
  217. }
  218. //返回结果
  219. if($data['errcode']==0&&$data['errmsg']=='ok'){
  220. $result = array('status'=>1,'data'=>$data);
  221. return $result;
  222. }
  223. $result = array('status'=>40014,'data'=>$data);
  224. return $result;
  225. }
  226. /**
  227. * 获取微信服务器IP地址
  228. * @author bug <3164145970@qq.com>
  229. * @createtime 2017-07-26 13:51:20
  230. * @return json ip_list 微信服务器IP地址
  231. */
  232. public function ip_list(){
  233. //获取access_token
  234. $access_token= $this->access_token(false);
  235. if($access_token['status']!=1 && $access_token['status']!=2){
  236. return $access_token;
  237. }
  238. //配置请求url,加入access_token参数
  239. $url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token='.$access_token['data'];
  240. //获取请求结果,并将请求结果转换成json
  241. $data = string_json($url);
  242. if(array_key_exists('errcode', $data)){
  243. //access_token 过期重新获取并重新回调当前函数
  244. if($data['errcode']==42001 || $data['errcode']==40001){
  245. $access_token = $this->access_token(true);
  246. return $this->ip_list();
  247. }
  248. $result = array('status'=>40014,'data'=>$data);
  249. return $result;
  250. }
  251. //返回结果
  252. $result = array('status'=>1,'data'=>$data);
  253. return $result;
  254. }
  255. /**********************开始开发 结束********/
  256. /**********************自定义菜单 开始********/
  257. /**
  258. * 自定义菜单创建接口
  259. * @author bug <3164145970@qq.com>
  260. * @createtime 2017-07-26 14:24:40
  261. * @param post_data 请求数据
  262. * @return json 请求结果
  263. */
  264. public function create_menu($post_data){
  265. //获取access_token
  266. $access_token= $this->access_token(false);
  267. if($access_token['status']!=1 && $access_token['status']!=2){
  268. return $access_token;
  269. }
  270. //配置请求url,加入access_token参数
  271. $url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token='.$access_token['data'];
  272. //将json数组转换成字符串数组
  273. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  274. //获取请求结果,并将请求结果转换成json
  275. $data = json_decode(https_request($url,$post_data),true);
  276. //access_token 过期重新获取并重新回调当前函数
  277. if($data['errcode']==42001 || $data['errcode']==40001){
  278. $access_token = $this->access_token(true);
  279. return $this->create_menu($post_data);
  280. }
  281. //返回结果
  282. if($data['errcode']==0&&$data['errmsg']=='ok'){
  283. $result = array('status'=>1,'data'=>$data);
  284. return $result;
  285. }
  286. $result = array('status'=>40014,'data'=>$data);
  287. return $result;
  288. }
  289. /**
  290. * 自定义菜单查询接口
  291. * @author bug <3164145970@qq.com>
  292. * @createtime 2017-07-26 14:17:05
  293. * @return json 菜单列表
  294. */
  295. public function get_menu(){
  296. //获取access_token
  297. $access_token= $this->access_token(false);
  298. if($access_token['status']!=1 && $access_token['status']!=2){
  299. return $access_token;
  300. }
  301. //配置请求url,加入access_token参数
  302. $url = 'https://api.weixin.qq.com/cgi-bin/menu/get?access_token='.$access_token['data'];
  303. //获取请求结果,并将请求结果转换成json
  304. $data = string_json($url);
  305. if(array_key_exists('errcode', $data)){
  306. //access_token 过期重新获取并重新回调当前函数
  307. if($data['errcode']==42001 || $data['errcode']==40001){
  308. $access_token = $this->access_token(true);
  309. return $this->get_menu();
  310. }
  311. $result = array('status'=>40014,'data'=>$data);
  312. return $result;
  313. }
  314. //返回结果
  315. $result = array('status'=>1,'data'=>$data);
  316. return $result;
  317. }
  318. /**
  319. * 自定义菜单删除接口
  320. * @author bug <3164145970@qq.com>
  321. * @createtime 2017-07-26 14:17:05
  322. * @return json 请求结果
  323. */
  324. public function delete_menu(){
  325. //获取access_token
  326. $access_token= $this->access_token(false);
  327. if($access_token['status']!=1 && $access_token['status']!=2){
  328. return $access_token;
  329. }
  330. //配置请求url,加入access_token参数
  331. $url = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token='.$access_token['data'];
  332. //获取请求结果,并将请求结果转换成json
  333. $data = string_json($url);
  334. //access_token 过期重新获取并重新回调当前函数
  335. if($data['errcode']==42001 || $data['errcode']==40001){
  336. $access_token = $this->access_token(true);
  337. return $this->delete_menu();
  338. }
  339. $status = $data['errcode']==0?1:40014;
  340. //返回结果
  341. $result = array('status'=>$status,'data'=>$data);
  342. return $result;
  343. }
  344. /**
  345. * 获取自定义菜单配置接口
  346. * @author bug <3164145970@qq.com>
  347. * @createtime 2017-07-26 14:17:05
  348. * @return json 菜单列表
  349. */
  350. public function menu_config(){
  351. //获取access_token
  352. $access_token= $this->access_token(false);
  353. if($access_token['status']!=1 && $access_token['status']!=2){
  354. return $access_token;
  355. }
  356. //配置请求url,加入access_token参数
  357. $url = 'https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token='.$access_token['data'];
  358. //获取请求结果,并将请求结果转换成json
  359. $data = string_json($url);
  360. if(array_key_exists('errcode', $data)){
  361. //access_token 过期重新获取并重新回调当前函数
  362. if($data['errcode']==42001 || $data['errcode']==40001){
  363. $access_token = $this->access_token(true);
  364. return $this->menu_config();
  365. }
  366. $result = array('status'=>40014,'data'=>$data);
  367. return $result;
  368. }
  369. //返回结果
  370. $result = array('status'=>1,'data'=>$data);
  371. return $result;
  372. }
  373. /**********************自定义菜单 结束********/
  374. /**********************消息管理 开始********/
  375. /**
  376. * 消息/事件推送处理
  377. * @author bug <3164145970@qq.com>
  378. * @createtime 2017-08-16 15:58:42
  379. * @param poststr xml 推送数据字符串
  380. * @return [type] [description]
  381. */
  382. public function responseMsg($poststr){
  383. //如果推送消息 或者推送事件存在,进行处理
  384. if(!empty($poststr)){
  385. libxml_disable_entity_loader(true);
  386. $postObj = simplexml_load_string($poststr, 'SimpleXMLElement', LIBXML_NOCDATA);
  387. $msgType = $postObj->MsgType;
  388. //判断事件类型,进行对应事件类型处理
  389. switch ($msgType) {
  390. case 'text':
  391. $resultStr = $this->handleText($postObj);
  392. break;
  393. case 'image':
  394. $resultStr = $this->handleImage($postObj);
  395. break;
  396. case 'voice':
  397. $resultStr = $this->handleVoice($postObj);
  398. break;
  399. case 'video':
  400. $resultStr = $this->handleVideo($postObj);
  401. break;
  402. case 'shortvideo':
  403. $resultStr = $this->handleShortVideo($postObj);
  404. break;
  405. case 'location':
  406. $resultStr = $this->handleLocation($postObj);
  407. break;
  408. case 'link':
  409. $resultStr = $this->handleLink($postObj);
  410. break;
  411. case 'event':
  412. $resultStr = $this->handleEvent($postObj);
  413. break;
  414. default:
  415. $resultStr = "Unknow msg type: ".$msgType;
  416. break;
  417. }
  418. return $resultStr;
  419. }
  420. }
  421. /**---------------------------------------------------------接收消息-接收普通消息 开始-------------------------------------------------------------**/
  422. /**
  423. * 接收文本消息
  424. * @author bug <3164145970@qq.com>
  425. * @createtime 2017-08-16 17:22:58
  426. * @param postObj object 推送事件对象
  427. * @return [type] [description]
  428. */
  429. public function handleText($postObj){
  430. $contentStr = "您发送了文本消息:".$postObj->Content;
  431. return $this->responseText($postObj,$contentStr);
  432. }
  433. /**
  434. * 接收图片消息
  435. * @author bug <3164145970@qq.com>
  436. * @createtime 2017-08-16 17:22:58
  437. * @param postObj object 推送事件对象
  438. * @return [type] [description]
  439. */
  440. public function handleImage($postObj){
  441. $contentStr = "您发送了图片,图片链接:".$postObj->PicUrl.",图片消息媒体id:".$postObj->MediaId.",消息id:".$postObj->MsgId;
  442. return $this->responseText($postObj,$contentStr);
  443. }
  444. /**
  445. * 接收语音消息
  446. * @author bug <3164145970@qq.com>
  447. * @createtime 2017-08-16 17:22:58
  448. * @param postObj object 推送事件对象
  449. * @return [type] [description]
  450. */
  451. public function handleVoice($postObj){
  452. $contentStr = "您发送了语音,语音消息媒体id:".$postObj->MediaId.",语音格式:".$postObj->Format.",消息id".$postObj->MsgId.",Recognition:".$postObj->Recognition;
  453. return $this->responseText($postObj,$contentStr);
  454. }
  455. /**
  456. * 接收视频消息
  457. * @author bug <3164145970@qq.com>
  458. * @createtime 2017-08-16 17:22:58
  459. * @param postObj object 推送事件对象
  460. * @return [type] [description]
  461. */
  462. public function handleVideo($postObj){
  463. $contentStr = "您发送了视频,语音消息媒体id:".$postObj->MediaId.",视频消息缩略图的媒体id:".$postObj->ThumbMediaId.",消息id".$postObj->MsgId;
  464. return $this->responseText($postObj,$contentStr);
  465. }
  466. /**
  467. * 接收小视频消息
  468. * @author bug <3164145970@qq.com>
  469. * @createtime 2017-08-16 17:22:58
  470. * @param postObj object 推送事件对象
  471. * @return [type] [description]
  472. */
  473. public function handleShortVideo($postObj){
  474. $contentStr = "您发送了小视频,语音消息媒体id:".$postObj->MediaId.",视频消息缩略图的媒体id:".$postObj->ThumbMediaId.",消息id".$postObj->MsgId;
  475. return $this->responseText($postObj,$contentStr);
  476. }
  477. /**
  478. * 接收地理位置消息
  479. * @author bug <3164145970@qq.com>
  480. * @createtime 2017-08-16 17:22:58
  481. * @param postObj object 推送事件对象
  482. * @return [type] [description]
  483. */
  484. public function handleLocation($postObj){
  485. $contentStr = "您发送了地理位置,地理位置维度:".$postObj->Location_X.",地理位置经度:".$postObj->Location_Y.",地图缩放大小:".$postObj->Scale.",地理位置信息:".$postObj->Label.",消息id:".$postObj->MsgId;
  486. return $this->responseText($postObj,$contentStr);
  487. }
  488. /**
  489. * 接收链接消息
  490. * @author bug <3164145970@qq.com>
  491. * @createtime 2017-08-16 17:22:58
  492. * @param postObj object 推送事件对象
  493. * @return [type] [description]
  494. */
  495. public function handleLink($postObj){
  496. $contentStr = "您发送了链接,消息标题:".$postObj->Title.",消息描述:".$postObj->Description.",消息链接:".$postObj->Url.",消息id:".$postObj->MsgId;
  497. return $this->responseText($postObj,$contentStr);
  498. }
  499. /**---------------------------------------------------------接收消息-接收普通消息 结束-------------------------------------------------------------**/
  500. /**---------------------------------------------接收消息-接收事件推送 开始-------------------------------------------------------------**/
  501. /**
  502. * 接收事件推送
  503. * @author bug <3164145970@qq.com>
  504. * @createtime 2017-08-16 17:22:58
  505. * @param postObj object 推送事件对象
  506. * @return [type] [description]
  507. */
  508. public function handleEvent($postObj){
  509. $event = $postObj->Event;
  510. switch ($event) {
  511. case 'subscribe'://关注
  512. break;
  513. case 'unsubscribe'://取消关注
  514. break;
  515. case 'scancode_waitmsg'://扫描二维码
  516. break;
  517. case 'SCAN':
  518. break;
  519. case 'LOCATION':
  520. break;
  521. case 'VIEW':
  522. break;
  523. default:
  524. # code...
  525. break;
  526. }
  527. $contentStr = "您触发了事件:".$event;
  528. return $this->responseText($postObj,$contentStr);
  529. }
  530. /**------------------------------------------------------------接收消息-接收事件推送 结束-------------------------------------------------------------**/
  531. /**------------------------------------------------------发送消息-被动回复用户消息 开始-------------------------------------------------------------**/
  532. /**
  533. * 推送事件回复文本消息
  534. * @author bug <3164145970@qq.com>
  535. * @createtime 2017-08-16 16:05:33
  536. * @param object 接收的推送对象
  537. * @param content string 回复的文本消息
  538. * @return [type] [description]
  539. */
  540. public function responseText($object,$content)
  541. {
  542. $textTpl = "<xml>
  543. <ToUserName><![CDATA[%s]]></ToUserName>
  544. <FromUserName><![CDATA[%s]]></FromUserName>
  545. <CreateTime>%s</CreateTime>
  546. <MsgType><![CDATA[text]]></MsgType>
  547. <Content><![CDATA[%s]]></Content>
  548. </xml>";
  549. $resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(),$content);
  550. return $resultStr;
  551. }
  552. /**
  553. * 推送事件回复图片消息
  554. * @author bug <3164145970@qq.com>
  555. * @createtime 2017-08-16 16:05:33
  556. * @param object 接收的推送对象
  557. * @param MediaId 通过素材管理中的接口上传多媒体文件,得到的id
  558. * @return [type] [description]
  559. */
  560. public function responseImage($object,$media_id)
  561. {
  562. $textTpl = "<xml>
  563. <ToUserName><![CDATA[%s]]></ToUserName>
  564. <FromUserName><![CDATA[%s]]></FromUserName>
  565. <CreateTime>%s</CreateTime>
  566. <MsgType><![CDATA[image]]></MsgType>
  567. <Image>
  568. <MediaId><![CDATA[media_id]]></MediaId>
  569. </Image>
  570. </xml>";
  571. $resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(),$media_id);
  572. return $resultStr;
  573. }
  574. /**
  575. * 推送事件回复语音消息
  576. * @author bug <3164145970@qq.com>
  577. * @createtime 2017-08-16 16:05:33
  578. * @param object 接收的推送对象
  579. * @param MediaId 通过素材管理中的接口上传多媒体文件,得到的id
  580. * @return [type] [description]
  581. */
  582. public function responseVoice($object,$media_id)
  583. {
  584. $textTpl = "<xml>
  585. <ToUserName><![CDATA[%s]]></ToUserName>
  586. <FromUserName><![CDATA[%s]]></FromUserName>
  587. <CreateTime>%s</CreateTime>
  588. <MsgType><![CDATA[voice]]></MsgType>
  589. <Voice>
  590. <MediaId><![CDATA[%s]]></MediaId>
  591. </Voice>
  592. </xml>";
  593. $resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(),$media_id);
  594. return $resultStr;
  595. }
  596. /**
  597. * 推送事件回复视频消息
  598. * @author bug <3164145970@qq.com>
  599. * @createtime 2017-08-16 16:05:33
  600. * @param object 接收的推送对象
  601. * @param media_id 通过素材管理中的接口上传多媒体文件,得到的id
  602. * @param title 视频消息的标题
  603. * @param description 视频消息的描述
  604. * @return
  605. */
  606. public function responseVideo($object,$media_id,$title='',$description='')
  607. {
  608. $textTpl = "<xml>
  609. <ToUserName><![CDATA[%s]]></ToUserName>
  610. <FromUserName><![CDATA[%s]]></FromUserName>
  611. <CreateTime>%s</CreateTime>
  612. <MsgType><![CDATA[video]]></MsgType>
  613. <Video>
  614. <MediaId><![CDATA[%s]]></MediaId>
  615. <Title><![CDATA[%s]]></Title>
  616. <Description><![CDATA[%s]]></Description>
  617. </Video>
  618. </xml>";
  619. $resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(),$media_id,$title,$description);
  620. return $resultStr;
  621. }
  622. /**
  623. * 推送事件回复音乐消息
  624. * @author bug <3164145970@qq.com>
  625. * @createtime 2017-08-16 16:05:33
  626. * @param object 接收的推送对象
  627. * @param media_id 缩略图的媒体id,通过素材管理中的接口上传多媒体文件,得到的id
  628. * @param title 音乐标题
  629. * @param description 音乐描述
  630. * @param music_url 音乐链接
  631. * @param hqmusic_url 高质量音乐链接,WIFI环境优先使用该链接播放音乐
  632. * @return
  633. */
  634. public function responseMusic($object,$media_id,$title='',$description='',$music_url='',$hqmusic_url='')
  635. {
  636. $textTpl = "<xml>
  637. <ToUserName><![CDATA[%s]]></ToUserName>
  638. <FromUserName><![CDATA[%s]]></FromUserName>
  639. <CreateTime>%s</CreateTime>
  640. <MsgType><![CDATA[music]]></MsgType>
  641. <Music>
  642. <Title><![CDATA[TITLE]]></Title>
  643. <Description><![CDATA[DESCRIPTION]]></Description>
  644. <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
  645. <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
  646. <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>
  647. </Music>
  648. </xml>";
  649. $resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(),$title,$description,$music_url,$hqmusic_url,$media_id);
  650. return $resultStr;
  651. }
  652. /**
  653. * 推送事件回复图文消息
  654. * @author bug <3164145970@qq.com>
  655. * @createtime 2017-08-16 16:05:33
  656. * @param object 接收的推送对象
  657. * @param articles 图文消息数组
  658. * @param article_count 图文消息个数,限制为8条以内
  659. * @param title 图文消息标题
  660. * @param description 图文消息描述
  661. * @param pic_url 图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200
  662. * @param url 点击图文消息跳转链接
  663. * @return
  664. */
  665. public function responseNews($object,$articles)
  666. {
  667. $article_count = count($articles);
  668. $textTpl = "<xml>
  669. <ToUserName><![CDATA[%s]]></ToUserName>
  670. <FromUserName><![CDATA[%s]]></FromUserName>
  671. <CreateTime>%s</CreateTime>
  672. <MsgType><![CDATA[news]]></MsgType>
  673. <ArticleCount>%s</ArticleCount>
  674. <Articles>";
  675. $textTpl = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(),$article_count);
  676. $article_tpl ="<item>
  677. <Title><![CDATA[%s]]></Title>
  678. <Description><![CDATA[%s]]></Description>
  679. <PicUrl><![CDATA[%s]]></PicUrl>
  680. <Url><![CDATA[%s]]></Url>
  681. </item>";
  682. foreach ($articles as $value) {
  683. $article_str = sprintf($article_tpl,$value['title'],$value['description'],$value['picurl'],$value['url']);
  684. $textTpl .= $article_str;
  685. }
  686. $textTpl .= "</Articles>
  687. </xml>";
  688. return $textTpl;
  689. }
  690. /**--------------------------------------------------------发送消息-被动回复用户消息 结束-------------------------------------------------------------**/
  691. /**
  692. * 客服接口-发消息
  693. * @author bug <3164145970@qq.com>
  694. * @createtime 2017-07-28 09:27:56
  695. * @param openid string 微信用户唯一凭证openid
  696. * @param type string 1 文本 2图文
  697. * @param data json 请求数据集
  698. * @return [type] [description]
  699. */
  700. public function custom_send($openid,$type,$msg,$customservice=''){
  701. //获取access_token
  702. $access_token= $this->access_token(false);
  703. if($access_token['status']!=1 && $access_token['status']!=2){
  704. return $access_token;
  705. }
  706. //配置请求url,加入access_token参数
  707. $url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$access_token['data'];
  708. $post_data['touser'] = $openid;
  709. $post_data['msgtype'] = $type;
  710. switch ($type) {
  711. case 'text'://发送文本消息
  712. $post_data['text']['content'] = $msg;
  713. break;
  714. case 'image'://发送图片消息
  715. $post_data['image']['media_id'] = $msg;
  716. break;
  717. case 'voice'://发送语音消息
  718. $post_data['voice']['media_id'] = $msg;
  719. break;
  720. case 'video'://发送视频消息,参数media_id,thumb_media_id,title,description
  721. $post_data['video'] = $msg;
  722. break;
  723. case 'music'://发送音乐消息,参数title,description,musicurl,hqmusicurl,thumb_media_id
  724. $post_data['music'] = $msg;
  725. break;
  726. case 'news'://发送图文消息(点击跳转到外链) 图文消息条数限制在8条以内,注意,如果图文数超过8,则将会无响应
  727. $post_data['news']['articles'] =$msg;
  728. break;
  729. case 'mpnews'://发送图文消息(点击跳转到图文消息页面) 图文消息条数限制在8条以内,注意,如果图文数超过8,则将会无响应
  730. $post_data['mpnews']['media_id'] = $msg;
  731. break;
  732. case 'wxcard'://发送卡券
  733. $post_data['wxcard']['card_id'] = $msg;
  734. break;
  735. case 'miniprogrampage'://发送小程序卡片,参数title,appid,pagepath,thumb_media_id
  736. $post_data['miniprogrampage'] = $msg;
  737. break;
  738. default:
  739. $post_data['msgtype'] = 'text';
  740. $post_data['text']['content'] = '这是一个默认图文消息:无消息类型';
  741. break;
  742. }
  743. //请注意,如果需要以某个客服帐号来发消息(在微信6.0.2及以上版本中显示自定义头像),则需在JSON数据包的后半部分加入customservice参数
  744. if(!empty($customservice)){
  745. $post_data['customservice']['kf_account'] = $customservice;
  746. }
  747. //将json数组转换成字符串数组
  748. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  749. //获取请求结果,并将请求结果转换成json
  750. $data = json_decode(https_request($url,$post_data),true);
  751. //access_token 过期重新获取并重新回调当前函数
  752. if($data['errcode']==42001 || $data['errcode']==40001){
  753. $access_token = $this->access_token(true);
  754. return $this->custom_send($openid,$type,$msg,$customservice);
  755. }
  756. //返回结果
  757. if($data['errcode']==0&&$data['errmsg']=='ok'){
  758. $result = array('status'=>1,'data'=>$data);
  759. return $result;
  760. }
  761. $result = array('status'=>40014,'data'=>$data);
  762. return $result;
  763. }
  764. /**
  765. * 获取模板列表
  766. * @author bug <3164145970@qq.com>
  767. * @createtime 2017-08-25 14:43:54
  768. * @param access_token 微信调用接口唯一凭证
  769. * @return json
  770. */
  771. public function template_list(){
  772. //获取access_token
  773. $access_token= $this->access_token(false);
  774. if($access_token['status']!=1 && $access_token['status']!=2){
  775. return $access_token;
  776. }
  777. //配置请求url,加入access_token参数
  778. $url = 'https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token='.$access_token['data'];
  779. //获取请求结果,并将请求结果转换成json
  780. $data = string_json($url);
  781. if(array_key_exists('errcode', $data)){
  782. //access_token 过期重新获取并重新回调当前函数
  783. if($data['errcode']==42001 || $data['errcode']==40001){
  784. $access_token = $this->access_token(true);
  785. return $this->template_list();
  786. }
  787. $result = array('status'=>40014,'data'=>$data);
  788. return $result;
  789. }
  790. //返回结果
  791. $result = array('status'=>1,'data'=>$data);
  792. return $result;
  793. }
  794. /**
  795. * 模板接口-发消息
  796. * @author bug <3164145970@qq.com>
  797. * @createtime 2017-08-01 15:50:11
  798. * @param data json 请求数据集
  799. * @return [type] [description]
  800. */
  801. public function template_send($post_data){
  802. //获取access_token
  803. $access_token= $this->access_token(false);
  804. if($access_token['status']!=1 && $access_token['status']!=2){
  805. return $access_token;
  806. }
  807. //配置请求url,加入access_token参数
  808. $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$access_token['data'];
  809. //将json数组转换成字符串数组
  810. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  811. //获取请求结果,并将请求结果转换成json
  812. $data = json_decode(https_request($url,$post_data),true);
  813. //access_token 过期重新获取并重新回调当前函数
  814. if($data['errcode']==42001 || $data['errcode']==40001){
  815. $access_token = $this->access_token(true);
  816. return $this->template_send($post_data);
  817. }
  818. //返回结果
  819. if($data['errcode']==0&&$data['errmsg']=='ok'){
  820. $result = array('status'=>1,'data'=>$data);
  821. return $result;
  822. }
  823. $result = array('status'=>40014,'data'=>$data);
  824. return $result;
  825. }
  826. /**********************消息管理 结束********/
  827. /**********************微信网页授权 开始********/
  828. /**
  829. * 通过微信授权code获取微信用户access_token
  830. * @author bug <3164145970@qq.com>
  831. * @createtime 2017-07-27 11:26:30
  832. * @param code 微信用户授权获取的code
  833. * @return json 返回结果
  834. */
  835. public function user_access_token($code){
  836. //session开始
  837. if(!isset($_SESSION)){
  838. session_start();
  839. }
  840. //如果code已经被使用过了返回缓存里面的微信用户access_token相关信息
  841. if(isset($_SESSION['user_access_token'])&&$code==$_SESSION['user_access_token']['code']){
  842. $data = $_SESSION['user_access_token'];
  843. $result = array('status'=>2,'data'=>$data);
  844. return $result;
  845. }
  846. //配置请求url,加入access_token参数
  847. $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->appid.'&secret='.$this->appsecret.'&code='.$code.'&grant_type=authorization_code';
  848. //获取请求结果,并将请求结果转换成json
  849. $data = string_json($url);
  850. //获取当前时间
  851. $time = time();
  852. if(array_key_exists('errcode', $data)){
  853. $result = array('status'=>40014,'data'=>$data);
  854. return $result;
  855. }
  856. session_set_cookie_params(60*5); //设置access_token在服务器session中缓存时间
  857. //添加access_token过期时间
  858. $data['access_endtime'] = $time+$data['expires_in'];
  859. //添加refresh_token过期时间
  860. $data['refresh_endtime'] = $time+60*60*24*30;
  861. $data['code'] = $code;
  862. $_SESSION['user_access_token'] = $data;
  863. //返回结果
  864. $result = array('status'=>1,'data'=>$data);
  865. return $result;
  866. }
  867. /**
  868. * 刷新微信用户access_token
  869. * @author bug <3164145970@qq.com>
  870. * @createtime 2017-07-27 11:26:27
  871. * @param refresh_token 微信用户用来刷新access_token用的
  872. * @param state int 微信用户获取access_token的state
  873. * @return json 返回结果
  874. */
  875. public function user_refresh_token($refresh_token,$state=0){
  876. //配置请求url,加入access_token参数
  877. $url = 'https://api.weixin.qq.com/sns/oauth2/refresh_token?appid='.$this->appid.'&grant_type=refresh_token&refresh_token='.$refresh_token;
  878. //获取请求结果,并将请求结果转换成json
  879. $data = string_json($url);
  880. //获取当前时间
  881. $time = time();
  882. if(array_key_exists('errcode', $data)){
  883. if($data['errcode']==42002){
  884. //如果超时重定向首页重新获取refresh_token
  885. header("location: https://open.weixin.qq.com/connect/oauth2/authorize?appid=".config('crm_config.wechat_appid')."&redirect_uri=".urlencode(config('crm_config.user_accesstoken_uri'))."&response_type=code&scope=snsapi_base&state=".$state."#wechat_redirect");exit;
  886. }
  887. $result = array('status'=>40014,'data'=>$data);
  888. return $result;
  889. }
  890. //添加access_token过期时间
  891. $data['access_endtime'] = $time+$data['expires_in'];
  892. //返回结果
  893. $result = array('status'=>1,'data'=>$data);
  894. return $result;
  895. }
  896. /**
  897. * 拉取用户信息(需scope为 snsapi_userinfo)
  898. * @author bug <3164145970@qq.com>
  899. * @createtime 2017-07-27 11:26:27
  900. * @param string access_token 微信用户授权获取的access_token
  901. * @param string openid 微信用户唯一凭证
  902. * @return json 返回结果
  903. */
  904. public function userinfo($access_token,$openid){
  905. //配置请求url,加入access_token参数
  906. $url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$access_token.'&openid='.$openid.'&lang=zh_CN';
  907. //获取请求结果,并将请求结果转换成json
  908. $data = string_json($url);
  909. if(array_key_exists('errcode', $data)){
  910. $result = array('status'=>40014,'data'=>$data);
  911. return $result;
  912. }
  913. //返回结果
  914. $result = array('status'=>1,'data'=>$data);
  915. return $result;
  916. }
  917. /**
  918. * 检验授权凭证(access_token)是否有效
  919. * @author bug <3164145970@qq.com>
  920. * @createtime 2017-07-27 11:26:27
  921. * @param string access_token 微信用户授权获取的access_token
  922. * @param string openid 微信用户唯一凭证
  923. * @return json 返回结果
  924. */
  925. public function auth($access_token,$openid){
  926. //配置请求url,加入access_token参数
  927. $url = 'https://api.weixin.qq.com/sns/auth?access_token='.$access_token.'&openid='.$openid;
  928. //获取请求结果,并将请求结果转换成json
  929. $data = string_json($url);
  930. //返回结果
  931. $status = $data['errcode']==0?1:40014;
  932. $result = array('status'=>$status,'data'=>$data);
  933. return $result;
  934. }
  935. /**********************微信网页授权 结束********/
  936. /**********************微信自定义分享 开始********/
  937. /**
  938. * 获取微信自定已分享配置参数包
  939. * @author bug <3164145970@qq.com>
  940. * @createtime 2017-08-05 14:21:04
  941. * @return array 配置参数包
  942. */
  943. public function getSignPackage() {
  944. $jsapiTicket = $this->getJsApiTicket();
  945. // 注意 URL 一定要动态获取,不能 hardcode.
  946. $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
  947. $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
  948. $timestamp = time();
  949. $nonceStr = $this->createNonceStr();
  950. // 这里参数的顺序要按照 key 值 ASCII 码升序排序
  951. $string = "jsapi_ticket=".$jsapiTicket."&noncestr=".$nonceStr."&timestamp=".$timestamp."&url=".$url;
  952. $signature = sha1($string);
  953. $signPackage = array(
  954. "appId" => $this->appid,
  955. "nonceStr" => $nonceStr,
  956. "timestamp" => $timestamp,
  957. "url" => $url,
  958. "signature" => $signature,
  959. "rawString" => $string
  960. );
  961. return $signPackage;
  962. }
  963. /**
  964. * 微信自定义分享随机字符串
  965. * @author bug <3164145970@qq.com>
  966. * @createtime 2017-08-05 14:22:15
  967. * @param length int 随机字符串长度
  968. * @return str string 随机字符串
  969. */
  970. private function createNonceStr($length = 16) {
  971. $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  972. $str = "";
  973. for ($i = 0; $i < $length; $i++) {
  974. $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
  975. }
  976. return $str;
  977. }
  978. /**
  979. * 微信自定义分享获取jsapiticket
  980. * @author bug <3164145970@qq.com>
  981. * @createtime 2017-08-05 14:23:30
  982. * @return jsapi_ticket string 微信jsapi调用凭证
  983. */
  984. private function getJsApiTicket() {
  985. // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
  986. $data = json_decode(file_get_contents(dirname(__FILE__)."/json/jsapi_ticket.json"));
  987. if ($data->expire_time < time()) {
  988. $access_token = $this->access_token(false);
  989. if($access_token['status']!=1 && $access_token['status']!=2){
  990. return $access_token;
  991. }
  992. // 如果是企业号用以下 URL 获取 ticket
  993. // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=".$access_token['data'];
  994. $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=".$access_token['data'];
  995. $res = json_decode(https_get($url));
  996. if(!isset($res->ticket)){
  997. $access_token = $this->access_token(true);
  998. $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=".$access_token['data'];
  999. $res = json_decode(https_get($url));
  1000. }
  1001. $ticket = $res->ticket;
  1002. if ($ticket) {
  1003. $data->expire_time = time() + 7200;
  1004. $data->jsapi_ticket = $ticket;
  1005. $fp = fopen(dirname(__FILE__)."/json/jsapi_ticket.json", "w");
  1006. fwrite($fp, json_encode($data));
  1007. fclose($fp);
  1008. }
  1009. } else {
  1010. $ticket = $data->jsapi_ticket;
  1011. }
  1012. return $ticket;
  1013. }
  1014. /**********************微信自定义分享 结束********/
  1015. /**********************素材管理 开始********/
  1016. /**
  1017. * 获取永久素材列表
  1018. * @author bug <3164145970@qq.com>
  1019. * @createtime 2017-09-02 16:44:24
  1020. * @param type string 素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)
  1021. * @param offset int 从全部素材的该偏移位置开始返回,0表示从第一个素材 返回
  1022. * @param count int 返回素材的数量,取值在1到20之间
  1023. * @return [type] [description]
  1024. */
  1025. public function material_list($type,$offset=0,$count=20){
  1026. //获取access_token
  1027. $access_token= $this->access_token(false);
  1028. if($access_token['status']!=1 && $access_token['status']!=2){
  1029. return $access_token;
  1030. }
  1031. //组装参数
  1032. $post_data['type'] = $type;
  1033. $post_data['offset'] = $offset;
  1034. $post_data['count'] = $count;
  1035. //配置请求url,加入access_token参数
  1036. $url = 'https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token='.$access_token['data'];
  1037. //将json数组转换成字符串数组
  1038. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  1039. //获取请求结果,并将请求结果转换成json
  1040. $data = json_decode(https_request($url,$post_data),true);
  1041. //access_token 过期重新获取并重新回调当前函数
  1042. if(isset($data['errcode']) && ($data['errcode']==42001 || $data['errcode']==40001)){
  1043. $access_token = $this->access_token(true);
  1044. return $this->create_menu($type,$offset,$count);
  1045. }
  1046. //返回结果
  1047. if(!isset($data['errcode'])){
  1048. $result = array('status'=>1,'data'=>$data);
  1049. return $result;
  1050. }
  1051. $result = array('status'=>40014,'data'=>$data);
  1052. return $result;
  1053. }
  1054. /**********************素材管理 结束********/
  1055. /**********************用户管理 开始********/
  1056. /**
  1057. * 获取关注用户个人信息
  1058. * @author bug <3164145970@qq.com>
  1059. * @createtime 2017-08-25 14:43:54
  1060. * @param access_token string 微信调用接口唯一凭证
  1061. * @param openid string 用户的openid
  1062. * @return json
  1063. */
  1064. public function user_info($openid=''){
  1065. //获取access_token
  1066. $access_token= $this->access_token(false);
  1067. if($access_token['status']!=1 && $access_token['status']!=2){
  1068. return $access_token;
  1069. }
  1070. //配置请求url,加入access_token参数
  1071. $url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$access_token['data'].'&openid='.$openid.'&lang=zh_CN ';
  1072. //获取请求结果,并将请求结果转换成json
  1073. $data = string_json($url);
  1074. if(array_key_exists('errcode', $data)){
  1075. //access_token 过期重新获取并重新回调当前函数
  1076. if($data['errcode']==42001 || $data['errcode']==40001 ){
  1077. $access_token = $this->access_token(true);
  1078. return $this->user_info($openid);
  1079. }
  1080. $result = array('status'=>40014,'data'=>$data);
  1081. return $result;
  1082. }
  1083. //返回结果
  1084. $result = array('status'=>1,'data'=>$data);
  1085. return $result;
  1086. }
  1087. /**
  1088. * 批量获取用户信息
  1089. * @author bug <3164145970@qq.com>
  1090. * @createtime 2017-10-16 14:20:46
  1091. * @param data json 请求数据集
  1092. * @return [type] [description]
  1093. */
  1094. public function user_list_info($post_data){
  1095. //获取access_token
  1096. $access_token= $this->access_token(false);
  1097. if($access_token['status']!=1 && $access_token['status']!=2){
  1098. return $access_token;
  1099. }
  1100. //配置请求url,加入access_token参数
  1101. $url = 'https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token='.$access_token['data'];
  1102. //将json数组转换成字符串数组
  1103. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  1104. //获取请求结果,并将请求结果转换成json
  1105. $data = json_decode(https_request($url,$post_data),true);
  1106. //access_token 过期重新获取并重新回调当前函数
  1107. if(isset($data['errcode'])&&($data['errcode']==42001 || $data['errcode']==40001)){
  1108. $access_token = $this->access_token(true);
  1109. return $this->user_list_info($post_data);
  1110. }
  1111. //返回结果
  1112. if(isset($data['user_info_list'])){
  1113. $result = array('status'=>1,'data'=>$data);
  1114. return $result;
  1115. }
  1116. $result = array('status'=>40014,'data'=>$data);
  1117. return $result;
  1118. }
  1119. /**
  1120. * 获取关注用户列表
  1121. * @author bug <3164145970@qq.com>
  1122. * @createtime 2017-08-25 14:43:54
  1123. * @param access_token string 微信调用接口唯一凭证
  1124. * @param next_openid string 上次请求最后一个用户的openid
  1125. * @return json
  1126. */
  1127. public function user_list($next_openid=''){
  1128. //获取access_token
  1129. $access_token= $this->access_token(false);
  1130. if($access_token['status']!=1 && $access_token['status']!=2){
  1131. return $access_token;
  1132. }
  1133. //配置请求url,加入access_token参数
  1134. $url = 'https://api.weixin.qq.com/cgi-bin/user/get?access_token='.$access_token['data'];
  1135. if(!empty($next_openid)){
  1136. $url.='&next_openid='.$next_openid;
  1137. }
  1138. //获取请求结果,并将请求结果转换成json
  1139. $data = string_json($url);
  1140. if(array_key_exists('errcode', $data)){
  1141. //access_token 过期重新获取并重新回调当前函数
  1142. if($data['errcode']==42001 || $data['errcode']==40001){
  1143. $access_token = $this->access_token(true);
  1144. return $this->user_list($next_openid);
  1145. }
  1146. $result = array('status'=>40014,'data'=>$data);
  1147. return $result;
  1148. }
  1149. //返回结果
  1150. $result = array('status'=>1,'data'=>$data);
  1151. return $result;
  1152. }
  1153. /**********************用户管理 结束********/
  1154. /**********************新版客服 开始********/
  1155. /**
  1156. * 添加客服账号
  1157. * @author bug <3164145970@qq.com>
  1158. * @createtime 2017-08-02 15:39:36
  1159. * @param post_data 请求数据
  1160. * @param kf_account string 完整客服帐号,格式为:帐号前缀@公众号微信号,帐号前缀最多10个字符,必须是英文、数字字符或者下划线,后缀为公众号微信号,长度不超过30个字符
  1161. * @param nickname 客服昵称,最长16个字
  1162. * @return [type] [description]
  1163. */
  1164. public function customservice_add($post_data){
  1165. //获取access_token
  1166. $access_token= $this->access_token(false);
  1167. if($access_token['status']!=1 && $access_token['status']!=2){
  1168. return $access_token;
  1169. }
  1170. //配置请求url,加入access_token参数
  1171. $url = 'https://api.weixin.qq.com/customservice/kfaccount/add?access_token='.$access_token['data'];
  1172. //将json数组转换成字符串数组
  1173. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  1174. //获取请求结果,并将请求结果转换成json
  1175. $data = json_decode(https_request($url,$post_data),true);
  1176. //access_token 过期重新获取并重新回调当前函数
  1177. if($data['errcode']==42001 || $data['errcode']==40001){
  1178. $access_token = $this->access_token(true);
  1179. return $this->customservice_add($post_data);
  1180. }
  1181. //返回结果
  1182. if($data['errcode']==0&&$data['errmsg']=='ok'){
  1183. $result = array('status'=>1,'data'=>$data);
  1184. return $result;
  1185. }
  1186. $result = array('status'=>40014,'data'=>$data);
  1187. return $result;
  1188. }
  1189. /**
  1190. * 获取聊天记录
  1191. * @author bug <3164145970@qq.com>
  1192. * @createtime 2017-08-01 17:20:03
  1193. * @param starttime int 起始时间,unix时间戳
  1194. * @param endtime int 结束时间,unix时间戳,每次查询时段不能超过24小时
  1195. * @param msgid int 消息id顺序从小到大,从1开始
  1196. * @param number int 每次获取条数,最多10000条
  1197. * @return json 返回结果
  1198. */
  1199. public function customservice_getmsglist($starttime,$endtime,$msgid,$number){
  1200. //获取access_token
  1201. $access_token= $this->access_token(false);
  1202. if($access_token['status']!=1 && $access_token['status']!=2){
  1203. return $access_token;
  1204. }
  1205. //配置请求url,加入access_token参数
  1206. $url = 'https://api.weixin.qq.com/customservice/msgrecord/getmsglist?access_token='.$access_token['data'];
  1207. //将json数组转换成字符串数组
  1208. $post_data = array('starttime'=>$starttime,
  1209. 'endtime'=>$endtime,
  1210. 'msgid'=>$msgid,
  1211. 'number'=>$number);
  1212. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  1213. //获取请求结果,并将请求结果转换成json
  1214. $data = json_decode(https_request($url,$post_data),true);
  1215. //access_token 过期重新获取并重新回调当前函数
  1216. if(isset($data['errcode']) && ($data['errcode']==42001 || $data['errcode']==40001)){
  1217. $access_token = $this->access_token(true);
  1218. return $this->customservice_getmsglist($starttime,$endtime,$msgid,$number);
  1219. }
  1220. //返回结果
  1221. if(isset($data['recordlist'])){
  1222. $result = array('status'=>1,'data'=>$data);
  1223. return $result;
  1224. }
  1225. $result = array('status'=>40014,'data'=>$data);
  1226. return $result;
  1227. }
  1228. /**********************新版客服 结束********/
  1229. /**********************微信支付 开始********/
  1230. /**
  1231. * 统一下单,WxPayUnifiedOrder中out_trade_no、body、total_fee、trade_type必填
  1232. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  1233. * @author bug <3164145970@qq.com>
  1234. * @createtime 2017-09-09 16:22:38\
  1235. * @param WxPayUnifiedOrder $inputObj
  1236. * @param int $timeOut
  1237. * @throws WxPayException
  1238. * @return [type] [description]
  1239. */
  1240. public function unifiedOrder($data, $timeOut = 6){
  1241. //配置请求url
  1242. $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  1243. //检查请求参数
  1244. if(!isset($data['out_trade_no'])){
  1245. $result = array('status'=>40010,'data'=>'缺少统一支付接口必填参数out_trade_no!');
  1246. return $result;
  1247. }
  1248. if(!isset($data['body'])){
  1249. $result = array('status'=>40010,'data'=>'缺少统一支付接口必填参数body!');
  1250. return $result;
  1251. }
  1252. if(!isset($data['total_fee'])){
  1253. $result = array('status'=>40010,'data'=>'缺少统一支付接口必填参数total_fee!');
  1254. return $result;
  1255. }
  1256. if(!isset($data['trade_type'])){
  1257. $result = array('status'=>40010,'data'=>'缺少统一支付接口必填参数trade_type!');
  1258. return $result;
  1259. }
  1260. if($data['trade_type'] == 'JSAPI' && !isset($data['openid'])){
  1261. $result = array('status'=>40010,'data'=>'统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!');
  1262. return $result;
  1263. }
  1264. if($data['trade_type'] == "NATIVE" && !isset($data['product_id'])){
  1265. $result = array('status'=>40010,'data'=>'统一支付接口中,缺少必填参数product_id!trade_type为NATIVE时,product_id为必填参数!');
  1266. return $result;
  1267. }
  1268. //异步通知url未设置,则使用配置文件中的url
  1269. if(!isset($data['notify_url'])){
  1270. $data['notify_url'] = config('crm_config.wechat_notify_url');
  1271. }
  1272. $data['appid'] = $this->appid;//微信支付分配的公众账号ID(企业号corpid即为此appId)
  1273. $data['mch_id'] = $this->mch_id;//微信支付分配的商户号
  1274. $data['spbill_create_ip'] = get_client_ip();//APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
  1275. $data['nonce_str'] = $this->createNonceStr(32);
  1276. $data['sign'] = $this->makeSign($data);
  1277. $xml = arr_xml($data);
  1278. $startTimeStamp = milli_time();//请求开始时间
  1279. $response = $this->postXml($xml, $url, false, $timeOut);
  1280. $datas = xml_arr($response);//将xml转为array
  1281. //判断请求结果是否成功
  1282. if($datas['return_code'] != 'SUCCESS'){
  1283. $result = array('status'=>40014,'data'=>$datas);
  1284. return $result;
  1285. }
  1286. //判断签名是否存在,及签名是否正确
  1287. if(!array_key_exists('sign', $datas)){
  1288. $result = array('status'=>40011,'data'=>'签名错误!');
  1289. return $result;
  1290. }
  1291. $this->reportCostTime($url, $startTimeStamp, $datas);//上报请求花费时间
  1292. //返回结果
  1293. $result = array('status'=>1,'data'=>$datas);
  1294. return $result;
  1295. }
  1296. /**
  1297. * 查询订单,WxPayOrderQuery中out_trade_no、transaction_id至少填一个
  1298. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  1299. * @author bug <3164145970@qq.com>
  1300. * @createtime 2017-09-11 11:37:20
  1301. * @param $data 参数集
  1302. * @param $timeOut 超时
  1303. * @return 成功时返回,其他抛异常
  1304. */
  1305. public function orderQuery($data, $timeOut = 6){
  1306. $url = "https://api.mch.weixin.qq.com/pay/orderquery";
  1307. //检测必填参数
  1308. if(!array_key_exists('out_trade_no', $data) && !array_key_exists('transaction_id', $data)) {
  1309. $result = array('status'=>40010,'data'=>'订单查询接口中,out_trade_no、transaction_id至少填一个!');
  1310. return $result;
  1311. }
  1312. //组装参数
  1313. $data['appid'] = $this->appid;//公众账号ID
  1314. $data['mch_id'] = $this->mch_id;//商户号
  1315. $data['nonce_str'] = $this->createNonceStr(32);//随机字符串
  1316. $data['sign'] = $this->makeSign($data);//签名
  1317. $xml = arr_xml($data);
  1318. $startTimeStamp = milli_time();//请求开始时间
  1319. $response = $this->postXml($xml, $url, false, $timeOut);
  1320. $datas = xml_arr($response);//将xml转为array
  1321. //判断请求结果是否成功
  1322. if($datas['return_code'] != 'SUCCESS'){
  1323. $result = array('status'=>40014,'data'=>$datas);
  1324. return $result;
  1325. }
  1326. //判断签名是否存在,及签名是否正确
  1327. if(!array_key_exists('sign', $datas) ){
  1328. $result = array('status'=>40011,'data'=>'签名错误!');
  1329. return $result;
  1330. }
  1331. $this->reportCostTime($url, $startTimeStamp, $datas);//上报请求花费时间
  1332. //返回结果
  1333. $result = array('status'=>1,'data'=>$datas);
  1334. return $result;
  1335. }
  1336. /**
  1337. * 关闭订单,WxPayCloseOrder中out_trade_no必填
  1338. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  1339. * @author bug <3164145970@qq.com>
  1340. * @createtime 2017-09-11 11:48:48
  1341. * @param $data 参数集
  1342. * @param $timeOut 超时
  1343. * @return 成功时返回,其他抛异常
  1344. */
  1345. public function closeOrder($data, $timeOut = 6){
  1346. $url = "https://api.mch.weixin.qq.com/pay/closeorder";
  1347. //检测必填参数
  1348. if(!array_key_exists('out_trade_no', $data)) {
  1349. $result = array('status'=>40010,'data'=>'订单关闭接口中,out_trade_no必填!');
  1350. return $result;
  1351. }
  1352. //组装参数
  1353. $data['appid'] = $this->appid;//公众账号ID
  1354. $data['mch_id'] = $this->mch_id;//商户号
  1355. $data['nonce_str'] = $this->createNonceStr(32);//随机字符串
  1356. $data['sign'] = $this->makeSign($data);//签名
  1357. $xml = arr_xml($data);
  1358. $startTimeStamp = milli_time();//请求开始时间
  1359. $response = $this->postXml($xml, $url, false, $timeOut);
  1360. $datas = xml_arr($response);//将xml转为array
  1361. //判断请求结果是否成功
  1362. if($datas['return_code'] != 'SUCCESS'){
  1363. $result = array('status'=>40014,'data'=>$datas);
  1364. return $result;
  1365. }
  1366. //判断签名是否存在,及签名是否正确
  1367. if(!array_key_exists('sign', $datas) ){
  1368. $result = array('status'=>40011,'data'=>'签名错误!');
  1369. return $result;
  1370. }
  1371. $this->reportCostTime($url, $startTimeStamp, $datas);//上报请求花费时间
  1372. //返回结果
  1373. $result = array('status'=>1,'data'=>$datas);
  1374. return $result;
  1375. }
  1376. /**
  1377. * 申请退款,WxPayRefund中out_trade_no、transaction_id至少填一个且
  1378. * out_refund_no、total_fee、refund_fee、op_user_id为必填参数
  1379. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  1380. * @author bug <3164145970@qq.com>
  1381. * @createtime 2017-09-11 13:42:49
  1382. * @param $data 参数集
  1383. * @param $timeOut 超时
  1384. * @return 成功时返回,其他抛异常
  1385. */
  1386. public function refund($data, $timeOut = 6){
  1387. $url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
  1388. //检测必填参数
  1389. if(!array_key_exists('out_trade_no', $data) && !array_key_exists('transaction_id', $data)) {
  1390. $result = array('status'=>40010,'data'=>'退款申请接口中,out_trade_no、transaction_id至少填一个!');
  1391. return $result;
  1392. }
  1393. if(!array_key_exists('out_refund_no', $data)) {
  1394. $result = array('status'=>40010,'data'=>'退款申请接口中,缺少必填参数out_refund_no!');
  1395. return $result;
  1396. }
  1397. if(!array_key_exists('total_fee', $data)) {
  1398. $result = array('status'=>40010,'data'=>'退款申请接口中,缺少必填参数total_fee!');
  1399. return $result;
  1400. }
  1401. if(!array_key_exists('refund_fee', $data)) {
  1402. $result = array('status'=>40010,'data'=>'退款申请接口中,缺少必填参数refund_fee!');
  1403. return $result;
  1404. }
  1405. //组装参数
  1406. $data['appid'] = $this->appid;//公众账号ID
  1407. $data['mch_id'] = $this->mch_id;//商户号
  1408. $data['nonce_str'] = $this->createNonceStr(32);//随机字符串
  1409. /**
  1410. * 仅针对老资金流商户使用
  1411. *REFUND_SOURCE_UNSETTLED_FUNDS---未结算资金退款(默认使用未结算资金退款)
  1412. *REFUND_SOURCE_RECHARGE_FUNDS---可用余额退款
  1413. */
  1414. $data['refund_account'] = 'REFUND_SOURCE_RECHARGE_FUNDS';//退款资金来源
  1415. $data['sign'] = $this->makeSign($data);//签名
  1416. $xml = arr_xml($data);
  1417. $startTimeStamp = milli_time();//请求开始时间
  1418. $response = $this->postXml($xml, $url, true, $timeOut);
  1419. $datas = xml_arr($response);//将xml转为array
  1420. //判断请求结果是否成功
  1421. if($datas['return_code'] != 'SUCCESS'){
  1422. $result = array('status'=>40014,'data'=>$datas);
  1423. return $result;
  1424. }
  1425. //判断签名是否存在,及签名是否正确
  1426. if(!array_key_exists('sign', $datas) ){
  1427. $result = array('status'=>40011,'data'=>'签名错误!');
  1428. return $result;
  1429. }
  1430. $this->reportCostTime($url, $startTimeStamp, $datas);//上报请求花费时间
  1431. //返回结果
  1432. $result = array('status'=>1,'data'=>$datas);
  1433. return $result;
  1434. }
  1435. /**
  1436. * 查询退款
  1437. * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,
  1438. * 用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。
  1439. * WxPayRefundQuery中out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个
  1440. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  1441. * @author bug <3164145970@qq.com>
  1442. * @createtime 2017-09-11 13:56:23
  1443. * @param $data 参数集
  1444. * @param $timeOut 超时
  1445. * @return 成功时返回,其他抛异常
  1446. */
  1447. public function refundQuery($data, $timeOut = 6){
  1448. $url = "https://api.mch.weixin.qq.com/pay/refundquery";
  1449. //检测必填参数
  1450. if(!array_key_exists('out_refund_no', $data) && !array_key_exists('out_trade_no', $data) && !array_key_exists('transaction_id', $data) && !array_key_exists('refund_id', $data) ) {
  1451. $result = array('status'=>40010,'data'=>'退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个');
  1452. return $result;
  1453. }
  1454. //组装参数
  1455. $data['appid'] = $this->appid;//公众账号ID
  1456. $data['mch_id'] = $this->mch_id;//商户号
  1457. $data['nonce_str'] = $this->createNonceStr(32);//随机字符串
  1458. $data['sign'] = $this->makeSign($data);//签名
  1459. $xml = arr_xml($data);
  1460. $startTimeStamp = milli_time();//请求开始时间
  1461. $response = $this->postXml($xml, $url, false, $timeOut);
  1462. $datas = xml_arr($response);//将xml转为array
  1463. //判断请求结果是否成功
  1464. if($datas['return_code'] != 'SUCCESS'){
  1465. $result = array('status'=>40014,'data'=>$datas);
  1466. return $result;
  1467. }
  1468. //判断签名是否存在,及签名是否正确
  1469. if(!array_key_exists('sign', $datas) ){
  1470. $result = array('status'=>40011,'data'=>'签名错误!');
  1471. return $result;
  1472. }
  1473. $this->reportCostTime($url, $startTimeStamp, $datas);//上报请求花费时间
  1474. //返回结果
  1475. $result = array('status'=>1,'data'=>$datas);
  1476. return $result;
  1477. }
  1478. /**
  1479. * 下载对账单,WxPayDownloadBill中bill_date为必填参数
  1480. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  1481. * @author bug <3164145970@qq.com>
  1482. * @createtime 2017-09-11 14:04:10
  1483. * @param $data 参数集
  1484. * @param $timeOut 超时
  1485. * @return 成功时返回,其他抛异常
  1486. */
  1487. public function downloadBill($data, $timeOut = 6){
  1488. $url = "https://api.mch.weixin.qq.com/pay/downloadbill";
  1489. //检测必填参数
  1490. if(!array_key_exists('bill_date', $data)) {
  1491. $result = array('status'=>40010,'data'=>'对账单接口中,缺少必填参数bill_date!');
  1492. return $result;
  1493. }
  1494. //组装参数
  1495. $data['appid'] = $this->appid;//公众账号ID
  1496. $data['mch_id'] = $this->mch_id;//商户号
  1497. $data['nonce_str'] = $this->createNonceStr(32);//随机字符串
  1498. $data['sign'] = $this->makeSign($data);//签名
  1499. $xml = arr_xml($data);
  1500. $startTimeStamp = milli_time();//请求开始时间
  1501. $response = $this->postXml($xml, $url, false, $timeOut);
  1502. $datas = xml_arr($response);//将xml转为array
  1503. //判断请求结果是否成功
  1504. if($datas['return_code'] != 'SUCCESS'){
  1505. $result = array('status'=>40014,'data'=>$datas);
  1506. return $result;
  1507. }
  1508. //判断签名是否存在,及签名是否正确
  1509. if(!array_key_exists('sign', $datas) ){
  1510. $result = array('status'=>40011,'data'=>'签名错误!');
  1511. return $result;
  1512. }
  1513. $this->reportCostTime($url, $startTimeStamp, $datas);//上报请求花费时间
  1514. //返回结果
  1515. $result = array('status'=>1,'data'=>$datas);
  1516. return $result;
  1517. }
  1518. /**
  1519. * 提交被扫支付API
  1520. * 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,
  1521. * 由商户收银台或者商户后台调用该接口发起支付。
  1522. * WxPayWxPayMicroPay中body、out_trade_no、total_fee、auth_code参数必填
  1523. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  1524. * @author bug <3164145970@qq.com>
  1525. * @createtime 2017-09-11 14:06:11
  1526. * @param $data 参数集
  1527. * @param $timeOut 超时
  1528. * @return 成功时返回,其他抛异常
  1529. */
  1530. public function micropay($data, $timeOut = 6){
  1531. $url = "https://api.mch.weixin.qq.com/pay/micropay";
  1532. //检测必填参数
  1533. if(!array_key_exists('body', $data)) {
  1534. $result = array('status'=>40010,'data'=>'提交被扫支付API接口中,缺少必填参数body!');
  1535. return $result;
  1536. }
  1537. if(!array_key_exists('out_trade_no', $data)) {
  1538. $result = array('status'=>40010,'data'=>'提交被扫支付API接口中,缺少必填参数out_trade_no!');
  1539. return $result;
  1540. }
  1541. if(!array_key_exists('total_fee', $data)) {
  1542. $result = array('status'=>40010,'data'=>'提交被扫支付API接口中,缺少必填参数total_fee!');
  1543. return $result;
  1544. }
  1545. if(!array_key_exists('auth_code', $data)) {
  1546. $result = array('status'=>40010,'data'=>'提交被扫支付API接口中,缺少必填参数auth_code!');
  1547. return $result;
  1548. }
  1549. //组装参数
  1550. $data['spbill_create_ip'] = get_client_ip();//终端ip
  1551. $data['appid'] = $this->appid;//公众账号ID
  1552. $data['mch_id'] = $this->mch_id;//商户号
  1553. $data['nonce_str'] = $this->createNonceStr(32);//随机字符串
  1554. $data['sign'] = $this->makeSign($data);//签名
  1555. $xml = arr_xml($data);
  1556. $startTimeStamp = milli_time();//请求开始时间
  1557. $response = $this->postXml($xml, $url, false, $timeOut);
  1558. $datas = xml_arr($response);//将xml转为array
  1559. //判断请求结果是否成功
  1560. if($datas['return_code'] != 'SUCCESS'){
  1561. $result = array('status'=>40014,'data'=>$datas);
  1562. return $result;
  1563. }
  1564. //判断签名是否存在,及签名是否正确
  1565. if(!array_key_exists('sign', $datas) ){
  1566. $result = array('status'=>40011,'data'=>'签名错误!');
  1567. return $result;
  1568. }
  1569. $this->reportCostTime($url, $startTimeStamp, $datas);//上报请求花费时间
  1570. //返回结果
  1571. $result = array('status'=>1,'data'=>$datas);
  1572. return $result;
  1573. }
  1574. /**
  1575. * 微信扫码支付模式一成功返回参数包装
  1576. * @author bug <3164145970@qq.com>
  1577. * @createtime 2017-09-16 16:22:40
  1578. * @param $data 参数集
  1579. * @return [type] [description]
  1580. */
  1581. public function native_pkg($data){
  1582. $data['nonce_str'] =$this->createNonceStr(32);//随机字符串
  1583. $data['sign'] = $this->makeSign($data);//签名
  1584. return $data;
  1585. }
  1586. /**
  1587. * 撤销订单API接口,WxPayReverse中参数out_trade_no和transaction_id必须填写一个
  1588. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  1589. * @author bug <3164145970@qq.com>
  1590. * @createtime 2017-09-11 14:06:11
  1591. * @param $data 参数集
  1592. * @param $timeOut 超时
  1593. * @return 成功时返回,其他抛异常
  1594. */
  1595. public function reverse($data, $timeOut = 6){
  1596. $url = "https://api.mch.weixin.qq.com/secapi/pay/reverse";
  1597. //检测必填参数
  1598. if(!array_key_exists('out_trade_no', $data) && !array_key_exists('transaction_id', $data)) {
  1599. $result = array('status'=>40010,'data'=>'撤销订单API接口中,参数out_trade_no和transaction_id必须填写一个');
  1600. return $result;
  1601. }
  1602. //组装参数
  1603. $data['appid'] = $this->appid;//公众账号ID
  1604. $data['mch_id'] = $this->mch_id;//商户号
  1605. $data['nonce_str'] = $this->createNonceStr(32);//随机字符串
  1606. $data['sign'] = $this->makeSign($data);//签名
  1607. $xml = arr_xml($data);
  1608. $startTimeStamp = milli_time();//请求开始时间
  1609. $response = $this->postXml($xml, $url, false, $timeOut);
  1610. $datas = xml_arr($response);//将xml转为array
  1611. //判断请求结果是否成功
  1612. if($datas['return_code'] != 'SUCCESS'){
  1613. $result = array('status'=>40014,'data'=>$datas);
  1614. return $result;
  1615. }
  1616. //判断签名是否存在,及签名是否正确
  1617. if(!array_key_exists('sign', $datas) ){
  1618. $result = array('status'=>40011,'data'=>'签名错误!');
  1619. return $result;
  1620. }
  1621. $this->reportCostTime($url, $startTimeStamp, $datas);//上报请求花费时间
  1622. //返回结果
  1623. $result = array('status'=>1,'data'=>$datas);
  1624. return $result;
  1625. }
  1626. /**
  1627. * 测速上报,该方法内部封装在report中,使用时请注意异常流程
  1628. * interface_url、return_code、result_code、user_ip、execute_time_必填
  1629. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  1630. * @author bug <3164145970@qq.com>
  1631. * @createtime 2017-09-11 11:18:44
  1632. * @param $data 参数集
  1633. * @param $timeOut 超时
  1634. * @return 成功时返回,其他抛异常
  1635. */
  1636. private function report($data, $timeOut = 1)
  1637. {
  1638. $url = "https://api.mch.weixin.qq.com/payitil/report";
  1639. //检测必填参数
  1640. if(!array_key_exists('interface_url', $data)){
  1641. throw new Exception("接口URL,缺少必填参数interface_url!");
  1642. }
  1643. if(!array_key_exists('return_code', $data)){
  1644. throw new Exception("返回状态码,缺少必填参数return_code!");
  1645. }
  1646. if(!array_key_exists('result_code', $data)){
  1647. throw new Exception("业务结果,缺少必填参数result_code!");
  1648. }
  1649. if(!array_key_exists('user_ip', $data)){
  1650. throw new Exception("访问接口IP,缺少必填参数user_ip!");
  1651. }
  1652. if(!array_key_exists('execute_time_', $data)){
  1653. throw new Exception("接口耗时,缺少必填参数execute_time_!");
  1654. }
  1655. //组装参数
  1656. $data['appid'] = $this->appid;//公众账号ID
  1657. $data['mch_id'] = $this->mch_id;//商户号
  1658. $data['user_ip'] = get_client_ip();//终端ip
  1659. $data['time'] = date("YmdHis");//商户上报时间
  1660. $data['nonce_str'] = $this->createNonceStr(32);//随机字符串
  1661. $data['sign'] = $this->makeSign($data);//签名
  1662. $xml = arr_xml($data);
  1663. $startTimeStamp = milli_time();//请求开始时间
  1664. $response = $this->postXml($xml, $url, false, $timeOut);
  1665. return $response;
  1666. }
  1667. /**
  1668. * 生成二维码规则,模式一生成支付二维码
  1669. * appid、mchid、spbill_create_ip、nonce_str不需要填入2017-09-11 14:20:05
  1670. * @author bug <3164145970@qq.com>
  1671. * @createtime 2017-09-11 14:20:05
  1672. * @param $data 参数集
  1673. * @param $timeOut 超时
  1674. * @return 成功时返回,其他抛异常
  1675. */
  1676. private function bizpayurl($data, $timeOut = 6){
  1677. //检测必填参数
  1678. if(!array_key_exists('product_id', $data)) {
  1679. $result = array('status'=>40010,'data'=>'生成二维码,缺少必填参数product_id!');
  1680. return $result;
  1681. }
  1682. //组装参数
  1683. $data['appid'] = $this->appid;//公众账号ID
  1684. $data['mch_id'] = $this->mch_id;//商户号
  1685. $data['time_stamp'] = time();//时间戳
  1686. $data['nonce_str'] = $this->createNonceStr(32);//随机字符串
  1687. $data['sign'] = $this->makeSign($data);//签名
  1688. $result = array('status'=>1,'data'=>$data);
  1689. return $result;
  1690. }
  1691. /**
  1692. * 转换短链接
  1693. * 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),
  1694. * 减小二维码数据量,提升扫描速度和精确度。
  1695. * appid、mchid、spbill_create_ip、nonce_str不需要填入
  1696. * @author bug <3164145970@qq.com>
  1697. * @createtime 2017-09-11 14:41:02
  1698. * @param $data 参数集
  1699. * @param $timeOut 超时
  1700. * @return 成功时返回,其他抛异常
  1701. */
  1702. public function shorturl($data, $timeOut = 6){
  1703. $url = "https://api.mch.weixin.qq.com/tools/shorturl";
  1704. //检测必填参数
  1705. if(!array_key_exists('long_url', $data)) {
  1706. $result = array('status'=>40010,'data'=>'需要转换的URL,签名用原串,传输需URL encode!');
  1707. return $result;
  1708. }
  1709. //组装参数
  1710. $data['appid'] = $this->appid;//公众账号ID
  1711. $data['mch_id'] = $this->mch_id;//商户号
  1712. $data['nonce_str'] = $this->createNonceStr(32);//随机字符串
  1713. $data['sign'] = $this->makeSign($data);//签名
  1714. $xml = arr_xml($data);
  1715. $startTimeStamp = milli_time();//请求开始时间
  1716. $response = $this->postXml($xml, $url, false, $timeOut);
  1717. $datas = xml_arr($response);//将xml转为array
  1718. //判断请求结果是否成功
  1719. if($datas['return_code'] != 'SUCCESS'){
  1720. $result = array('status'=>40014,'data'=>$datas);
  1721. return $result;
  1722. }
  1723. //判断签名是否存在,及签名是否正确
  1724. if(!array_key_exists('sign', $datas) ){
  1725. $result = array('status'=>40011,'data'=>'签名错误!');
  1726. return $result;
  1727. }
  1728. $this->reportCostTime($url, $startTimeStamp, $datas);//上报请求花费时间
  1729. //返回结果
  1730. $result = array('status'=>1,'data'=>$datas);
  1731. return $result;
  1732. }
  1733. /**
  1734. * 支付结果通用通知
  1735. * 直接回调函数使用方法: notify(you_function);
  1736. * 回调类成员函数方法:notify(array($this, you_function));
  1737. * $callback 原型为:function function_name($data){}
  1738. * @author bug <3164145970@qq.com>
  1739. * @createtime 2017-09-11 14:41:02
  1740. * @param function $callback
  1741. */
  1742. public function notify(){
  1743. //获取通知的数据
  1744. $xml = file_get_contents('php://input');
  1745. //将xml转为array
  1746. $datas = xml_arr($xml);
  1747. //判断请求结果是否成功
  1748. if($datas['return_code'] != 'SUCCESS'){
  1749. $result = array('status'=>40014,'data'=>$datas['return_msg']);
  1750. return $result;
  1751. }
  1752. //判断业务结果是否成功
  1753. if($datas['result_code'] != 'SUCCESS'){
  1754. $result = array('status'=>40011,'data'=>$datas['err_code_des']);
  1755. return $result;
  1756. }
  1757. //判断签名是否存在
  1758. if(!array_key_exists('sign', $datas)){
  1759. $result = array('status'=>40011,'data'=>'缺少签名参数!');
  1760. return $result;
  1761. }
  1762. //签名验证
  1763. $data = $datas;
  1764. unset($data['sign']);
  1765. if($this->makeSign($data)!=$datas['sign']){
  1766. $result = array('status'=>40011,'data'=>'签名验证失败!');
  1767. return $result;
  1768. }
  1769. //返回结果
  1770. $result = array('status'=>1,'data'=>$datas);
  1771. return $result;
  1772. }
  1773. /**
  1774. * 退款结果通知
  1775. * @author bug <3164145970@qq.com>
  1776. * @createtime 2017-09-22 17:10:21
  1777. * @param array
  1778. */
  1779. public function refund_notify(){
  1780. //获取通知的数据
  1781. $xml = file_get_contents('php://input');
  1782. log_result("//////////// start //////////////");
  1783. log_result($xml);
  1784. //将xml转为array
  1785. $datas = xml_arr($xml);
  1786. log_result("datas:".json_encode($datas));
  1787. //判断请求结果是否成功
  1788. if($datas['return_code'] != 'SUCCESS'){
  1789. $result = array('status'=>40014,'data'=>$datas['return_msg']);
  1790. log_result($datas['return_code'] != 'SUCCESS');
  1791. return $result;
  1792. }
  1793. //对加密字符串进行解密
  1794. $req_info = base64_decode($datas['req_info']);//对加密串A做base64解码,得到加密串B
  1795. log_result("req_info:".$req_info);
  1796. $md5_key = md5($this->key);//对商户key做md5,得到32位小写key
  1797. log_result("md5_key:".$md5_key);
  1798. $info = aes_decode($req_info,$md5_key);//用key*对加密串B做AES-256-ECB解密
  1799. log_result("info:".$info);
  1800. $datas = array_merge($datas,$info);//合并数组 返回结果
  1801. log_result("//////////// end //////////////");
  1802. //返回结果
  1803. $result = array('status'=>1,'data'=>$datas);
  1804. return $result;
  1805. }
  1806. /**
  1807. * 共享收货地址js函数需要的参数
  1808. * @author bug <3164145970@qq.com>
  1809. * @createtime 2017-09-11 16:37:27
  1810. * @param
  1811. * @return 获取共享收货地址js函数需要的参数,json格式可以直接做参数使用
  1812. */
  1813. public function editAddressParameters(){
  1814. $data = array();
  1815. $data["appid"] = $this->appid;
  1816. $data["url"] = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
  1817. $time = time();
  1818. $data["timestamp"] = "$time";
  1819. $data["noncestr"] = "1234568";
  1820. $data["accesstoken"] = $this->access_token(false);
  1821. ksort($data);
  1822. $params = $this->toUrlParams($data);
  1823. $addrSign = sha1($params);
  1824. $afterData = array(
  1825. "addrSign" => $addrSign,
  1826. "signType" => "sha1",
  1827. "scope" => "jsapi_address",
  1828. "appId" => $this->appid,
  1829. "timeStamp" => $data["timestamp"],
  1830. "nonceStr" => $data["noncestr"]
  1831. );
  1832. $parameters = json_encode($afterData);
  1833. return $parameters;
  1834. }
  1835. /**
  1836. * 生成扫描支付URL,模式一
  1837. * @author bug <3164145970@qq.com>
  1838. * @createtime 2017-09-16 10:40:10
  1839. * @param $productId 产品编号
  1840. * @return [type] [description]
  1841. */
  1842. public function getPrePayUrl($productId)
  1843. {
  1844. $data['product_id'] = $productId;
  1845. $result = $this->bizpayurl($data);
  1846. if($result['status']!=1){
  1847. return $result;
  1848. }
  1849. $url = "weixin://wxpay/bizpayurl?" . $this->toUrlParams($result['data'],true);
  1850. $result['data'] = $url;
  1851. return $result;
  1852. }
  1853. /**
  1854. * 生成二维码
  1855. * @author bug <3164145970@qq.com>
  1856. * @createtime 2017-09-16 11:15:17
  1857. * @param $data 参数集
  1858. * @return [type] [description]
  1859. */
  1860. public function qrcode($data){
  1861. error_reporting(E_ERROR);
  1862. require_once 'phpqrcode/phpqrcode.php';
  1863. $url = urldecode($data);
  1864. header('Content-Type: image/png');
  1865. ob_clean();
  1866. $errorCorrectionLevel = "L"; // 纠错级别:L、M、Q、H
  1867. $matrixPointSize = "4"; //生成图片大小 :1到10
  1868. \QRcode::png($url, false, $errorCorrectionLevel, $matrixPointSize);
  1869. exit();
  1870. }
  1871. /**
  1872. * 格式化参数格式化成url参数
  1873. * @author bug <3164145970@qq.com>
  1874. * @createtime 2017-09-11 09:58:58
  1875. * @param $data 参数集
  1876. * @param $sign 是否考虑sign
  1877. * @return
  1878. */
  1879. private function toUrlParams($data,$sign=false)
  1880. {
  1881. $buff = "";
  1882. foreach ($data as $k => $v)
  1883. {
  1884. if($sign && $v != "" && !is_array($v)){
  1885. $buff .= $k . "=" . $v . "&";
  1886. }else{
  1887. if($k != "sign" && $v != "" && !is_array($v)){
  1888. $buff .= $k . "=" . $v . "&";
  1889. }
  1890. }
  1891. }
  1892. $buff = trim($buff, "&");
  1893. return $buff;
  1894. }
  1895. /**
  1896. * 生成签名
  1897. * @author bug <3164145970@qq.com>
  1898. * @createtime 2017-09-11 10:01:14
  1899. * @param
  1900. * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
  1901. */
  1902. public function makeSign($data)
  1903. {
  1904. //签名步骤一:按字典序排序参数
  1905. ksort($data);
  1906. $string = $this->toUrlParams($data);
  1907. //签名步骤二:在string后加入KEY
  1908. $string = $string . "&key=".$this->key;
  1909. //签名步骤三:MD5加密
  1910. $string = md5($string);
  1911. //签名步骤四:所有字符转为大写
  1912. $result = strtoupper($string);
  1913. return $result;
  1914. }
  1915. /**
  1916. * 以post方式提交xml到对应的接口url
  1917. * @author bug <3164145970@qq.com>
  1918. * @createtime 2017-09-11 10:08:11
  1919. * @param string $xml 需要post的xml数据
  1920. * @param string $url url
  1921. * @param bool $useCert 是否需要证书,默认不需要
  1922. * @param int $second url执行超时时间,默认30s
  1923. * @return [type] [description]
  1924. */
  1925. private function postXml($xml, $url, $useCert = false, $second = 30)
  1926. {
  1927. header("Content-type: text/html; charset=utf-8");
  1928. $ch = curl_init();
  1929. curl_setopt($ch, CURLOPT_TIMEOUT, $second);
  1930. curl_setopt($ch, CURLOPT_URL, $url);
  1931. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
  1932. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  1933. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  1934. curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
  1935. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  1936. curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
  1937. curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  1938. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  1939. //如果有配置代理这里就设置代理
  1940. if(self::CURL_PROXY_HOST != "0.0.0.0" && self::CURL_PROXY_PORT != 0){
  1941. curl_setopt($ch,CURLOPT_PROXY, self::CURL_PROXY_HOST);
  1942. curl_setopt($ch,CURLOPT_PROXYPORT, self::CURL_PROXY_PORT);
  1943. }
  1944. if($useCert == true){
  1945. //设置证书
  1946. //使用证书:cert 与 key 分别属于两个.pem文件
  1947. curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
  1948. curl_setopt($ch,CURLOPT_SSLCERT, dirname(__FILE__).self::SSLCERT_PATH);
  1949. curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
  1950. curl_setopt($ch,CURLOPT_SSLKEY, dirname(__FILE__).self::SSLKEY_PATH);
  1951. }
  1952. $data = curl_exec($ch);
  1953. if (curl_errno($ch)) {
  1954. return curl_error($ch);
  1955. }
  1956. curl_close($ch);
  1957. return $data;
  1958. // $ch = curl_init();
  1959. // //设置超时
  1960. // curl_setopt($ch, CURLOPT_TIMEOUT, $second);
  1961. // //如果有配置代理这里就设置代理
  1962. // if(self::CURL_PROXY_HOST != "0.0.0.0" && self::CURL_PROXY_PORT != 0){
  1963. // curl_setopt($ch,CURLOPT_PROXY, self::CURL_PROXY_HOST);
  1964. // curl_setopt($ch,CURLOPT_PROXYPORT, self::CURL_PROXY_PORT);
  1965. // }
  1966. // curl_setopt($ch,CURLOPT_URL, $url);
  1967. // curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
  1968. // curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
  1969. // //设置header
  1970. // curl_setopt($ch, CURLOPT_HEADER, FALSE);
  1971. // //要求结果为字符串且输出到屏幕上
  1972. // curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  1973. // if($useCert == true){
  1974. // //设置证书
  1975. // //使用证书:cert 与 key 分别属于两个.pem文件
  1976. // curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
  1977. // curl_setopt($ch,CURLOPT_SSLCERT, dirname(__FILE__).self::SSLCERT_PATH);
  1978. // curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
  1979. // curl_setopt($ch,CURLOPT_SSLKEY, dirname(__FILE__).self::SSLKEY_PATH);
  1980. // }
  1981. // //post提交方式
  1982. // curl_setopt($ch, CURLOPT_POST, TRUE);
  1983. // curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  1984. //运行curl
  1985. // $data = curl_exec($ch);
  1986. //返回结果
  1987. // if($data){
  1988. // curl_close($ch);
  1989. // return $data;
  1990. // } else {
  1991. // $error = curl_errno($ch);
  1992. // curl_close($ch);
  1993. // return $error;
  1994. // }
  1995. }
  1996. /**
  1997. * 上报数据, 上报的时候将屏蔽所有异常流程
  1998. * @author bug <3164145970@qq.com>
  1999. * @createtime 2017-09-11 11:10:20
  2000. * @param string $usrl
  2001. * @param int $startTimeStamp
  2002. * @param array $data
  2003. * @return [type] [description]
  2004. */
  2005. private function reportCostTime($url, $startTimeStamp, $data)
  2006. {
  2007. //如果不需要上报数据
  2008. if(self::REPORT_LEVENL == 0){
  2009. return;
  2010. }
  2011. //如果仅失败上报
  2012. if(self::REPORT_LEVENL == 1 &&
  2013. array_key_exists("return_code", $data) &&
  2014. $data["return_code"] == "SUCCESS" &&
  2015. array_key_exists("result_code", $data) &&
  2016. $data["result_code"] == "SUCCESS")
  2017. {
  2018. return;
  2019. }
  2020. //上报逻辑
  2021. $endTimeStamp = milli_time();
  2022. $result['interface_url'] = $url;
  2023. $result['execute_time_'] = $endTimeStamp - $startTimeStamp;
  2024. //返回状态码
  2025. if(array_key_exists("return_code", $data)){
  2026. $result['return_code'] = $data["return_code"];
  2027. }
  2028. //返回信息
  2029. if(array_key_exists("return_msg", $data)){
  2030. $result['return_msg'] = $data["return_msg"];
  2031. }
  2032. //业务结果
  2033. if(array_key_exists("result_code", $data)){
  2034. $result['result_code'] = $data["result_code"];
  2035. }
  2036. //错误代码
  2037. if(array_key_exists("err_code", $data)){
  2038. $result['err_code'] = $data["err_code"];
  2039. }
  2040. //错误代码描述
  2041. if(array_key_exists("err_code_des", $data)){
  2042. $result['err_code_des'] = $data["err_code_des"];
  2043. }
  2044. //商户订单号
  2045. if(array_key_exists("out_trade_no", $data)){
  2046. $result['out_trade_no'] = $data["out_trade_no"];
  2047. }
  2048. //设备号
  2049. if(array_key_exists("device_info", $data)){
  2050. $result['device_info'] = $data["device_info"];
  2051. }
  2052. try{
  2053. $this->report($result);
  2054. } catch (Exception $e){
  2055. //不做任何处理
  2056. }
  2057. }
  2058. /**********************微信支付 结束********/
  2059. /**********************微信卡券 开始********/
  2060. /**
  2061. * 微信卡券获取api_ticket
  2062. * @author bug <3164145970@qq.com>
  2063. * @createtime 2017-10-17 13:30:13
  2064. * @return api_ticket string 微信卡券调用凭证
  2065. */
  2066. private function api_ticket() {
  2067. // api_ticket 应该全局存储与更新,以下代码以写入到文件中做示例
  2068. $data = json_decode(file_get_contents(dirname(__FILE__)."/json/api_ticket.json"));
  2069. if ($data->expire_time < time()) {
  2070. $access_token = $this->access_token(false);
  2071. if($access_token['status']!=1 && $access_token['status']!=2){
  2072. return $access_token;
  2073. }
  2074. $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card&access_token=".$access_token['data'];
  2075. $res = json_decode(https_get($url));
  2076. if(!isset($res->ticket)){
  2077. $access_token = $this->access_token(true);
  2078. $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card&access_token=".$access_token['data'];
  2079. $res = json_decode(https_get($url));
  2080. }
  2081. $ticket = $res->ticket;
  2082. if ($ticket) {
  2083. $data->expire_time = time() + 7200;
  2084. $data->ticket = $ticket;
  2085. $fp = fopen(dirname(__FILE__)."/json/api_ticket.json", "w");
  2086. fwrite($fp, json_encode($data));
  2087. fclose($fp);
  2088. }
  2089. } else {
  2090. $ticket = $data->ticket;
  2091. }
  2092. return $ticket;
  2093. }
  2094. /**
  2095. * 卡券签名
  2096. * @author bug <3164145970@qq.com>
  2097. * @createtime 2017-10-17 16:43:44
  2098. * @param
  2099. * @return [type] [description]
  2100. */
  2101. public function card_sign($card_id){
  2102. $api_ticket = $this->api_ticket();
  2103. $timestamp = time();
  2104. $nonce_str = $this->createNonceStr();
  2105. $arr = array($api_ticket,$timestamp,$nonce_str,$card_id);
  2106. sort($arr, SORT_STRING);
  2107. $signature = sha1(implode($arr));
  2108. $signPackage = array(
  2109. "timestamp" => $timestamp,
  2110. "nonce_str" => $nonce_str,
  2111. "signature" => $signature,
  2112. );
  2113. return $signPackage;
  2114. }
  2115. /**
  2116. * 查看卡券详情
  2117. * @author bug <3164145970@qq.com>
  2118. * @createtime 2017-10-17 13:59:51
  2119. * @param post_data 请求数据 卡券ID
  2120. * @return json 请求结果
  2121. */
  2122. public function get_card($post_data){
  2123. //获取access_token
  2124. $access_token= $this->access_token(false);
  2125. if($access_token['status']!=1 && $access_token['status']!=2){
  2126. return $access_token;
  2127. }
  2128. //配置请求url,加入access_token参数
  2129. $url = 'https://api.weixin.qq.com/card/get?access_token='.$access_token['data'];
  2130. //将json数组转换成字符串数组
  2131. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  2132. //获取请求结果,并将请求结果转换成json
  2133. $data = json_decode(https_request($url,$post_data),true);
  2134. //access_token 过期重新获取并重新回调当前函数
  2135. if($data['errcode']==42001 || $data['errcode']==40001){
  2136. $access_token = $this->access_token(true);
  2137. return $this->get_card($post_data);
  2138. }
  2139. //返回结果
  2140. if($data['errcode']==0&&$data['errmsg']=='ok'){
  2141. $result = array('status'=>1,'data'=>$data);
  2142. return $result;
  2143. }
  2144. $result = array('status'=>40014,'data'=>$data);
  2145. return $result;
  2146. }
  2147. /**
  2148. * 批量查询卡券列表
  2149. * @author bug <3164145970@qq.com>
  2150. * @createtime 2017-10-17 14:02:10
  2151. * @param post_data 请求数据
  2152. * offset 查询卡列表的起始偏移量,从0开始,即offset: 5是指从从列表里的第六个开始读取。
  2153. * count 需要查询的卡片的数量(数量最大50)。
  2154. * status_list 支持开发者拉出指定状态的卡券列表“CARD_STATUS_NOT_VERIFY”,待审核;“CARD_STATUS_VERIFY_FAIL”,审核失败;“CARD_STATUS_VERIFY_OK”,通过审核;“CARD_STATUS_DELETE”,卡券被商户删除;“CARD_STATUS_DISPATCH”,在公众平台投放过的卡券;
  2155. * @return json 请求结果
  2156. */
  2157. public function card_list($post_data){
  2158. //获取access_token
  2159. $access_token= $this->access_token(false);
  2160. if($access_token['status']!=1 && $access_token['status']!=2){
  2161. return $access_token;
  2162. }
  2163. //配置请求url,加入access_token参数
  2164. $url = 'https://api.weixin.qq.com/card/batchget?access_token='.$access_token['data'];
  2165. //将json数组转换成字符串数组
  2166. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  2167. //获取请求结果,并将请求结果转换成json
  2168. $data = json_decode(https_request($url,$post_data),true);
  2169. //access_token 过期重新获取并重新回调当前函数
  2170. if($data['errcode']==42001 || $data['errcode']==40001){
  2171. $access_token = $this->access_token(true);
  2172. return $this->get_card($card_id);
  2173. }
  2174. //返回结果
  2175. if($data['errcode']==0&&$data['errmsg']=='ok'){
  2176. $result = array('status'=>1,'data'=>$data);
  2177. return $result;
  2178. }
  2179. $result = array('status'=>40014,'data'=>$data);
  2180. return $result;
  2181. }
  2182. /**************************微信会员卡 开始****************************/
  2183. /**
  2184. * 拉取会员信息(积分查询)接口
  2185. * @author bug <3164145970@qq.com>
  2186. * @createtime 2017-10-27 09:24:15
  2187. * @param card_id 查询会员卡的cardid
  2188. * @param code 所查询用户领取到的code值
  2189. * @return [type] [description]
  2190. */
  2191. public function membercard_info($post_data){
  2192. //获取access_token
  2193. $access_token= $this->access_token(false);
  2194. if($access_token['status']!=1 && $access_token['status']!=2){
  2195. return $access_token;
  2196. }
  2197. //配置请求url,加入access_token参数
  2198. $url = 'https://api.weixin.qq.com/card/membercard/userinfo/get?access_token='.$access_token['data'];
  2199. //将json数组转换成字符串数组
  2200. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  2201. //获取请求结果,并将请求结果转换成json
  2202. $data = json_decode(https_request($url,$post_data),true);
  2203. //access_token 过期重新获取并重新回调当前函数
  2204. if($data['errcode']==42001 || $data['errcode']==40001){
  2205. $access_token = $this->access_token(true);
  2206. return $this->membercard_info($post_data);
  2207. }
  2208. //返回结果
  2209. if($data['errcode']==0&&$data['errmsg']=='ok'){
  2210. $result = array('status'=>1,'data'=>$data);
  2211. return $result;
  2212. }
  2213. $result = array('status'=>40014,'data'=>$data);
  2214. return $result;
  2215. }
  2216. /**
  2217. * 更新会员信息
  2218. * @author bug <3164145970@qq.com>
  2219. * @createtime 2017-10-27 15:08:46
  2220. * @param
  2221. * @return [type] [description]
  2222. */
  2223. public function membercard_update($post_data){
  2224. //获取access_token
  2225. $access_token= $this->access_token(false);
  2226. if($access_token['status']!=1 && $access_token['status']!=2){
  2227. return $access_token;
  2228. }
  2229. //配置请求url,加入access_token参数
  2230. $url = 'https://api.weixin.qq.com/card/membercard/updateuser?access_token='.$access_token['data'];
  2231. //将json数组转换成字符串数组
  2232. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  2233. //获取请求结果,并将请求结果转换成json
  2234. $data = json_decode(https_request($url,$post_data),true);
  2235. //access_token 过期重新获取并重新回调当前函数
  2236. if($data['errcode']==42001 || $data['errcode']==40001){
  2237. $access_token = $this->access_token(true);
  2238. return $this->membercard_update($post_data);
  2239. }
  2240. //返回结果
  2241. if($data['errcode']==0&&$data['errmsg']=='ok'){
  2242. $result = array('status'=>1,'data'=>$data);
  2243. return $result;
  2244. }
  2245. $result = array('status'=>40014,'data'=>$data);
  2246. return $result;
  2247. }
  2248. /**
  2249. * 激活会员卡
  2250. * @author bug <3164145970@qq.com>
  2251. * @createtime 2017-10-27 11:45:44
  2252. * @param
  2253. * @return [type] [description]
  2254. */
  2255. public function membercard_active($post_data){
  2256. //获取access_token
  2257. $access_token= $this->access_token(false);
  2258. if($access_token['status']!=1 && $access_token['status']!=2){
  2259. return $access_token;
  2260. }
  2261. //配置请求url,加入access_token参数
  2262. $url = 'https://api.weixin.qq.com/card/membercard/activate?access_token='.$access_token['data'];
  2263. //将json数组转换成字符串数组
  2264. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  2265. //获取请求结果,并将请求结果转换成json
  2266. $data = json_decode(https_request($url,$post_data),true);
  2267. //access_token 过期重新获取并重新回调当前函数
  2268. if($data['errcode']==42001 || $data['errcode']==40001){
  2269. $access_token = $this->access_token(true);
  2270. return $this->membercard_active($post_data);
  2271. }
  2272. //返回结果
  2273. if($data['errcode']==0&&$data['errmsg']=='ok'){
  2274. $result = array('status'=>1,'data'=>$data);
  2275. return $result;
  2276. }
  2277. $result = array('status'=>40014,'data'=>$data);
  2278. return $result;
  2279. }
  2280. /**
  2281. * 设置开卡字段接口
  2282. * @author bug <3164145970@qq.com>
  2283. * @createtime 2017-10-27 13:54:02
  2284. * @param
  2285. * @return [type] [description]
  2286. */
  2287. public function activateuserform($post_data){
  2288. //获取access_token
  2289. $access_token= $this->access_token(false);
  2290. if($access_token['status']!=1 && $access_token['status']!=2){
  2291. return $access_token;
  2292. }
  2293. //配置请求url,加入access_token参数
  2294. $url = 'https://api.weixin.qq.com/card/membercard/activateuserform/set?access_token='.$access_token['data'];
  2295. //将json数组转换成字符串数组
  2296. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  2297. //获取请求结果,并将请求结果转换成json
  2298. $data = json_decode(https_request($url,$post_data),true);
  2299. //access_token 过期重新获取并重新回调当前函数
  2300. if($data['errcode']==42001 || $data['errcode']==40001){
  2301. $access_token = $this->access_token(true);
  2302. return $this->activateuserform($post_data);
  2303. }
  2304. //返回结果
  2305. if($data['errcode']==0&&$data['errmsg']=='ok'){
  2306. $result = array('status'=>1,'data'=>$data);
  2307. return $result;
  2308. }
  2309. $result = array('status'=>40014,'data'=>$data);
  2310. return $result;
  2311. }
  2312. /**
  2313. * 更改会员卡信息接口
  2314. * @author bug <3164145970@qq.com>
  2315. * @createtime 2017-10-27 09:36:18
  2316. * @param 提交修改的数据集
  2317. * @return [type] [description]
  2318. */
  2319. public function card_update($post_data){
  2320. //获取access_token
  2321. $access_token= $this->access_token(false);
  2322. if($access_token['status']!=1 && $access_token['status']!=2){
  2323. return $access_token;
  2324. }
  2325. //配置请求url,加入access_token参数
  2326. $url = 'https://api.weixin.qq.com/card/update?access_token='.$access_token['data'];
  2327. //将json数组转换成字符串数组
  2328. $post_data = json_encode($post_data,JSON_UNESCAPED_UNICODE);
  2329. //获取请求结果,并将请求结果转换成json
  2330. $data = json_decode(https_request($url,$post_data),true);
  2331. //access_token 过期重新获取并重新回调当前函数
  2332. if($data['errcode']==42001 || $data['errcode']==40001){
  2333. $access_token = $this->access_token(true);
  2334. return $this->card_update($post_data);
  2335. }
  2336. //返回结果
  2337. if($data['errcode']==0&&$data['errmsg']=='ok'){
  2338. $result = array('status'=>1,'data'=>$data);
  2339. return $result;
  2340. }
  2341. $result = array('status'=>40014,'data'=>$data);
  2342. return $result;
  2343. }
  2344. /**************************微信会员卡 结束****************************/
  2345. /**********************微信卡券 结束********/
  2346. }
  2347. ?>
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议