├── .gitignore ├── LICENSE ├── README.md └── code ├── __config__.php ├── ydwx ├── agentauth.php ├── auth-agent.php ├── auth-crop.php ├── auth.php ├── baseauth-agent.php ├── baseauth-crop.php ├── baseauth.php ├── card.php ├── functions │ ├── agent.php │ ├── base.php │ ├── card-hasmp.php │ ├── card-notmp.php │ ├── card.php │ ├── js.php │ ├── kf.php │ ├── meida.php │ ├── menu.php │ ├── msgs.php │ ├── packet.php │ ├── pay.php │ ├── poi.php │ ├── qy-user.php │ ├── user.php │ ├── yaotv.php │ └── zb.php ├── index-agent.php ├── index-crop.php ├── index.php ├── libs │ ├── const.php │ ├── errorCode.php │ ├── model.php │ ├── pkcs7Encoder.php │ ├── sha1.php │ ├── wxBizMsgCrypt.php │ ├── xmlparse.php │ ├── ydhttp.php │ └── ydwxhook.php ├── models │ ├── base.php │ ├── card.php │ ├── event.php │ ├── meida.php │ ├── msg.php │ ├── packet.php │ ├── pay.php │ ├── poi.php │ ├── qy-user.php │ ├── user.php │ ├── yaotv.php │ └── zb.php ├── packet.php ├── pay-notify.php ├── pay.php ├── refresh-agent.php ├── refresh-crop.php ├── refresh.php ├── test.php ├── webauth.php ├── yaotv_auth.php ├── yaotv_draw.php ├── yaotv_draw_result.php └── yaotv_hb.php └── ydwxhooks ├── agent.php ├── auth.php ├── basic.php ├── card.php ├── log.php ├── menu.php ├── msgs.php ├── packet.php ├── pay.php ├── poi.php └── zb.php /.gitignore: -------------------------------------------------------------------------------- 1 | /.buildpath 2 | /.project 3 | /.settings/org.eclipse.core.resources.prefs 4 | /.settings/org.eclipse.php.core.prefs 5 | /.settings/org.eclipse.wst.common.project.facet.core.xml 6 | /nbproject/private/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ydwx 开发框架 2 | 3 | ## 如何使用 4 | 5 | 1. 拷贝code中的内容到你的项目,ydwx中包含了库代码和一些直接访问入口,这些访问入口主要提供给微信回调用的,ydwxhooks是你要关系的需要注册的回调 6 | 2. 根据你的公众号情况,修改__config__.php中的配置,里面的配置项有完整的注释 7 | 3. 对你感兴趣的微信事件注册hook处理函数,并把这些函数文件放在code/ydwxhooks中,里面的文件任意组织,ydwx会自动包含他们 8 | 4. 剩下的只需要到微信上配置一下就可以了。 9 | 5. 配置access token自动刷新,在你的服务器上配置定时刷新,如cron, 10 | refresh.php 刷新普通公众号 11 | refresh-crop.php 刷新企业微信 12 | refresh-agent.php 刷新第三方公众平台 13 | 14 | *ydwx的目的是把微信的交互细节帮你搞定,你只需要填写相关申请到的key然后注册你关心的事件hook就可以了* 15 | 16 | ## 进一步了解 https://github.com/ydhl/ydwx/wiki 17 | 18 | 欢迎大家把遇到的问题在issue提出来 19 | -------------------------------------------------------------------------------- /code/__config__.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /code/ydwx/agentauth.php: -------------------------------------------------------------------------------- 1 | getMessage())); 20 | die(); 21 | } 22 | try{ 23 | $auth_info->query = $_GET; 24 | YDWXHook::do_hook(YDWXHook::AUTH_AGENT_SUCCESS, 25 | array($auth_info, ydwx_agent_get_auth_account($auth_info->authorizer_appid))); 26 | }catch (\Exception $e){ 27 | YDWXHook::do_hook(YDWXHook::AUTH_FAIL, YDWXAuthFailResponse::errMsg($e->getMessage())); 28 | die(); 29 | } -------------------------------------------------------------------------------- /code/ydwx/auth-agent.php: -------------------------------------------------------------------------------- 1 | ".$_GET['realappid']; 26 | } 27 | 28 | $state = urlencode(base64_encode($state)); 29 | 30 | $redirect = YDWX_SITE_URL.'ydwx/auth-agent.php'; 31 | 32 | $isAgent = true; 33 | $appid = $_GET['appid']; 34 | $authorize_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" 35 | .$appid."&redirect_uri=".urlencode($redirect)."&response_type=code&scope=snsapi_userinfo&state={$state}&component_appid=" 36 | .YDWX_WEIXIN_COMPONENT_APP_ID."#wechat_redirect"; 37 | 38 | $access_token_url = "https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=" 39 | .$appid."&code=%s&grant_type=authorization_code&component_appid=".YDWX_WEIXIN_COMPONENT_APP_ID 40 | ."&component_access_token=".YDWXHook::do_hook(YDWXHook::GET_AGENT_ACCESS_TOKEN); 41 | 42 | 43 | //第一步,引导用户到微信页面授权 44 | if( ! @$_GET['code'] && ! @$_GET['state']){ 45 | ob_clean(); 46 | header("Location: {$authorize_url}"); 47 | die; 48 | } 49 | 50 | //用户取消授权后返回本页面 51 | if( ! @$_GET['code'] && @$_GET['state']){ 52 | YDWXHook::do_hook(YDWXHook::AUTH_CANCEL); 53 | die; 54 | } 55 | 56 | $http = new YDHttp(); 57 | $info = json_decode($http->get(sprintf($access_token_url, $_GET['code'])), true); 58 | 59 | if( !@$info['openid']){ 60 | YDWXHook::do_hook(YDWXHook::AUTH_FAIL, YDWXAuthFailResponse::errMsg($info['errmsg'], $info['errcode'])); 61 | die; 62 | } 63 | 64 | try{ 65 | $state = base64_decode($_GET['state']); 66 | $rst = preg_match('/>(?P.+)$/', $state, $matches); 67 | if($rst){ 68 | $state = preg_replace('/>.+$/', "", $state); 69 | $appid = $matches['realappid']; 70 | } 71 | $user = ydwx_sns_userinfo($info['access_token'], $info['openid']); 72 | $user->state = $state; 73 | $user->appid = $appid; 74 | YDWXHook::do_hook(YDWXHook::AUTH_INAPP_SUCCESS, $user); 75 | }catch (\Exception $e){ 76 | YDWXHook::do_hook(YDWXHook::AUTH_FAIL, YDWXAuthFailResponse::errMsg($e->getMessage(), $e->getCode())); 77 | } 78 | die(); 79 | 80 | -------------------------------------------------------------------------------- /code/ydwx/auth-crop.php: -------------------------------------------------------------------------------- 1 | get(sprintf($access_token_url, $_GET['code'])); 52 | $info = json_decode($accesstoken, true); 53 | 54 | if( !@$info['openid']){ 55 | YDWXHook::do_hook(YDWXHook::AUTH_FAIL, YDWXAuthFailResponse::errMsg($info['errmsg'].$accesstoken, $info['errcode'])); 56 | die; 57 | } 58 | 59 | try{ 60 | $state = base64_decode($_GET['state']); 61 | $user = ydwx_sns_userinfo($info['access_token'], $info['openid']); 62 | $user->state = $state; 63 | YDWXHook::do_hook(YDWXHook::AUTH_INAPP_SUCCESS, $user); 64 | }catch (\Exception $e){ 65 | YDWXHook::do_hook(YDWXHook::AUTH_FAIL, YDWXAuthFailResponse::errMsg($e->getMessage(), $e->getCode())); 66 | } 67 | die(); 68 | -------------------------------------------------------------------------------- /code/ydwx/baseauth-agent.php: -------------------------------------------------------------------------------- 1 | get(sprintf($access_token_url, $_GET['code'])), true); 49 | 50 | if( !@$info['openid']){ 51 | YDWXHook::do_hook(YDWXHook::AUTH_FAIL, YDWXAuthFailResponse::errMsg($info['errmsg'], $info['errcode'])); 52 | die; 53 | } 54 | 55 | $access_token = YDWXHook::do_hook(YDWXHook::GET_HOST_ACCESS_TOKEN, $appid); 56 | 57 | 58 | if($access_token){ 59 | try{ 60 | $user = ydwx_user_info($access_token, $info['openid']); 61 | }catch (\Exception $e){ 62 | $user = new YDWXSubscribeUser(); 63 | $user->openid = $info['openid']; 64 | } 65 | }else{ 66 | $user = new YDWXSubscribeUser(); 67 | $user->openid = $info['openid']; 68 | } 69 | 70 | $user->appid = $appid; 71 | $user->state = $_GET['state']; 72 | YDWXHook::do_hook(YDWXHook::AUTH_INAPP_SUCCESS, $user); 73 | die(); -------------------------------------------------------------------------------- /code/ydwx/baseauth-crop.php: -------------------------------------------------------------------------------- 1 | get(sprintf($access_token_url, $_GET['code'])), true); 47 | 48 | if( !@$info['openid']){ 49 | YDWXHook::do_hook(YDWXHook::AUTH_FAIL, YDWXAuthFailResponse::errMsg($info['errmsg'], $info['errcode'])); 50 | die; 51 | } 52 | 53 | $access_token = YDWXHook::do_hook(YDWXHook::GET_ACCESS_TOKEN); 54 | 55 | if($access_token){ 56 | try{ 57 | $user = ydwx_user_info($access_token, $info['openid']); 58 | }catch (\Exception $e){ 59 | $user = new YDWXSubscribeUser(); 60 | $user->openid = $info['openid']; 61 | } 62 | }else{ 63 | $user = new YDWXSubscribeUser(); 64 | $user->openid = $info['openid']; 65 | } 66 | $user->appid = $appid; 67 | $user->state = $_GET['state']; 68 | YDWXHook::do_hook(YDWXHook::AUTH_INAPP_SUCCESS, $user); 69 | die(); 70 | -------------------------------------------------------------------------------- /code/ydwx/card.php: -------------------------------------------------------------------------------- 1 | $shopId, 34 | "cardType" => $cardType, 35 | "cardId" => $cardId, 36 | "nonceStr" => $nonceStr, 37 | "time" => $time, 38 | "cardSign" => $cardSignStr, 39 | ))); 40 | die; 41 | } 42 | 43 | 44 | if($action == "addCard"){ 45 | $exts = $_POST['exts']; 46 | $appid = $_POST['appid']; 47 | if($appid){ 48 | $card_jsapi_ticket = YDWXHook::do_hook(YDWXHook::GET_HOST_CARD_JSAPI_TICKET, $appid); 49 | }else{ 50 | $card_jsapi_ticket = YDWXHook::do_hook(YDWXHook::GET_CARD_JSAPI_TICKET); 51 | } 52 | $array = array(); 53 | 54 | foreach ($exts as $ext){ 55 | $extObj = new YDWXCardExt(); 56 | $extObj->cardId = $ext['cardId']; 57 | $extObj->code = @$ext['code']; 58 | $extObj->openid = @$ext['openid']; 59 | $extObj->jsApiTicket = $card_jsapi_ticket; 60 | $array[] = $extObj->toArray(); 61 | } 62 | echo json_encode(ydwx_success($array)); 63 | die; 64 | } 65 | ?> -------------------------------------------------------------------------------- /code/ydwx/functions/agent.php: -------------------------------------------------------------------------------- 1 | query获取 6 | */ 7 | function ydwx_agent_create_preauthcode($queryString=""){ 8 | $accessToken = YDWXHook::do_hook(YDWXHook::GET_AGENT_ACCESS_TOKEN); 9 | $http = new YDHttp(); 10 | $info = $http->post(YDWX_WEIXIN_BASE_URL."component/api_create_preauthcode?component_access_token={$accessToken}", 11 | ydwx_json_encode(array("component_appid"=>YDWX_WEIXIN_COMPONENT_APP_ID))); 12 | $msg = new YDWXResponse($info); 13 | if( ! $msg->isSuccess()){ 14 | throw new YDWXException($msg->errmsg.$msg->errcode, $msg->errcode); 15 | } 16 | $queryString = trim($queryString,"?"); 17 | return "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=" 18 | .YDWX_WEIXIN_COMPONENT_APP_ID."&pre_auth_code=".$msg->pre_auth_code 19 | ."&redirect_uri=".urlencode(YDWX_SITE_URL."ydwx/agentauth.php".($queryString ? "?{$queryString}" :"")); 20 | } 21 | 22 | 23 | /** 24 | * 得到授权码后,第三方平台方可以使用授权码换取授权公众号的授权信息,再通过公众号授权信息调用公众号相关API 25 | * @param unknown $auth_code 26 | * @return YDWXAgentAuthInfo 27 | */ 28 | function ydwx_agent_query_auth($auth_code){ 29 | $accessToken = YDWXHook::do_hook(YDWXHook::GET_AGENT_ACCESS_TOKEN); 30 | $http = new YDHttp(); 31 | $info = $http->post(YDWX_WEIXIN_BASE_URL."component/api_query_auth?component_access_token={$accessToken}", 32 | ydwx_json_encode(array( 33 | "component_appid"=>YDWX_WEIXIN_COMPONENT_APP_ID, 34 | "authorization_code"=>$auth_code))); 35 | $msg = new YDWXAgentAuthInfo($info); 36 | if( $msg->isSuccess()){ 37 | return $msg; 38 | } 39 | throw new YDWXException($msg->errmsg); 40 | } 41 | 42 | /** 43 | * 获取授权的公众号信息 44 | * 45 | * @param unknown $appid 46 | * @throws YDWXException 47 | * @return YDWXAgentAuthInfo 48 | */ 49 | function ydwx_agent_get_auth_account($appid){ 50 | $accessToken = YDWXHook::do_hook(YDWXHook::GET_AGENT_ACCESS_TOKEN); 51 | $http = new YDHttp(); 52 | $info = $http->post(YDWX_WEIXIN_BASE_URL."component/api_get_authorizer_info?component_access_token={$accessToken}", 53 | ydwx_json_encode(array( 54 | "component_appid" =>YDWX_WEIXIN_COMPONENT_APP_ID, 55 | "authorizer_appid"=>$appid))); 56 | $msg = new YDWXAgentAuthUser($info); 57 | if( $msg->isSuccess()){ 58 | return $msg; 59 | } 60 | throw new YDWXException($msg->errmsg); 61 | } 62 | 63 | /** 64 | * 获取第三方平台access_token 65 | * 66 | * @param unknown $verify_ticket 是微信没10分钟推送得到,需要注册hook 67 | * @throws YDWXException 68 | * @return YDWXAccessTokenResponse 69 | */ 70 | function ydwx_agent_access_token($verify_ticket){ 71 | $http = new YDHttp(); 72 | $info = $http->post(YDWX_WEIXIN_BASE_URL."component/api_component_token", 73 | ydwx_json_encode(array( 74 | "component_appid" =>YDWX_WEIXIN_COMPONENT_APP_ID, 75 | "component_appsecret"=>YDWX_WEIXIN_COMPONENT_APP_SECRET, 76 | "component_verify_ticket"=>$verify_ticket))); 77 | $msg = new YDWXAccessTokenResponse($info); 78 | $msg->access_token = $msg->component_access_token; 79 | if( $msg->isSuccess()){ 80 | return $msg; 81 | } 82 | throw new YDWXException($msg->errmsg); 83 | } 84 | 85 | /** 86 | * 刷新授权的公众号的令牌 87 | * @param 授权公众号的 appid 88 | * @param 授权公众号的 refreshToken 89 | * @return string access token 90 | */ 91 | function ydwx_agent_refresh_auth_token($appid, $refreshToken){ 92 | $accessToken = YDWXHook::do_hook(YDWXHook::GET_AGENT_ACCESS_TOKEN); 93 | $http = new YDHttp(); 94 | $info = $http->post(YDWX_WEIXIN_BASE_URL."component/api_authorizer_token?component_access_token={$accessToken}", 95 | ydwx_json_encode(array( 96 | "component_appid" => YDWX_WEIXIN_COMPONENT_APP_ID, 97 | "authorizer_appid" => $appid, 98 | "authorizer_refresh_token"=>$refreshToken 99 | ))); 100 | $msg = new YDWXAuthorizerTokenResponse($info); 101 | if( $msg->isSuccess()){ 102 | return $msg; 103 | } 104 | throw new YDWXException($msg->errmsg); 105 | } 106 | 107 | /** 108 | * 该 API 用于第三方平台确认接受公众号将某权限集高级权限的授权 109 | * @param unknown $appid 110 | * @param unknown $funcscope_category_id 功能集合,见YDWX_FUNC_XX常量 111 | * @param boolean $confirm true 确认 false取消 112 | * @throws YDWXException 113 | * @return boolean 114 | */ 115 | function ydwx_agent_confirm_authorization($appid, $funcscope_category_id, $confirm){ 116 | $accessToken = YDWXHook::do_hook(YDWXHook::GET_AGENT_ACCESS_TOKEN); 117 | $http = new YDHttp(); 118 | $info = $http->post(YDWX_WEIXIN_BASE_URL."component/api_confirm_authorization?component_access_token={$accessToken}", 119 | ydwx_json_encode(array( 120 | "component_appid" => YDWX_WEIXIN_COMPONENT_APP_ID, 121 | "authorizer_appid" => $appid, 122 | "funcscope_category_id"=>$funcscope_category_id, 123 | "confirm_value" => $confirm ? 1 :2 124 | ))); 125 | $msg = new YDWXResponse($info); 126 | if( $msg->isSuccess()){ 127 | return true; 128 | } 129 | throw new YDWXException($msg->errmsg); 130 | } -------------------------------------------------------------------------------- /code/ydwx/functions/base.php: -------------------------------------------------------------------------------- 1 | $value){ 9 | if(is_array($value)){ 10 | $temp[$key] = ydwx_url_encode($value); 11 | }else if(is_numeric($value) || is_bool($value)){ 12 | $temp[$key] = $value; 13 | }else{ 14 | $temp[$key] = str_replace("%22",'"',urlencode($value)); 15 | } 16 | } 17 | return $temp; 18 | } 19 | function ydwx_error($message="", $code=null){ 20 | return array('success'=> false, "data"=>null,"msg"=>$message); 21 | } 22 | 23 | function ydwx_success($data=null){ 24 | return array('success'=> true, "data"=>$data,"msg"=>null); 25 | } 26 | 27 | function ydwx_qy_refresh_access_token($appid, $appsecret){ 28 | $http = new YDHttp(); 29 | $msg = $http->get(YDWX_WEIXIN_QY_BASE_URL."gettoken?corpid=".$appid."&corpsecret=".$appsecret); 30 | $accessToken = new YDWXAccessTokenResponse($msg); 31 | if($accessToken->isSuccess()) { 32 | return $accessToken; 33 | } 34 | throw new YDWXException($accessToken->errmsg, $accessToken->errcode); 35 | } 36 | 37 | function ydwx_qy_refresh_jsapi_ticket($token){ 38 | $http = new YDHttp(); 39 | $msg = $http->get(YDWX_WEIXIN_QY_BASE_URL."get_jsapi_ticket?access_token=".$token); 40 | $ticket = new YDWXJsapiTicketResponse($msg); 41 | if($ticket->isSuccess()) { 42 | return $ticket; 43 | } 44 | throw new YDWXException($ticket->errmsg, $ticket->errcode); 45 | } 46 | 47 | /** 48 | * 微信oauth登录通过code获取access token 49 | * 50 | * @param unknown $appid 51 | * @param unknown $appsecret 52 | * @param unknown $code 53 | * @throws YDWXException 54 | */ 55 | function ydwx_get_oauth_accesstoken($appid, $appsecret, $code){ 56 | $access_token_url = YDWX_WEIXIN_WEB_BASE_URL."oauth2/access_token?appid={$appid}&secret={$appsecret}&code={$code}&grant_type=authorization_code"; 57 | 58 | $http = new YDHttp(); 59 | $accessToken = new YDWXGetAccessTokenResponse($http->get($access_token_url)); 60 | if($accessToken->isSuccess()) { 61 | return $accessToken; 62 | } 63 | throw new YDWXException($accessToken->errmsg, $accessToken->errcode); 64 | } 65 | 66 | /** 67 | * 微信oauth登录accesstoken刷新 68 | * @param unknown $appid 69 | * @param unknown $refresh_token 70 | * @throws YDWXException 71 | */ 72 | function ydwx_refresh_oauth_accesstoken($appid, $refresh_token){ 73 | $access_token_url = YDWX_WEIXIN_WEB_BASE_URL."oauth2/refresh_token?appid={$appid}&refresh_token={$refresh_token}&code={$code}&grant_type=refresh_token"; 74 | 75 | $http = new YDHttp(); 76 | $accessToken = new YDWXGetAccessTokenResponse($http->get($access_token_url)); 77 | if($accessToken->isSuccess()) { 78 | return $accessToken; 79 | } 80 | throw new YDWXException($accessToken->errmsg, $accessToken->errcode); 81 | } 82 | 83 | function ydwx_refresh_access_token($appid, $appsecret){ 84 | $http = new YDHttp(); 85 | $msg = $http->get(YDWX_WEIXIN_BASE_URL."token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret); 86 | $accessToken = new YDWXAccessTokenResponse($msg); 87 | if($accessToken->isSuccess()) { 88 | return $accessToken; 89 | } 90 | throw new YDWXException($accessToken->errmsg, $accessToken->errcode); 91 | } 92 | 93 | function ydwx_refresh_jsapi_ticket($token){ 94 | $http = new YDHttp(); 95 | $msg = $http->get(YDWX_WEIXIN_BASE_URL."ticket/getticket?type=jsapi&access_token=".$token); 96 | $ticket = new YDWXJsapiTicketResponse($msg); 97 | if($ticket->isSuccess()) { 98 | return $ticket; 99 | } 100 | throw new YDWXException($ticket->errmsg, $ticket->errcode); 101 | } 102 | 103 | function ydwx_refresh_card_jsapi_ticket($token){ 104 | $http = new YDHttp(); 105 | $msg = $http->get(YDWX_WEIXIN_BASE_URL."ticket/getticket?type=wx_card&access_token=".$token); 106 | $ticket = new YDWXJsapiTicketResponse($msg); 107 | if($ticket->isSuccess()) { 108 | return $ticket; 109 | } 110 | throw new YDWXException($ticket->errmsg, $ticket->errcode); 111 | } -------------------------------------------------------------------------------- /code/ydwx/functions/card-hasmp.php: -------------------------------------------------------------------------------- 1 | post(YDWX_WEIXIN_BASE_URL."component/upload_card_agent_qualification?access_token={$accessToken}", 21 | $request->toJSONString()); 22 | $msg = new YDWXResponse($info); 23 | if($msg->isSuccess()){ 24 | return true; 25 | } 26 | throw new YDWXException($request->toJSONString().$msg->errmsg, $msg->errcode); 27 | } 28 | 29 | /** 30 | * 该接口用于查询母商户资质审核的结果,审核通过后才能用接口继续提交子商户资质。 31 | * @param unknown $accessTokent 第三方平台的access token 32 | * @throws YDWXException 33 | * @return YDWX_CARD_CHECK_AGENT_QUALIFICATION_XX常量 34 | */ 35 | function ydwx_card_check_agent_qualification($accessToken){ 36 | $http = new YDHttp(); 37 | $info = $http->get(YDWX_WEIXIN_BASE_URL."component/check_card_agent_qualification?access_token={$accessToken}"); 38 | $msg = new YDWXResponse($info); 39 | if($msg->isSuccess()){ 40 | return $msg->result; 41 | } 42 | throw new YDWXException($msg->errmsg, $msg->errcode); 43 | } 44 | 45 | /** 46 | * 母商户(第三方平台)申请获得开发者协助制券能力后,才可提交名下子商户的资质。 47 | * 子商户资质审核通过后,才可进行后续的授权流程。 48 | * 子商户的资质包括:商户名称、商户 logo(图片)、卡券类目、AppID、营业执照或个 49 | * 体户经营执照(扫描件)、授权协议(扫描件)。 50 | * 注意: 51 | * 1、 请用母商户(第三方平台)的账号提交子商户资料。 52 | * 2、 母商户必须先上传子商户的相应扫描件获取 media_id 后,传入 media_id。ydwx_media_upload接口(传入第三方平台的access token) 53 | * 3、 母商户必须先通过卡券类目查询接口获取卡券实时对外开放的一级、二级类目 ID,传入类目 ID。 54 | * 4、 商户名称在 12 个汉字长度内。 55 | * 5、同一个 appid 的申请,仅当驳回时可再次提交,审核中和审核通过时不可重复提交。 56 | * 57 | * 注意该接口只返回成功与失败,具体的子商户信息需要通过upload_card_merchant_qualification 取得 58 | * 59 | * @param unknown $accessTokent 第三方平台的access token 60 | * @param YDWXCardMerchantQualificationRequest $request 61 | * @throws YDWXException 62 | */ 63 | function ydwx_card_upload_mpmerchant_qualification($accessToken,YDWXCardMerchantQualificationRequest $request){ 64 | $http = new YDHttp(); 65 | $info = $http->post(YDWX_WEIXIN_BASE_URL."component/upload_card_merchant_qualification?access_token={$accessToken}", 66 | $request->toJSONString()); 67 | $msg = new YDWXResponse($info); 68 | if($msg->isSuccess()){ 69 | return true; 70 | } 71 | throw new YDWXException($msg->errmsg, $msg->errcode); 72 | } 73 | 74 | /** 75 | * 该接口用于查询子商户资质审核的结果,审核通过后才能进行后续授权流程。注意,用母商户去调用接口,但接口内传入的是子商户的 appid。 76 | * @param unknown $accessTokent 第三方平台的access token 77 | * @param unknown $appid 78 | * @throws YDWXException 79 | * @return YDWX_CARD_CHECK_AGENT_QUALIFICATION_XX常量 80 | */ 81 | function ydwx_card_check_mpmerchant_qualification($accessToken, $appid){ 82 | $http = new YDHttp(); 83 | $info = $http->post(YDWX_WEIXIN_BASE_URL."component/check_card_merchant_qualification?access_token={$accessToken}", 84 | ydwx_json_encode(array("appid"=>$appid))); 85 | $msg = new YDWXResponse($info); 86 | if($msg->isSuccess()){ 87 | return $msg->result; 88 | } 89 | throw new YDWXException($msg->errmsg, $msg->errcode); 90 | } 91 | 92 | /** 93 | * 通过指定的子商户 appid,拉取该子商户的基础信息。 94 | * 注意,用母商户去调用接口,但接口内传入的是子商户的 appid。 95 | * 96 | * @param unknown $accessTokent 第三方平台的access token 97 | * @param unknown $appid 98 | * @throws YDWXException 99 | * @return YDWXCardMPMerchantResponse 100 | */ 101 | function ydwx_card_get_mpmerchant($accessToken, $appid){ 102 | $http = new YDHttp(); 103 | $info = $http->post(YDWX_WEIXIN_BASE_URL."component/get_card_merchant?access_token={$accessToken}", 104 | ydwx_json_encode(array("appid"=>$appid))); 105 | $msg = new YDWXCardMPMerchantResponse($info); 106 | if($msg->isSuccess()){ 107 | return $msg; 108 | } 109 | throw new YDWXException($msg->errmsg, $msg->errcode); 110 | } 111 | 112 | /** 113 | * 母商户可以通过该接口批量拉取子商户的相关信息,一次调用最多拉取 100 个子商户 114 | * 的信息,可以通过多次拉去满足不同的查询需求。 115 | * 116 | * @param unknown $accessTokent 第三方平台的access token 117 | * @throws YDWXException 118 | * @return YDWXCardMPMerchantBatchGetResponse 119 | */ 120 | function ydwx_card_batchget_mpmerchant($accessToken, $next_get){ 121 | $http = new YDHttp(); 122 | $info = $http->post(YDWX_WEIXIN_BASE_URL."component/batchget_card_merchant?access_token={$accessToken}" 123 | ,ydwx_json_encode(array("next_get"=>$next_get))); 124 | $msg = new YDWXCardMPMerchantBatchGetResponse($info); 125 | if($msg->isSuccess()){ 126 | return $msg; 127 | } 128 | throw new YDWXException($msg->errmsg, $msg->errcode); 129 | } -------------------------------------------------------------------------------- /code/ydwx/functions/card-notmp.php: -------------------------------------------------------------------------------- 1 | post(YDWX_WEIXIN_BASE_URL2."card/submerchant/submit?access_token={$accessToken}", 17 | $request->toJSONString()); 18 | $msg = new YDWXCardSubmerchantResponse($info); 19 | if($msg->isSuccess()){ 20 | return $msg; 21 | } 22 | throw new YDWXException($msg->errmsg, $msg->errcode); 23 | } 24 | 25 | /** 26 | * 卡券类目查询接口 27 | * 通过调用该接口查询卡券开放的类目ID,类目会随业务发展变更,请每次用接口去查询获取实时卡券类目。 28 | * 注意: 29 | * 本接口查询的返回值还有卡券资质ID,此处的卡券资质为:已微信认证的公众号通过微信公众平台申请卡券功能时,所需的资质。 30 | * 对于开发者协助制券(无公众号)模式,子商户无论选择什么类目,均暂不需提供资质,所以不用考虑此处返回的资质字段,返回值仅参考类目ID 即可。 31 | * 32 | * @param unknown $accessToken 第三方平台的access token 33 | * @throws YDWXException 34 | * @return array YDWXCardApplyProtocol 组成的数组 35 | */ 36 | function ydwx_card_getapplyprotocol($accessToken){ 37 | $http = new YDHttp(); 38 | $info = $http->get(YDWX_WEIXIN_BASE_URL2."card/getapplyprotocol?access_token={$accessToken}"); 39 | $msg = new YDWXResponse($info); 40 | $array= array(); 41 | if($msg->isSuccess()){ 42 | foreach ($msg->category as $category){ 43 | $protocol = new YDWXCardApplyProtocol(); 44 | $protocol->category_id = $category['primary_category_id']; 45 | $protocol->category_name = $category['category_name']; 46 | $protocol->secondary_category = array(); 47 | foreach ($category['secondary_category'] as $sub){ 48 | $secondary = new YDWXCardApplyProtocol(); 49 | $secondary->category_id = $sub['secondary_category_id']; 50 | $secondary->category_name = $sub['category_name']; 51 | $secondary->can_choose_payment_card = $sub['can_choose_payment_card']; 52 | $secondary->can_choose_prepaid_card = $sub['can_choose_prepaid_card']; 53 | $protocol->secondary_category[] = $secondary; 54 | } 55 | $array[] = $protocol; 56 | } 57 | return $array; 58 | } 59 | throw new YDWXException($msg->errmsg, $msg->errcode); 60 | } 61 | 62 | /** 63 | * 更新子商户接口 64 | * 支持调用该接口更新子商户信息。 65 | * 注:只有审核驳回和过期两种状态的子商户才能调用更新接口 66 | * 67 | * @param unknown $accessToken 第三方平台的access token 68 | * @param YDWXCardSubmerchantRequest $request 69 | * @throws YDWXException 70 | * @return YDWXCardSubmerchantResponse 71 | */ 72 | function ydwx_card_submerchant_update($accessToken, YDWXCardSubmerchantRequest $request){ 73 | $http = new YDHttp(); 74 | $info = $http->post(YDWX_WEIXIN_BASE_URL2."card/submerchant/update?access_token={$accessToken}", 75 | $request->toJSONString()); 76 | $msg = new YDWXCardSubmerchantResponse($info); 77 | if($msg->isSuccess()){ 78 | return $msg; 79 | } 80 | throw new YDWXException($msg->errmsg, $msg->errcode); 81 | } 82 | 83 | /** 84 | * 支持通过指定子商户 ID 拉取 子商户信息。 85 | * @param unknown $accessToken 第三方平台的access token 86 | * @param unknown $merchant_id 87 | * @throws YDWXException 88 | * @return YDWXCardSubmerchantResponse 89 | */ 90 | function ydwx_card_submerchant_get($accessToken, $merchant_id){ 91 | $http = new YDHttp(); 92 | $info = $http->post(YDWX_WEIXIN_BASE_URL2."card/submerchant/get?access_token={$accessToken}", 93 | ydwx_json_encode(array("merchant_id"=>intval($merchant_id)))); 94 | $msg = new YDWXCardSubmerchantResponse($info); 95 | if($msg->isSuccess()){ 96 | return $msg; 97 | } 98 | throw new YDWXException($msg->errmsg, $msg->errcode); 99 | } 100 | 101 | /** 102 | * 批量拉取子商户信息接口 103 | * 母商户 可以通过该接口批量拉取 子商户的相关信息,一次调用最多拉起100个子商户的信息,可 以通过多次拉去满足不同的查询需求 104 | 105 | * @param unknown $accessToken 第三方平台的access token 106 | * @param unknown $begin_id merchant_id 107 | * @param unknown $limit 数量 最大100 108 | * @param unknown $status YDWX_CARD_MERCHANT_XX 109 | * @throws YDWXException 110 | * @return YDWXCardSubmerchantBatchGetResponse 111 | */ 112 | function ydwx_card_submerchant_batchget($accessToken, $begin_id, $limit, $status){ 113 | if($limit>100){ 114 | throw new YDWXException("商户批量查询数量最大100"); 115 | } 116 | $http = new YDHttp(); 117 | $info = $http->get(YDWX_WEIXIN_BASE_URL2."card/submerchant/batchget?access_token={$accessToken}", 118 | ydwx_json_encode(array("begin_id"=>intval($begin_id),"limit"=>intval($limit),"status"=>$status))); 119 | $msg = new YDWXCardSubmerchantBatchGetResponse($info); 120 | if($msg->isSuccess()){ 121 | return $msg; 122 | } 123 | throw new YDWXException($msg->errmsg, $msg->errcode); 124 | } 125 | -------------------------------------------------------------------------------- /code/ydwx/functions/js.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 29 | 30 | 49 | 70 | 71 | 93 | 100 | 101 | 112 | 123 | wx.scanQRCode({ 124 | needResult: , // 默认为0,扫描结果由微信处理,1则直接返回扫描结果, 125 | scanType: ["qrCode","barCode"], // 可以指定扫二维码还是一维码,默认二者都有 126 | success: function (res) { 127 | var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果 128 | ; 129 | } 130 | }); 131 | 148 | wx.getLocation({ 149 | type: '', 150 | success: function (res) { 151 | 152 | } 153 | }); 154 | 169 | wx.chooseImage({ 170 | count: , 171 | sizeType: [], 172 | sourceType: [], 173 | success: function (res) { 174 | 175 | } 176 | }); 177 | 193 | function ydwx_uploadImage(localid, jscallback){ 194 | setTimeout(function(){ 195 | wx.uploadImage({ 196 | localId: localid, 197 | isShowProgressTips: 1, 198 | success: function (res) { 199 | var serverId = res.serverId; 200 | jscallback(localid, serverId); 201 | } 202 | }); 203 | },500); 204 | } 205 | 215 | function ydwx_previewImage(urls){ 216 | wx.previewImage({ 217 | current: window.document.href, 218 | urls: urls 219 | }); 220 | } 221 | post(YDWX_WEIXIN_BASE_URL."message/custom/send?access_token={$accessToken}", 24 | $arg->toJSONString()); 25 | $rst = new YDWXResponse($info); 26 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg); 27 | 28 | return $rst; 29 | } 30 | 31 | /** 32 | * 通过本接口为公众号添加客服账号,每个公众号最多添加10个客服账号 33 | * 34 | * @param unknown $accessToken 35 | * @param unknown $kfaccount test1@test 账号前缀@公众号微信号 36 | * @param unknown $nickname 客服1 37 | * @param unknown $password pswmd5 38 | * @throws YDWXException 39 | * @return YDWXResponse 40 | */ 41 | function ydwx_kfaccount_add($accessToken, $kfaccount, $nickname, $password){ 42 | $http = new YDHttp(); 43 | $info = $http->post(YDWX_WEIXIN_BASE_URL."customservice/kfaccount/add?access_token={$accessToken}", 44 | ydwx_json_encode(array( 45 | "kf_account"=>$kfaccount, 46 | "nickname" =>$nickname, 47 | "password" =>$password, 48 | ))); 49 | $rst = new YDWXResponse($info); 50 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg); 51 | 52 | return $rst; 53 | } 54 | 55 | /** 56 | * 通过本接口为公众号修改客服账号 57 | * 58 | * @param unknown $accessToken 59 | * @param unknown $kfaccount 账号前缀@公众号微信号 60 | * @param unknown $nickname 61 | * @param unknown $password 62 | * @throws YDWXException 63 | * @return YDWXResponse 64 | */ 65 | function ydwx_kfaccount_update($accessToken, $kfaccount, $nickname, $password){ 66 | $http = new YDHttp(); 67 | $info = $http->post(YDWX_WEIXIN_BASE_URL."customservice/kfaccount/update?access_token={$accessToken}", 68 | ydwx_json_encode(array( 69 | "kf_account"=>$kfaccount, 70 | "nickname" =>$nickname, 71 | "password" =>$password, 72 | ))); 73 | $rst = new YDWXResponse($info); 74 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg); 75 | 76 | return $rst; 77 | } 78 | /** 79 | * 为公众号删除客服帐号 80 | * 81 | * @param unknown $accessToken 82 | * @param unknown $kfaccount 账号前缀@公众号微信号 83 | * @param unknown $nickname 84 | * @param unknown $password 85 | * @throws YDWXException 86 | * @return YDWXResponse 87 | */ 88 | function ydwx_kfaccount_del($accessToken, $kfaccount, $nickname, $password){ 89 | $http = new YDHttp(); 90 | $info = $http->post(YDWX_WEIXIN_BASE_URL."customservice/kfaccount/del?access_token={$accessToken}", 91 | ydwx_json_encode(array( 92 | "kf_account"=>$kfaccount, 93 | "nickname" =>$nickname, 94 | "password" =>$password, 95 | ))); 96 | $rst = new YDWXResponse($info); 97 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg); 98 | 99 | return $rst; 100 | } 101 | /** 102 | * 上传图片作为客服人员的头像,头像图片文件必须是jpg格式,推荐使用640*640大小的图片以达到最佳效果 103 | * @param unknown $accessToken 104 | * @param unknown $kfaccount 账号前缀@公众号微信号 105 | * @param unknown $headimg 头像绝对路径 106 | * @throws YDWXException 107 | * @return YDWXResponse 108 | */ 109 | function ydwx_kfaccount_uploadheadimg($accessToken, $kfaccount, $headimg){ 110 | $http = new YDHttp(); 111 | $info = $http->post(YDWX_WEIXIN_BASE_URL."customservice/kfaccount/uploadheadimg?access_token={$accessToken}&kf_account={$kfaccount}", 112 | array( 113 | "media"=>"@".$headimg 114 | ), true); 115 | $rst = new YDWXResponse($info); 116 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg); 117 | 118 | return $rst; 119 | } 120 | 121 | /** 122 | * 获取公众号中所设置的客服基本信息,包括客服工号、客服昵称、客服登录账号。 123 | * 124 | * @param unknown $accessToken 125 | * @throws YDWXException 126 | * @return multitype:KFAccount 127 | */ 128 | function ydwx_kfaccount_getall($accessToken){ 129 | $http = new YDHttp(); 130 | $info = $http->post(YDWX_WEIXIN_BASE_URL."customservice/getkflist?access_token={$accessToken}"); 131 | $rst = new YDWXResponse($info); 132 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg); 133 | $rsts = array(); 134 | foreach($rst->kf_list as $list){ 135 | $kf = new KFAccount(); 136 | $kf->kf_account = $list['kf_account']; 137 | $kf->kf_nick = $list['kf_nick']; 138 | $kf->kf_id = $list['kf_id']; 139 | $kf->kf_headimgurl = $list['kf_headimgurl']; 140 | $rsts[] = $kf; 141 | } 142 | return $rsts ; 143 | } -------------------------------------------------------------------------------- /code/ydwx/functions/meida.php: -------------------------------------------------------------------------------- 1 | post(YDWX_WEIXIN_BASE_URL."media/upload?access_token={$accessToken}&type=$type", 14 | array("media"=>"@".$media) ,true); 15 | $msg = new YDWXResponse($info); 16 | if($msg->isSuccess()){ 17 | return $msg->media_id; 18 | } 19 | throw new YDWXException($msg->errmsg,$msg->errcode); 20 | } 21 | 22 | /** 23 | * 新增永久图文素材 24 | * 25 | * @param unknown $accessToken 26 | * @param array $articles YDWXMpNewsMsg 组成的数组 27 | * @return mediaid 28 | * @throws YDWXException 29 | */ 30 | function ydwx_material_add_news($accessToken, array $articles){ 31 | $array = array(); 32 | foreach ($articles as $article){ 33 | $array[] = $article->toArray(); 34 | } 35 | $http = new YDHttp(); 36 | $info = $http->post(YDWX_WEIXIN_BASE_URL."material/add_news?access_token={$accessToken}", 37 | ydwx_json_encode(array("articles"=>$array))); 38 | $msg = new YDWXResponse($info); 39 | if($msg->isSuccess()){ 40 | return $msg->media_id; 41 | } 42 | throw new YDWXException($msg->errmsg,$msg->errcode); 43 | } 44 | 45 | /** 46 | * 上传图片得到URL, 47 | * 上传图文消息内的图片获取URL 48 | * 请注意,本接口所上传的图片不占用公众号的素材库中图片数量的5000个的限制。 49 | * 图片仅支持jpg/png格式,大小必须在1MB以下。 50 | * @param unknown $accessToken 51 | * @param string $media 绝对路径 52 | * @return url 53 | * @throws YDWXException 54 | */ 55 | function ydwx_media_uploadimg($accessToken, $media){ 56 | $http = new YDHttp(); 57 | $info = $http->post(YDWX_WEIXIN_BASE_URL."media/uploadimg?access_token={$accessToken}", 58 | array("media"=>"@".$media) ,true); 59 | $msg = new YDWXResponse($info); 60 | if($msg->isSuccess()){ 61 | return $msg->url; 62 | } 63 | throw new YDWXException($msg->errmsg,$msg->errcode); 64 | } 65 | 66 | /** 67 | * 新增其他类型永久素材 68 | * 69 | * @param unknown $accessToken 70 | * @param unknown $type 媒体文件类型,分别有图片(image)、语音(voice)和缩略图(thumb) 71 | * @param unknown $media 72 | * @throws YDWXException 73 | * @return YDWXMaterialResponse 74 | */ 75 | function ydwx_media_add_material($accessToken, $type, $media){ 76 | $http = new YDHttp(); 77 | $info = $http->post(YDWX_WEIXIN_BASE_URL."material/add_material?access_token={$accessToken}&type=$type", 78 | array("media"=>"@".$media) ,true); 79 | 80 | $msg = new YDWXMaterialResponse($info); 81 | 82 | if($msg->isSuccess()){ 83 | return $msg; 84 | } 85 | throw new YDWXException($msg->errmsg,$msg->errcode); 86 | } 87 | /** 88 | * 新增视频类型永久素材 89 | * 90 | * @param unknown $accessToken 91 | * @param unknown $media 92 | * @param unknown $title 视频素材的标题 93 | * @param unknown $introduction 视频素材的描述 94 | * @throws YDWXException 95 | * @return YDWXMaterialResponse 96 | */ 97 | function ydwx_media_add_material_video($accessToken, $media, $title, $introduction){ 98 | $http = new YDHttp(); 99 | $info = $http->post(YDWX_WEIXIN_BASE_URL."material/add_material?access_token={$accessToken}&type=video", 100 | array("media"=>"@".$media, 101 | "description"=>ydwx_json_encode(array("title"=>$title, "introduction"=>$introduction))) ,true); 102 | $msg = new YDWXMaterialResponse($info); 103 | if($msg->isSuccess()){ 104 | return $msg; 105 | } 106 | throw new YDWXException($msg->errmsg,$msg->errcode); 107 | } 108 | 109 | /** 110 | * 下载临时文件 111 | * 112 | * @param unknown $accessToken 113 | * @param unknown $mediaid 114 | * @param string $isVideo 115 | * @return boolean|content 116 | */ 117 | function ydwx_media_get($accessToken, $mediaid, $isVideo=false){ 118 | $http = new YDHttp(); 119 | $content = $http->get( ($isVideo ? YDWX_WEIXIN_NO_SSL_URL : YDWX_WEIXIN_BASE_URL)."media/get?access_token={$accessToken}&media_id={$mediaid}"); 120 | $info = json_decode($content, true); 121 | if( array_key_exists("errcode", $info))throw new YDWXException($info['errmsg']); 122 | return $content; 123 | } -------------------------------------------------------------------------------- /code/ydwx/functions/menu.php: -------------------------------------------------------------------------------- 1 | get(YDWX_WEIXIN_BASE_URL."menu/get?access_token=".$accessToken), true); 13 | 14 | $array = array(); 15 | if( ! @$menus['menu']['button'])return array(); 16 | 17 | foreach ($menus['menu']['button'] as $menu){ 18 | $array[] = YDWXMenu::build($menu); 19 | } 20 | return $array; 21 | } 22 | 23 | /** 24 | * 创建菜单 25 | * 26 | * @param unknown $accessToken 27 | * @param unknown $menus YDWXMenu数组 28 | * @return boolean 29 | * @see http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 30 | */ 31 | function ydwx_menu_create($accessToken, $menus){ 32 | $http = new YDHttp(); 33 | 34 | $save_menus = array(); 35 | foreach ($menus as $menu){ 36 | $save_menus['button'][] = $menu->toArray(); 37 | } 38 | $info = $http->post(YDWX_WEIXIN_BASE_URL."menu/create?access_token=".$accessToken, 39 | ydwx_json_encode($save_menus)); 40 | $res = new YDWXResponse($info); 41 | if($res->isSuccess())return true; 42 | throw new YDWXException($res->errmsg.ydwx_json_encode($save_menus), $res->errcode); 43 | } 44 | 45 | /** 46 | * 删除api创建的菜单 47 | * @param unknown $accessToken 48 | * @return boolean 49 | * @see http://mp.weixin.qq.com/wiki/16/8ed41ba931e4845844ad6d1eeb8060c8.html 50 | */ 51 | function ydwx_menu_delete($accessToken){ 52 | $http = new YDHttp(); 53 | $info = json_decode($http->get(YDWX_WEIXIN_BASE_URL."menu/delete?access_token=".$accessToken), true); 54 | 55 | return ! $info['errcode']; 56 | 57 | } 58 | 59 | function ydwx_get_current_selfmenu_info($accessToken){ 60 | $http = new YDHttp(); 61 | $menus = json_decode($http->get(YDWX_WEIXIN_BASE_URL."get_current_selfmenu_info?access_token=".$accessToken), true); 62 | 63 | $array = array(); 64 | if( ! @$menus['selfmenu_info']['button'])return array(); 65 | 66 | foreach ($menus['selfmenu_info']['button'] as $menu){ 67 | $array[] = YDWXMenu::build($menu); 68 | } 69 | return $array; 70 | } -------------------------------------------------------------------------------- /code/ydwx/functions/msgs.php: -------------------------------------------------------------------------------- 1 | post(YDWX_WEIXIN_BASE_URL."message/mass/get?access_token={$accessToken}", 18 | ydwx_json_encode(array("msg_id"=>$msg_id))); 19 | $rst = new YDWXResponse($info); 20 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg); 21 | 22 | return $rst->msg_status; 23 | } 24 | 25 | /** 26 | * 预览接口【订阅号与服务号认证后均可用】 27 | * 开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版。 28 | * 为了满足第三方平台开发者的需求,在保留对openID预览能力的同时,增加了对指定微信号发送预览的能力, 29 | * 但该能力每日调用次数有限制(100次),请勿滥用。 30 | * @param String $accessToken; 31 | * @param YDWXMassPreviewRequest $arg; 32 | * @return String msg_id 预览消息id 33 | * @see http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E9.A2.84.E8.A7.88.E6.8E.A5.E5.8F.A3.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91 34 | */ 35 | function ydwx_message_preview($accessToken, YDWXMassPreviewRequest $arg){ 36 | 37 | $http = new YDHttp(); 38 | $info = $http->post(YDWX_WEIXIN_BASE_URL."message/mass/preview?access_token={$accessToken}", $arg->toJSONString()); 39 | $rst = new YDWXMassResponse($info); 40 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg); 41 | 42 | return $rst->msg_id; 43 | } 44 | 45 | /** 46 | * 删除群发【订阅号与服务号认证后均可用】 47 | * 1、只有已经发送成功的消息才能删除 48 | * 2、删除消息是将消息的图文详情页失效,已经收到的用户,还是能在其本地看到消息卡片。 49 | * 3、删除群发消息只能删除图文消息和视频消息,其他类型的消息一经发送,无法删除。 50 | * 4、如果多次群发发送的是一个图文消息,那么删除其中一次群发,就会删除掉整个图文消息、导致所有群发都失效 51 | * @param String $accessToken; 52 | * @param String $messageid; 53 | * @return void 54 | * @see http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E5.88.A0.E9.99.A4.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91 55 | */ 56 | function ydwx_message_delete($accessToken, $messageid){ 57 | $http = new YDHttp(); 58 | $info = $http->post(YDWX_WEIXIN_BASE_URL."message/mass/delete?access_token={$accessToken}", 59 | ydwx_json_encode(array("msg_id"=>$messageid))); 60 | $rst = new YDWXResponse($info); 61 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg); 62 | } 63 | 64 | /** 65 | * 企业号发送消息 66 | * @param YDWXQyMsgRequest $arg; 67 | * @return YDWXResponse 68 | * @see http://qydev.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E7%B1%BB%E5%9E%8B%E5%8F%8A%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F 69 | */ 70 | function ydwx_qy_message_send($accessToken, YDWXQyMsgRequest $arg){ 71 | $http = new YDHttp(); 72 | $info = $http->post(YDWX_WEIXIN_QY_BASE_URL."message/send?access_token={$accessToken}", $arg->toJSONString()); 73 | $info = new YDWXResponse($info); 74 | if($info->isSuccess())return $info; 75 | throw new YDWXException($info->errmsg, $info->errcode); 76 | } 77 | 78 | /** 79 | * 向微信回复消息 80 | * 81 | * @param YDWXAnswerMsg $msg 82 | * @param boolean isComponent 83 | */ 84 | function ydwx_answer_msg(YDWXAnswerMsg $msg, $isComponent=false){ 85 | ob_start(); 86 | if($isComponent){//第三方平台要加密 87 | $crypt = new WXBizMsgCrypt(YDWX_WEIXIN_COMPONENT_TOKEN, YDWX_WEIXIN_COMPONENT_ENCODING_AES_KEY, YDWX_WEIXIN_COMPONENT_APP_ID); 88 | $encryptMsg = ""; 89 | $crypt->encryptMsg($msg->toXMLString(), time(), uniqid(), $encryptMsg); 90 | echo $encryptMsg; 91 | }else{ 92 | echo $msg->toXMLString(); 93 | } 94 | ob_end_flush(); 95 | } 96 | 97 | function ydwx_qy_answer_msg(YDWXAnswerMsg $msg){ 98 | ob_start(); 99 | $crypt = new WXBizMsgCrypt(YDWX_WEIXIN_TOKEN, YDWX_WEIXIN_ENCODING_AES_KEY, YDWX_WEIXIN_CROP_ID); 100 | $encryptMsg = ""; 101 | $crypt->encryptMsg($msg->toXMLString(), time(), uniqid(), $encryptMsg); 102 | echo $encryptMsg; 103 | ob_end_flush(); 104 | } 105 | /** 106 | * 从行业模板库选择模板到账号后台,获得模板ID 107 | * 108 | * @param String $accessToken 109 | * @param String $template_id 模板库中模板的编号,有“TM**”和“OPENTMTM**”等形式 110 | * 111 | * @return string 模板的id 112 | */ 113 | function ydwx_message_template_add($accessToken, $template_id){ 114 | $http = new YDHttp(); 115 | $info = $http->post(YDWX_WEIXIN_BASE_URL."template/api_add_template?access_token={$accessToken}", 116 | ydwx_json_encode(array("template_id_short"=>$template_id))); 117 | $rst = new YDWXResponse($info); 118 | if( ! $rst->isSuccess())throw new YDWXException($rst->errmsg); 119 | return $rst->template_id; 120 | } 121 | /** 122 | * 设置行业可在MP中完成,每月可修改行业1次,账号仅可使用所属行业中相关的模板, 123 | * 为方便第三方开发者,提供通过接口调用的方式来修改账号所属行业 124 | * 125 | * @param String $accessToken 126 | * @param String $id1 见 YDWX_INDUSTRY_XX 127 | * @param String $id2 见 YDWX_INDUSTRY_XX 128 | * 129 | * @return void 130 | */ 131 | function ydwx_message_template_set_industry($accessToken, $id1, $id2){ 132 | 133 | $http = new YDHttp(); 134 | $info = $http->post(YDWX_WEIXIN_BASE_URL."template/api_set_industry?access_token={$accessToken}", 135 | ydwx_json_encode(array("industry_id1"=>$id1, "industry_id2"=>$id2))); 136 | $rst = new YDWXResponse($info); 137 | if( ! $rst->isSuccess())throw new YDWXException($rst->errmsg); 138 | } 139 | 140 | /** 141 | * 发送模板消息, 要求是认证的服务号 142 | * 143 | * @param unknown $accessToken 144 | * @param YDWXTemplateRequest $tpl 145 | * @return YDWXTemplateResponse 146 | */ 147 | function ydwx_message_template_send($accessToken, YDWXTemplateRequest $tpl){ 148 | 149 | $http = new YDHttp(); 150 | $info = $http->post(YDWX_WEIXIN_BASE_URL."message/template/send?access_token={$accessToken}", 151 | $tpl->toJSONString()); 152 | $info = new YDWXTemplateResponse($info); 153 | if($info->isSuccess())return $info; 154 | throw new YDWXException($info->errmsg, $info->errcode); 155 | } 156 | 157 | /** 158 | * 根据openid群发消息, 要求认证 159 | * 160 | * @see http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AEOpenID.E5.88.97.E8.A1.A8.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8D.E5.8F.AF.E7.94.A8.EF.BC.8C.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.8F.AF.E7.94.A8.E3.80.91 161 | * @param unknown $accessToken 162 | * @param YDWXMassRequest $arg 163 | * @return YDWXMassResponse 164 | */ 165 | function ydwx_message_send_by_openid($accessToken, YDWXMassRequest $arg){ 166 | 167 | $http = new YDHttp(); 168 | $info = $http->post(YDWX_WEIXIN_BASE_URL."message/mass/send?access_token={$accessToken}", 169 | $arg->toJSONString()); 170 | $info = new YDWXMassResponse($info); 171 | if($info->isSuccess())return $info; 172 | throw new YDWXException($info->errmsg, $info->errcode); 173 | } 174 | 175 | /** 176 | * 根据分组群发消息, 要求认证 177 | * 178 | * @see http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E6.A0.B9.E6.8D.AE.E5.88.86.E7.BB.84.E8.BF.9B.E8.A1.8C.E7.BE.A4.E5.8F.91.E3.80.90.E8.AE.A2.E9.98.85.E5.8F.B7.E4.B8.8E.E6.9C.8D.E5.8A.A1.E5.8F.B7.E8.AE.A4.E8.AF.81.E5.90.8E.E5.9D.87.E5.8F.AF.E7.94.A8.E3.80.91 179 | * @param unknown $accessToken 180 | * @param YDWXMassByGroupRequest $arg 181 | * @return YDWXMassResponse 182 | */ 183 | function ydwx_message_send_by_group($accessToken, YDWXMassByGroupRequest $arg){ 184 | $openids = (array)$openids; 185 | $http = new YDHttp(); 186 | $info = $http->post(YDWX_WEIXIN_BASE_URL."message/mass/sendall?access_token={$accessToken}", 187 | $arg->toJSONString()); 188 | $info = new YDWXMassResponse($info); 189 | if($info->isSuccess())return $info; 190 | throw new YDWXException($info->errmsg, $info->errcode); 191 | } 192 | -------------------------------------------------------------------------------- /code/ydwx/functions/packet.php: -------------------------------------------------------------------------------- 1 | wxappid); 17 | $request->sign(); 18 | $info = $http->post(YDWX_WEIXIN_PAY_URL."mmpaymkttransfers/hbpreorder", 19 | $request->toXMLString()); 20 | $rst = new YDWXPacketPreorderResponse($info); 21 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg.$rst->errcode, $rst->errcode); 22 | 23 | return $rst; 24 | } 25 | 26 | /** 27 | * 创建红包活动 28 | * 创建红包活动,设置红包活动有效期,红包活动开关等基本信息,返回活动id 29 | * @param unknown $accessToken 30 | * @param YDWXPacketAddLotteryInfoRequest $request 31 | * @param unknown $logourl 使用模板页面的logo_url,不使用模板时可不加。展示在摇一摇界面的消息图标。图片尺寸为120x120。 32 | * @param boolean $useTemplate 是否使用模板, 模版即交互流程图中的红包加载页,使用模板用户不需要点击可自动打开红包;不使用模版需自行开发HTML5页面,并在页面调用红包jsapi) 33 | * @throws YDWXException 34 | * @return YDWXPacketAddLotteryInfoResponse 35 | */ 36 | function ydwx_packet_addlotteryinfo($accessToken, YDWXPacketAddLotteryInfoRequest $request, $logourl, $useTemplate=true){ 37 | $http = new YDHttp(); 38 | $info = $http->post(YDWX_WEIXIN_BASE_URL2."shakearound/lottery/addlotteryinfo?access_token={$accessToken}&use_template=".($useTemplate ? 1 : 2)."&logo_url={$logourl}", $request->toJSONString()); 39 | $rst = new YDWXPacketAddLotteryInfoResponse($info); 40 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg, $rst->errcode); 41 | 42 | return $rst; 43 | } 44 | 45 | /** 46 | * 录入红包信息 47 | * 在调用"创建红包活动"接口之后,调用此接口录入红包信息。注意,此接口每次调用, 48 | * 都会向某个活动新增一批红包信息,如果红包数少于100个,请通过一次调用添加所有红包信息。 49 | * 如果红包数大于100,可以多次调用接口添加。请注意确保多次录入的红包ticket总的数目不大于 50 | * 创建该红包活动时设置的total值。 51 | * 52 | * @param unknown $accessToken 53 | * @param YDWXPacketSetPrizeBucketRequest $request 54 | * @throws YDWXException 55 | * @return YDWXPacketSetPrizeBucketResponse 56 | */ 57 | function ydwx_packet_setprizebucket($accessToken, YDWXPacketSetPrizeBucketRequest $request){ 58 | $http = new YDHttp(); 59 | $info = $http->post(YDWX_WEIXIN_BASE_URL2."shakearound/lottery/setprizebucket?access_token={$accessToken}", $request->toJSONString()); 60 | $rst = new YDWXPacketSetPrizeBucketResponse($info); 61 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg, $rst->errcode); 62 | 63 | return $rst; 64 | } 65 | 66 | /** 67 | * 设置红包活动抽奖开关 68 | * 69 | * 开发者实时控制红包活动抽奖的开启和关闭。 70 | * 注意活动抽奖开关只在红包活动有效期之内才能生效, 71 | * 如果不能确定红包活动有效期,请尽量将红包活动有效期的范围设置大。 72 | * 73 | * @param unknown $accessToken 74 | * @param unknown $lottery_id 红包抽奖id,来自addlotteryinfo返回的lottery_id 75 | * @param boolean $onoff 活动抽奖开关,false:关闭,true:开启 76 | * @throws YDWXException 77 | * @return boolean 78 | */ 79 | function ydwx_packet_setlotteryswitch($accessToken, $lottery_id, $onoff){ 80 | $http = new YDHttp(); 81 | $info = $http->get(YDWX_WEIXIN_BASE_URL2."shakearound/lottery/setlotteryswitch?access_token={$accessToken}&lottery_id={$lottery_id}&onoff=".($onoff ? "1" : "0")); 82 | $rst = new YDWXResponse($info); 83 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg, $rst->errcode); 84 | 85 | return true; 86 | } 87 | 88 | /** 89 | * 红包JSAPI 90 | * 在第三方页面中,通过调用JSAPI来触发用户抽红包的操作, 91 | * 如果抽到红包,会呼出微信的原生红包页面。 92 | * 用户只有通过摇周边的入口才能抽中红包。每个用户在一个活动抽奖id下最多 93 | * 只能中一个红包。创建红包活动时,选择使用模板页面的开发者不需要调用该接口 94 | * 95 | * openid 当前访问页面的用户openid 可以在访问页面之前是否微信用户“登录”了(之前已经访问过后,把openid记在会话中); 96 | * 如果没有登录,则把请求转向auth.php或则baseauth.php 97 | * 对于h5页面,微信也是一个浏览器,具有会话 98 | * 99 | * @param $lottery_id 红包抽奖id,必填,来自addlotteryinfo返回的lottery_id 100 | * @param $key 通过“创建红包活动” ydwx_packet_addlotteryinfo 接口设置的key 101 | * @param $openid 当前访问页面的用户openid 可以在访问页面之前是否微信用户“登录”了(之前已经访问过后,把openid记在会话中);如果没有登录,则把请求转向auth.php或则baseauth.php 102 | * 103 | * @return string 104 | */ 105 | function ydwx_packet_shake_js_api($lottery_id, $key, $openid){ 106 | ob_start(); 107 | ?> 108 | 109 | 125 | appid); 137 | $request->sign(); 138 | $info = $http->post(YDWX_WEIXIN_PAY_URL."mmpaymkttransfers/gethbinfo", 139 | $request->toXMLString()); 140 | $rst = new YDWXPacketGetHBInfoResponse($info); 141 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg, $rst->errcode); 142 | 143 | return $rst; 144 | } 145 | 146 | /** 147 | * 用于企业向微信用户个人发现金红包,目前支持向指定微信用户的openid发放指定金额红包 148 | * 149 | * @param YDWXPacketSendRequest $request 150 | * @throws YDWXException 151 | * @return YDWXPacketSendResponse 152 | */ 153 | function ydwx_packet_send(YDWXPacketSendRequest $request){ 154 | $http = new YDHttps($request->wxappid); 155 | $request->sign(); 156 | $info = $http->post(YDWX_WEIXIN_PAY_URL."mmpaymkttransfers/sendredpack", 157 | $request->toXMLString()); 158 | $rst = new YDWXPacketSendResponse($info); 159 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg, $rst->errcode); 160 | 161 | return $rst; 162 | } 163 | 164 | /** 165 | * 用于企业向微信用户个人发裂变红包 166 | * 目前支持向指定微信用户的openid发放指定金额裂变红包 167 | * 对应红包的领取情况,可通过ydwx_packet_gethbinfo获取 168 | * @param YDWXPacketSendGroupRequest $request 169 | * @throws YDWXException 170 | * @return YDWXPacketSendGroupResponse 171 | */ 172 | function ydwx_packet_send_group(YDWXPacketSendGroupRequest $request){ 173 | $http = new YDHttps($request->wxappid); 174 | $request->sign(); 175 | $info = $http->post(YDWX_WEIXIN_PAY_URL."mmpaymkttransfers/sendgroupredpack", 176 | $request->toXMLString()); 177 | $rst = new YDWXPacketSendGroupResponse($info); 178 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg, $rst->errcode); 179 | 180 | return $rst; 181 | } -------------------------------------------------------------------------------- /code/ydwx/functions/pay.php: -------------------------------------------------------------------------------- 1 | appid); 10 | $request->sign(); 11 | $info = $http->post(YDWX_WEIXIN_PAY_URL."mmpaymkttransfers/gettransferinfo", 12 | $request->toXMLString()); 13 | $rst = new YDWXCropTransferQueryResponse($info); 14 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg, $rst->errcode); 15 | 16 | return $rst; 17 | } 18 | 19 | /** 20 | * 用于企业向微信用户个人付款 21 | * 目前支持向指定微信用户的openid付款。 22 | * 23 | * @param YDWXCropTransferRequest $request 24 | * @throws YDWXException 25 | * @return YDWXCropTransferResponse 26 | */ 27 | function ydwx_crop_transfer(YDWXCropTransferRequest $request){ 28 | $http = new YDHttps($request->mch_appid); 29 | $request->sign(); 30 | $info = $http->post(YDWX_WEIXIN_PAY_URL."mmpaymkttransfers/promotion/transfers", 31 | $request->toXMLString()); 32 | $rst = new YDWXCropTransferResponse($info); 33 | if( ! $rst->isSuccess()) throw new YDWXException($rst->errmsg, $rst->errcode); 34 | 35 | return $rst; 36 | } 37 | 38 | /** 39 | * 生成微信外H5 40 | * 调起微信支付的deeplink 41 | * 42 | * @param $appid 公众账号ID 43 | * @param $package 订单详情扩展字符串 44 | * @param $prepayid 预支付交易会话标识 45 | * @param $mch_key 支付秘钥 46 | * @return string 47 | * @link https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_4 48 | */ 49 | function ydwx_pay_deeplink($appid, $package, $prepayid, $mch_key){ 50 | $timestamp = time(); 51 | $noncestr = uniqid(); 52 | $sign = strtoupper(md5("appid=".$appid 53 | ."&noncestr=".$noncestr 54 | ."&package=".$package 55 | ."&prepayid=".$prepayid 56 | ."×tamp=".$timestamp 57 | ."&key=".$mch_key)); 58 | 59 | 60 | $string1 = "appid=".urlencode($appid) 61 | ."&noncestr=".urlencode($noncestr) 62 | ."&package=".urlencode($package) 63 | ."&prepayid=".urlencode($prepayid) 64 | ."&sign=".urlencode($sign) 65 | ."×tamp=".urlencode($timestamp); 66 | 67 | return "weixin://wap/pay?".urlencoce($string1); 68 | 69 | } 70 | /** 71 | * 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XX), 72 | * 减小二维码数据量,提升扫描速度和精确度。 73 | * 74 | * @param YDWXPayShorturlRequest $msg 75 | * @return YDWXPayShorturlResponse 76 | */ 77 | function ydwx_pay_short_qrcode(YDWXPayShorturlRequest $arg){ 78 | $arg->sign(); 79 | $args = $arg->toXMLString(); 80 | YDWXHook::do_hook(YDWXHook::YDWX_LOG, "ydwx_pay_short_qrcode:".$args); 81 | $http = new YDHttp(); 82 | $info = $http->post(YDWX_WEIXIN_PAY_URL."tools/shorturl", $args); 83 | 84 | $msg = new YDWXPayShorturlResponse($info); 85 | if( ! $msg->isSuccess()){ 86 | throw new YDWXException($msg->errmsg, $msg->errcode); 87 | } 88 | return $msg; 89 | } 90 | 91 | /** 92 | * 商户可以通过该接口下载历史交易清单。比如掉单、系统错误等导致商户侧和微信侧数据不一致,通过对账单核对后可校正支付状态。 93 | * 注意: 94 | * 1、微信侧未成功下单的交易不会出现在对账单中。支付成功后撤销的交易会出现在对账单中,跟原支付单订单号一致,bill_type为REVOKED; 95 | * 2、微信在次日9点启动生成前一天的对账单,建议商户10点后再获取; 96 | * 3、对账单中涉及金额的字段单位为“元”。 97 | * 98 | * @param YDWXPayDownloadbillRequest arg 99 | * @return YDWXPayDownloadbillResponse 100 | */ 101 | function ydwx_pay_downloadbill(YDWXPayDownloadbillRequest $arg){ 102 | $arg->sign(); 103 | $args = $arg->toXMLString(); 104 | 105 | $http = new YDHttp(); 106 | $info = $http->post(YDWX_WEIXIN_PAY_URL."pay/downloadbill", $args); 107 | 108 | $msg = new YDWXPayDownloadbillResponse($info); 109 | if( ! $msg->isSuccess()){ 110 | throw new YDWXException($msg->errmsg); 111 | } 112 | $msg->bill_type = $arg->bill_type; 113 | return $msg; 114 | } 115 | /** 116 | * 提交退款申请后,通过调用该接口查询退款状态。退款有一定延时,用零钱支付的退款20分钟内到账, 117 | * 银行卡支付的退款3个工作日后重新查询退款状态。 118 | * 119 | * @param YDWXPayRefundQueryRequest arg 120 | * @return YDWXPayRefundQueryResponse 121 | */ 122 | function ydwx_pay_refund_query(YDWXPayRefundQueryRequest $arg){ 123 | $arg->sign(); 124 | $args = $arg->toXMLString(); 125 | 126 | $http = new YDHttp(); 127 | $info = $http->post(YDWX_WEIXIN_PAY_URL."pay/refundquery", $args); 128 | 129 | $msg = new YDWXPayRefundQueryResponse($info); 130 | if( ! $msg->isSuccess()){ 131 | throw new YDWXException($msg->errmsg); 132 | } 133 | return $msg; 134 | } 135 | /** 136 | * 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时, 137 | * 卖家可以通过退款接口将支付款退还给买家,微信支付将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。 138 | * 注意: 139 | * 1、交易时间超过一年的订单无法提交退款; 140 | * 2、微信支付退款支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。 141 | * 一笔退款失败后重新提交,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 142 | * 143 | * @param YDWXPayRefundRequest arg 144 | * @return YDWXPayRefundResponse 145 | */ 146 | function ydwx_pay_refund(YDWXPayRefundRequest $arg){ 147 | $arg->sign(); 148 | $args = $arg->toXMLString(); 149 | 150 | $http = new YDHttps($arg->appid); 151 | $info = $http->post(YDWX_WEIXIN_PAY_URL."secapi/pay/refund", $args); 152 | 153 | $msg = new YDWXPayRefundResponse($info); 154 | if( ! $msg->isSuccess()){ 155 | throw new YDWXException($msg->errmsg); 156 | } 157 | return $msg; 158 | } 159 | /** 160 | * 以下情况需要调用关单接口:商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单, 161 | * 避免重复支付;系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。 162 | * 163 | * 注意:订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟。 164 | * 165 | * @param YDWXCloseOrderRequest arg 166 | * @return YDWXPayBaseResponse 167 | */ 168 | function ydwx_pay_closeorder(YDWXCloseOrderRequest $arg){ 169 | $arg->sign(); 170 | $args = $arg->toXMLString(); 171 | 172 | $http = new YDHttp(); 173 | $info = $http->post(YDWX_WEIXIN_PAY_URL."pay/closeorder", $args); 174 | 175 | $msg = new YDWXPayBaseResponse($info); 176 | if( ! $msg->isSuccess()){ 177 | throw new YDWXException($msg->errmsg); 178 | } 179 | return $msg; 180 | } 181 | /** 182 | * 该接口提供所有微信支付订单的查询,商户可以通过该接口主动查询订单状态,完成下一步的业务逻辑。 183 | * 需要调用查询接口的情况: 184 | * ◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知; 185 | * ◆ 调用支付接口后,返回系统错误或未知交易状态情况; 186 | * ◆ 调用被扫支付API,返回USERPAYING的状态; 187 | * ◆ 调用关单或撤销接口API之前,需确认支付状态; 188 | * 189 | * @param YDWXOrderQueryRequest arg 190 | * @return YDWXOrderQueryResponse 191 | */ 192 | function ydwx_pay_orderquery(YDWXOrderQueryRequest $arg){ 193 | $arg->sign(); 194 | $args = $arg->toXMLString(); 195 | 196 | $http = new YDHttp(); 197 | $info = $http->post(YDWX_WEIXIN_PAY_URL."pay/orderquery", $args); 198 | 199 | $msg = new YDWXOrderQueryResponse($info); 200 | if( ! $msg->isSuccess()){ 201 | throw new YDWXException($msg->errmsg); 202 | } 203 | return $msg; 204 | } 205 | /** 206 | * 微信统一下单接口,根据构造YDWXPayUnifiedOrderRequest的方式不同返回不同 207 | * 通过 new YDWXPayUnifiedOrderRequest(true);返回的YDWXPayUnifiedOrderResponse中会有code_url(二维码内容) 208 | * 其他情况没用 209 | * 210 | * 建议采用http://ydimage.yidianhulian.com/qrcode?str=二维码内容来生产二维码 211 | * 212 | * @param YDWXPayUnifiedOrderRequest arg 213 | * @return YDWXPayUnifiedOrderResponse 214 | */ 215 | function ydwx_pay_unifiedorder(YDWXPayUnifiedOrderRequest $arg){ 216 | $arg->sign(); 217 | $args = $arg->toXMLString(); 218 | 219 | $http = new YDHttp(); 220 | $info = $http->post(YDWX_WEIXIN_PAY_URL."pay/unifiedorder", $args); 221 | 222 | $msg = new YDWXPayUnifiedOrderResponse($info); 223 | if( ! $msg->isSuccess()){ 224 | throw new YDWXException($msg->errmsg, $msg->errcode); 225 | } 226 | return $msg; 227 | } 228 | 229 | 230 | /** 231 | * 扫码支付二维码内容(模式一) 232 | * 把返回的内容生成二维码后,用户扫码后回回调pay-notify.php 233 | * 234 | * 235 | * 建议采用http://ydimage.yidianhulian.com/qrcode?str=二维码内容来生产二维码 236 | * 237 | * 可以把返回结果再次调用ydwx_pay_short_qrcode()得到更精简的二维码内容,减少二维码复杂度 238 | * 239 | * @param unknown $product_id 你系统的产品id 240 | * @param string type 见YDWX_WEIXIN_TYPE_XX常量 241 | * @param unknown $appid 当前公众号appid,如果不是第三方平台,则传入(普通账号)YDWX_WEIXIN_APP_ID或(企业号)YDWX_WEIXIN_CROP_ID 242 | */ 243 | function ydwx_pay_product_qrcode($product_id, $appid, $type=YDWX_WEIXIN_TYPE_NORMAL){ 244 | $nonceStr = uniqid(); 245 | $time_stamp = time(); 246 | 247 | if($type==YDWX_WEIXIN_TYPE_CROP){ 248 | $mchkey = YDWX_WEIXIN_QY_MCH_KEY; 249 | $mchid = YDWX_WEIXIN_QY_MCH_ID; 250 | }else if($type==YDWX_WEIXIN_TYPE_AGENT){ 251 | $mchkey = YDWXHook::do_hook(YDWXHook::GET_HOST_MCH_KEY, $appid); 252 | $mchid = YDWXHook::do_hook(YDWXHook::GET_HOST_MCH_ID, $appid); 253 | 254 | }else{ 255 | $mchkey = YDWX_WEIXIN_MCH_KEY; 256 | $mchid = YDWX_WEIXIN_MCH_ID; 257 | } 258 | 259 | $str = "appid=".$appid 260 | ."&mch_id=".$mchid 261 | ."&nonce_str=".$nonceStr."&product_id=".$product_id 262 | ."&time_stamp=".$time_stamp; 263 | $signStr = strtoupper(md5($str."&key=".$mchkey)); 264 | 265 | return "weixin://wxpay/bizpayurl?sign={$signStr}&appid=" 266 | .$appid."&mch_id=".$mchid 267 | ."&product_id={$product_id}&time_stamp={$time_stamp}&nonce_str={$nonceStr}"; 268 | } 269 | 270 | /** 271 | * 生成jsAPI 预处理支付脚本,其中有个一个jsPayApi(openid, traceno,totalPrice, attach, payDesc, success, fail, cancel)方法是实际调起微信支付的入口 272 | * openid 支付用户openid;traceno订单号,totalPrice是支付费用;attach是附加数据,微信原因返回;payDesc商品描述; 273 | * success 成功回调 274 | * fail 失败回调 参数为错误消息 275 | * cancel 用户取消支付回调 276 | * 277 | * 在准备支付是调用jsPayApi即可 278 | * 279 | * 需要先调用dwx_jsapi_include() 280 | * 281 | * @param unknown $appid 如果是托管平台,则传所托管对appid,其他情况不传 282 | * @return string 283 | */ 284 | function ydwx_jspay_script($appid=""){ 285 | ob_start(); 286 | ?> 287 | 332 | -------------------------------------------------------------------------------- /code/ydwx/functions/poi.php: -------------------------------------------------------------------------------- 1 | post(YDWX_WEIXIN_BASE_URL."media/uploadimg?access_token={$accessToken}", 17 | array("buffer"=>"@".$buffer) ,true); 18 | $msg = new YDWXResponse($info); 19 | if($msg->isSuccess()){ 20 | return $msg->url; 21 | } 22 | throw new YDWXException($msg->errmsg); 23 | } 24 | 25 | /** 26 | * 27 | * 创建门店接口是为商户提供创建自己门店数据的接口,门店数据字段越完整,商户页面展示越丰富,越能够吸引更多用户,并提高曝光度。 28 | * 创建门店接口调用成功后会返回bool,但不会实时返回poi_id。 29 | * 成功创建后,会生成poi_id,但该id不一定为最终id。门店信息会经过审核,审核通过后方可获取最终poi_id(YDWXHook::Event_poi_check_notify 钩子),该id为门店的唯一id,强烈建议自行存储审核通过后的最终poi_id,并为后续调用使用。 30 | * @param unknown $accessToken 31 | * @param YDWXPoiAddRequest $request 32 | * @throws YDWXException 33 | * @return boolean 34 | */ 35 | function ydwx_poi_add($accessToken, YDWXPoiAddRequest $request){ 36 | $http = new YDHttp(); 37 | $info = $http->post(YDWX_WEIXIN_BASE_URL."poi/addpoi?access_token={$accessToken}", 38 | $request->toJSONString()); 39 | $msg = new YDWXResponse($info); 40 | if($msg->isSuccess()){ 41 | return true; 42 | } 43 | throw new YDWXException($msg->errmsg); 44 | } 45 | 46 | /** 47 | * 查询门店信息 48 | * 创建门店后获取poi_id 后,商户可以利用poi_id,查询具体某条门店的信息。 若在查询时, 49 | * update_status 字段为1,表明在5 个工作日内曾用update 接口修改过门店扩展字段, 50 | * 该扩展字段为最新的修改字段,尚未经过审核采纳,因此不是最终结果。最终结果会在5 个工作日内, 51 | * 最终确认是否采纳,并前端生效(但该扩展字段的采纳过程不影响门店的可用性,即available_state仍为审核通过状态) 52 | * 注:扩展字段为公共编辑信息(大家都可修改),修改将会审核,并决定是否对修改建议进行采纳, 53 | * 但不会影响该门店的生效可用状态。 54 | * 55 | * @param unknown $accessToken 56 | * @param unknown $poiid 57 | * @throws YDWXException 58 | * @return YDWXPoiGetResponse 59 | */ 60 | function ydwx_poi_get($accessToken, $poiid){ 61 | $http = new YDHttp(); 62 | $info = $http->post(YDWX_WEIXIN_BASE_URL."poi/getpoi?access_token={$accessToken}", 63 | ydwx_json_encode(array("poi_id"=>$poiid))); 64 | $msg = new YDWXPoiGetResponse($info); 65 | if($msg->isSuccess()){ 66 | return $msg; 67 | } 68 | throw new YDWXException($msg->errmsg); 69 | } 70 | 71 | /** 72 | * 查询门店列表 73 | * 商户可以通过该接口,批量查询自己名下的门店list,并获取已审核通过的poi_id(所有状态均会返回poi_id,但该poi_id不一定为最终id)、商户自身sid 用于对应、商户名、分店名、地址字段 74 | * 75 | * @param unknown $accessToken 76 | * @param unknown $begin 开始位置,0 即为从第一条开始查询 77 | * @param unknown $limit 返回数据条数,最大允许50,默认为20 78 | * @throws YDWXException 79 | * @return YDWXPoiGetListResponse 80 | */ 81 | function ydwx_poi_list($accessToken, $begin, $limit){ 82 | $http = new YDHttp(); 83 | $info = $http->post(YDWX_WEIXIN_BASE_URL."poi/getpoilist?access_token={$accessToken}", 84 | ydwx_json_encode(array("begin"=>$begin, "limit"=>$limit))); 85 | $msg = new YDWXPoiGetListResponse($info); 86 | if($msg->isSuccess()){ 87 | return $msg; 88 | } 89 | throw new YDWXException($msg->errmsg); 90 | } 91 | 92 | /** 93 | * 修改门店服务信息 94 | * 商户可以通过该接口,修改门店的服务信息,包括:图片列表、营业时间、推荐、特色服务、简介、人均价格、电话7 个字段(名称、坐标、地址等不可修改)修改后需要人工审核。 95 | * 若有填写内容则为覆盖更新,若无内容则视为不修改,维持原有内容。 photo_list 字段为全列表覆盖,若需要增加图片,需将之前图片同样放入list 中,在其后增加新增图片。如:已有A、B、C 三张图片,又要增加D、E 两张图,则需要调用该接口,photo_list 传入A、B、C、D、E 五张图片的链接。 96 | * @param unknown $accessToken 97 | * @param unknown $begin 98 | * @param unknown $limit 99 | * @throws YDWXException 100 | * @return boolean 101 | */ 102 | function ydwx_poi_update($accessToken, YDWXPoiAddRequest $request){ 103 | $http = new YDHttp(); 104 | $info = $http->post(YDWX_WEIXIN_BASE_URL."poi/updatepoi?access_token={$accessToken}", 105 | $request->toJSONString()); 106 | $msg = new YDWXResponse($info); 107 | if($msg->isSuccess()){ 108 | return true; 109 | } 110 | throw new YDWXException($msg->errmsg); 111 | } 112 | /** 113 | * 删除门店 114 | * 商户可以通过该接口,删除已经成功创建的门店。请商户慎重调用该接口,门店信息被删除后,可能会影响其他与门店相关的业务使用,如卡券等。同样,该门店信息也不会在微信的商户详情页显示,不会再推荐入附近功能。 115 | * 116 | * @param unknown $accessToken 117 | * @param unknown $poiid 118 | * @throws YDWXException 119 | * @return boolean 120 | */ 121 | function ydwx_poi_delete($accessToken, $poiid){ 122 | $http = new YDHttp(); 123 | $info = $http->post(YDWX_WEIXIN_BASE_URL."poi/delpoi?access_token={$accessToken}", 124 | ydwx_json_encode(array("poi_id"=>$poiid))); 125 | $msg = new YDWXResponse($info); 126 | if($msg->isSuccess()){ 127 | return true; 128 | } 129 | throw new YDWXException($msg->errmsg); 130 | } 131 | 132 | /** 133 | * 取得poi类目 134 | * @param unknown $accessToken 135 | * @throws YDWXException 136 | * @return array 137 | */ 138 | function ydwx_poi_getwxcategory($accessToken){ 139 | $http = new YDHttp(); 140 | $info = $http->get(YDWX_WEIXIN_BASE_URL."api_getwxcategory?access_token={$accessToken}"); 141 | $msg = new YDWXResponse($info); 142 | if($msg->isSuccess()){ 143 | return $msg->category_list; 144 | } 145 | throw new YDWXException($msg->errmsg); 146 | } 147 | -------------------------------------------------------------------------------- /code/ydwx/functions/qy-user.php: -------------------------------------------------------------------------------- 1 | post(YDWX_WEIXIN_QY_BASE_URL."user/create?access_token={$accessToken}", $request->toJSONString()); 23 | $response = new YDWXResponse($response); 24 | if($response->isSuccess()){ 25 | return true; 26 | } 27 | throw new YDWXException($response->errmsg); 28 | } 29 | 30 | /** 31 | * 删除成员 32 | * 系统应用须拥有指定成员的管理权限。 33 | * 34 | * @param unknown $accessToken 可通过hook YDWXHook::do_hook(YDWXHook::GET_QY_ACCESS_TOKEN) 获取 35 | * @param unknown $userId 36 | * @throws YDWXException 37 | * @return boolean 38 | */ 39 | function ydwx_qy_user_delete($accessToken, $userId){ 40 | $http = new YDHttps(); 41 | $response= $http->get(YDWX_WEIXIN_QY_BASE_URL."user/create?access_token={$accessToken}&userid={$userId}"); 42 | $response = new YDWXResponse($response); 43 | if($response->isSuccess()){ 44 | return true; 45 | } 46 | throw new YDWXException($response->errmsg); 47 | } 48 | 49 | /** 50 | * 读取成员 51 | * 在通讯录同步助手中此接口可以读取企业通讯录的所有成员信息,而企业自定义的应用可以读取该应用设置的可见范围内的成员信息。 52 | * 系统应用须拥有指定部门的管理权限。 53 | * 54 | * @param unknown $accessToken 55 | * @param unknown $userId 56 | * @throws YDWXException 57 | * @return YDWXQYUserResponse 58 | */ 59 | function ydwx_qy_user_get($accessToken, $userId){ 60 | $http = new YDHttps(); 61 | $response= $http->get(YDWX_WEIXIN_QY_BASE_URL."user/get?access_token={$accessToken}&userid={$userId}"); 62 | $response = new YDWXQYUserResponse($response); 63 | if($response->isSuccess()){ 64 | return $response; 65 | } 66 | throw new YDWXException($response->errmsg); 67 | } 68 | 69 | /** 70 | * 更新成员 71 | * 系统应用须拥有指定部门、成员的管理权限。 72 | * 注意,每个部门下的节点不能超过3万个。企业号(未升级成企业微信账号)将不保存接口传过来的english_name、telephone、 73 | * isleader,order四个参数,请服务商自行保存 74 | * 75 | * @param YDWXQYUserCreate $request 76 | * @param unknown $accessToken 77 | * @throws YDWXException 78 | * @return boolean 79 | */ 80 | function ydwx_qy_user_update(YDWXQYUserCreate $request, $accessToken){ 81 | $http = new YDHttps(); 82 | $response= $http->post(YDWX_WEIXIN_QY_BASE_URL."user/update?access_token={$accessToken}", $request->toJSONString()); 83 | $response = new YDWXResponse($response); 84 | if($response->isSuccess()){ 85 | return true; 86 | } 87 | throw new YDWXException($response->errmsg); 88 | } 89 | 90 | /** 91 | * 批量删除成员 92 | * 系统应用须拥有指定成员的管理权限。 93 | * 94 | * @param unknown $accessToken 95 | * @param unknown $userids 成员UserID列表。对应管理端的帐号。(最多支持200个) 96 | * @throws YDWXException 97 | * @return boolean 98 | */ 99 | function ydwx_qy_user_batchdelete($accessToken, $userids){ 100 | $args = array(); 101 | $args["useridlist"]=(array)$userids; 102 | $http = new YDHttps(); 103 | $response= $http->post(YDWX_WEIXIN_QY_BASE_URL."user/batchdelete?access_token={$accessToken}", json_encode($args)); 104 | $response = new YDWXResponse($response); 105 | if($response->isSuccess()){ 106 | return true; 107 | } 108 | throw new YDWXException($response->errmsg); 109 | } 110 | 111 | /** 112 | * 获取部门成员 113 | * 系统应用须拥有指定部门的查看权限。 114 | * 115 | * @param unknown $accessToken 116 | * @param unknown $depart_id 117 | * @param number $fetch_childs 1/0:是否递归获取子部门下面的成员 118 | * @param number $simpleinfo 1返回简单信息YDWXQYUserSimpleInfo 0返回详细信息YDWXQYUserResponse 119 | * @throws YDWXException 120 | * @return array(YDWXQYUserSimpleInfo) | array(YDWXQYUserResponse) 121 | */ 122 | function ydwx_qy_users_of_depart($accessToken, $depart_id, $fetch_childs=0, $simpleinfo=1){ 123 | $http = new YDHttps(); 124 | $response= $http->get(YDWX_WEIXIN_QY_BASE_URL."user/".($simpleinfo ? "simplelist" :"list")."?access_token={$accessToken}&department_id={$depart_id}&fetch_child={$fetch_childs}"); 125 | $response = new YDWXResponse($response); 126 | if($response->isSuccess()){ 127 | $arr = array(); 128 | foreach ($response->userlist as $userinfo){ 129 | $user = $simpleinfo ? new YDWXQYUserSimpleInfo() : new YDWXQYUserResponse(); 130 | foreach ($userinfo as $n=>$v){ 131 | $user->$n = $v; 132 | } 133 | $arr[] = $user; 134 | } 135 | return $arr; 136 | } 137 | throw new YDWXException($response->errmsg); 138 | } 139 | 140 | /** 141 | * Userid与Openid互换接口 142 | * 该接口使用场景为微信支付、微信红包和企业转账,企业号用户在使用微信支付的功能时,需要自行将企业号的userid转成openid。在使用微信红包功能时,需要将应用id和userid转成appid和openid才能使用。 143 | * 144 | * 成员必须处于应用的可见范围内,并且管理组对应用有使用权限、对成员有查看权限。 145 | * 146 | * @param unknown $accessToken 147 | * @param unknown $app_agent_id 整型,需要发送红包的应用ID,若只是使用微信支付和企业转账,则无需该参数 148 | * @param unknown $userid 149 | * @throws YDWXException 150 | * @return array("openid","appid"); 151 | */ 152 | function ydwx_qy_user_get_openid($accessToken, $app_agent_id, $userid){ 153 | $args = array(); 154 | $args["userid"] = $userid; 155 | $args["agentid"] = $app_agent_id; 156 | $http = new YDHttps(); 157 | $response= $http->post(YDWX_WEIXIN_QY_BASE_URL."user/convert_to_openid?access_token={$accessToken}", json_encode($args)); 158 | $response = new YDWXResponse($response); 159 | if($response->isSuccess()){ 160 | return array("openid"=>$response->openid, "appid"=>$response->appid); 161 | } 162 | throw new YDWXException($response->errmsg); 163 | } 164 | 165 | /** 166 | * openid转换成userid接口 167 | * 该接口主要应用于使用微信支付、微信红包和企业转账之后的结果查询,开发者需要知道某个结果事件的openid对应企业号内成员的信息时,可以通过调用该接口进行转换查询。 168 | * 管理组需对openid对应的企业号成员有查看权限。 169 | * 170 | * @param unknown $accessToken 171 | * @param unknown $openid 172 | * @throws YDWXException 173 | * @return string userid 该openid在企业中对应的成员userid 174 | */ 175 | function ydwx_qy_user_get_userid($accessToken, $openid){ 176 | $args = array(); 177 | $args["openid"] = $openid; 178 | $http = new YDHttps(); 179 | $response= $http->post(YDWX_WEIXIN_QY_BASE_URL."user/convert_to_userid?access_token={$accessToken}", json_encode($args)); 180 | $response = new YDWXResponse($response); 181 | if($response->isSuccess()){ 182 | return $response->userid; 183 | } 184 | throw new YDWXException($response->errmsg); 185 | } 186 | 187 | /** 188 | * 创建部门 189 | * 190 | * 系统应用须拥有父部门的管理权限。 191 | * 注意,部门的最大层级为15层;部门总数不能超过3万个;每个部门下的节点不能超过3万个。建议保证创建的部门和对应部门成员是串行化处理。 192 | * 193 | * @param YDWXQYDepartCreate $request 194 | * @param unknown $accessToken 195 | * @throws YDWXException 196 | * @return int 成功返回部门id 197 | */ 198 | function ydwx_qy_department_create(YDWXQYDepartCreate $request, $accessToken){ 199 | $http = new YDHttps(); 200 | $response= $http->post(YDWX_WEIXIN_QY_BASE_URL."department/create?access_token={$accessToken}", $request->toJSONString()); 201 | $response = new YDWXResponse($response); 202 | if($response->isSuccess()){ 203 | return $response->id; 204 | } 205 | throw new YDWXException($response->errmsg); 206 | } 207 | 208 | /** 209 | * 更新部门 210 | * 如果非必须的字段未指定,则不更新该字段 211 | * 212 | * 系统应用须拥有指定部门的管理权限。注意,部门的最大层级为15层;部门总数不能超过3万个;每个部门下的节点不能超过3万个。 213 | * 214 | * @param YDWXQYDepartCreate $request 215 | * @param unknown $accessToken 216 | * @throws YDWXException 217 | * @return boolean 218 | */ 219 | function ydwx_qy_department_update(YDWXQYDepartCreate $request, $accessToken){ 220 | $http = new YDHttps(); 221 | $response= $http->post(YDWX_WEIXIN_QY_BASE_URL."department/update?access_token={$accessToken}", $request->toJSONString()); 222 | $response = new YDWXResponse($response); 223 | if($response->isSuccess()){ 224 | return true; 225 | } 226 | throw new YDWXException($response->errmsg); 227 | } 228 | 229 | /** 230 | * 删除部门 231 | * 系统应用须拥有指定部门的管理权限。 232 | * 233 | * @param string $id 不能删除根部门;不能删除含有子部门、成员的部门 234 | * @param unknown $accessToken 235 | * @throws YDWXException 236 | * @return boolean 237 | */ 238 | function ydwx_qy_department_delete($id, $accessToken){ 239 | $http = new YDHttps(); 240 | $response= $http->get(YDWX_WEIXIN_QY_BASE_URL."department/delete?access_token={$accessToken}&id={$id}"); 241 | $response = new YDWXResponse($response); 242 | if($response->isSuccess()){ 243 | return true; 244 | } 245 | throw new YDWXException($response->errmsg); 246 | } 247 | 248 | /** 249 | * 获取部门列表 250 | * 部门id。获取指定部门及其下的子部门。 如果不填,默认获取全量组织架构 251 | * 252 | * 系统应用须拥有指定部门的查看权限。 253 | * 254 | * @param string $id 不能删除根部门;不能删除含有子部门、成员的部门 255 | * @param unknown $accessToken 256 | * @throws YDWXException 257 | * @return array(YDWXQYDepartCreate) 258 | */ 259 | function ydwx_qy_departments($accessToken, $id=""){ 260 | $http = new YDHttps(); 261 | $response= $http->get(YDWX_WEIXIN_QY_BASE_URL."department/list?access_token={$accessToken}&id={$id}"); 262 | $response = new YDWXResponse($response); 263 | if($response->isSuccess()){ 264 | $arr = array(); 265 | foreach ($response->department as $userinfo){ 266 | $user = new YDWXQYDepartCreate(); 267 | foreach ($userinfo as $n=>$v){ 268 | $user->$n = $v; 269 | } 270 | $arr[] = $user; 271 | } 272 | return $arr; 273 | } 274 | throw new YDWXException($response->errmsg); 275 | } -------------------------------------------------------------------------------- /code/ydwx/functions/user.php: -------------------------------------------------------------------------------- 1 | get(YDWX_WEIXIN_QY_BASE_URL."user/getuserinfo?access_token={$accessToken}&code=$code&lang=zh_CN"); 14 | $user = new YDWXOAuthCropUser($user); 15 | if($user->isSuccess()){ 16 | return $user; 17 | } 18 | throw new YDWXException($user->errmsg); 19 | } 20 | /** 21 | * 微信内应用获取用户信息.用于用户关注了公众号或者与公众号产生了交互(菜单点击、消息会话),其他情况可能只能得到openid 22 | * 要求公众必须认证 23 | * @param unknown $accessToken oauth流程得到的token或者是ydwx/refresh.php定时刷新下来的access token 24 | * @param unknown $openid 25 | * @throws YDWXException 26 | * @return YDWXSubscribeUser 27 | */ 28 | function ydwx_user_info($accessToken, $openid){ 29 | $http = new YDHttp(); 30 | $userinfo = $http->get(YDWX_WEIXIN_BASE_URL."user/info?access_token={$accessToken}&openid=$openid&lang=zh_CN"); 31 | $user = new YDWXSubscribeUser($userinfo); 32 | if($user->isSuccess()){ 33 | return $user; 34 | } 35 | throw new YDWXException($user->errmsg); 36 | } 37 | 38 | /** 39 | * 网站应用获取用户信息 40 | * @param unknown $accessToken 注意,这里的access token是oauth认证第二步微信返回的 41 | * @param unknown $openid 42 | * @throws YDWXException 43 | * @return YDWXOAuthUser 44 | */ 45 | function ydwx_sns_userinfo($accessToken, $openid){ 46 | $http = new YDHttp(); 47 | $user = $http->get(YDWX_WEIXIN_WEB_BASE_URL."userinfo?access_token={$accessToken}&openid=$openid&lang=zh_CN"); 48 | $user = new YDWXOAuthUser($user); 49 | if($user->isSuccess()){ 50 | return $user; 51 | } 52 | throw new YDWXException($user->errmsg); 53 | } -------------------------------------------------------------------------------- /code/ydwx/index-agent.php: -------------------------------------------------------------------------------- 1 | decryptMsg($msg_sign, $timeStamp, $nonce, $from_xml, $msg); 43 | if( ! $msg)die("success"); 44 | 45 | YDWXHook::do_hook(YDWXHook::YDWX_LOG, $msg.$APPID); 46 | 47 | //微信事件指派 48 | $wxevent = YDWXEvent::CreateEventMsg($msg); 49 | if(@$APPID){ 50 | $wxevent->APPID = $APPID; 51 | } 52 | YDWXHook::do_hook($wxevent->HookName(), $wxevent); -------------------------------------------------------------------------------- /code/ydwx/index-crop.php: -------------------------------------------------------------------------------- 1 | getSHA1(YDWX_WEIXIN_TOKEN, $timestamp, $nonce, $echostr); 20 | $ret = $array[0]; 21 | 22 | if ($ret != 0) { 23 | die(); 24 | } 25 | 26 | $signature = $array[1]; 27 | if ($signature != $signature) { 28 | die(); 29 | } 30 | 31 | $result = $pc->decrypt($echostr, YDWX_WEIXIN_CROP_ID); 32 | if ($result[0] != 0) { 33 | die(); 34 | } 35 | 36 | echo $result[1]; 37 | die; 38 | } 39 | 40 | 41 | //微信通知处理 42 | $from_xml = @$raw; 43 | $msg_sign = $_GET["msg_signature"]; 44 | $timeStamp = $_GET["timestamp"]; 45 | $nonce = $_GET["nonce"]; 46 | 47 | $crypt = new WXBizMsgCrypt(YDWX_WEIXIN_TOKEN, YDWX_WEIXIN_ENCODING_AES_KEY, YDWX_WEIXIN_CROP_ID); 48 | 49 | $msg = ''; 50 | $errCode = $crypt->decryptMsg($msg_sign, $timeStamp, $nonce, $from_xml, $msg); 51 | if( ! $msg)die("success"); 52 | 53 | YDWXHook::do_hook(YDWXHook::YDWX_LOG, $msg); 54 | 55 | //微信事件指派 56 | $wxevent = YDWXEvent::CreateEventMsg($msg); 57 | YDWXHook::do_hook($wxevent->HookName(), $wxevent); -------------------------------------------------------------------------------- /code/ydwx/index.php: -------------------------------------------------------------------------------- 1 | decryptMsg($msg_sign, $timeStamp, $nonce, $from_xml, $msg); 40 | if( ! $msg)die("success"); 41 | 42 | YDWXHook::do_hook(YDWXHook::YDWX_LOG, $msg); 43 | 44 | //微信事件指派 45 | $wxevent = YDWXEvent::CreateEventMsg($msg); 46 | YDWXHook::do_hook($wxevent->HookName(), $wxevent); -------------------------------------------------------------------------------- /code/ydwx/libs/const.php: -------------------------------------------------------------------------------- 1 | #63b359 344 | * 345 | */ 346 | DEFINE("YDWX_CARD_COLOR_010", 'Color010'); 347 | /** 348 | * 颜色值#2c9f67 349 | * 350 | */ 351 | DEFINE("YDWX_CARD_COLOR_020", 'Color020'); 352 | /** 353 | * 颜色值#509fc9 354 | * 355 | */ 356 | DEFINE("YDWX_CARD_COLOR_030", 'Color030'); 357 | /** 358 | * 颜色值#5885cf 359 | * 360 | */ 361 | DEFINE("YDWX_CARD_COLOR_040", 'Color040'); 362 | /** 363 | * 颜色值#9062c0 364 | * 365 | */ 366 | DEFINE("YDWX_CARD_COLOR_050", 'Color050'); 367 | /** 368 | * 颜色值#d09a45 369 | * 370 | */ 371 | DEFINE("YDWX_CARD_COLOR_060", 'Color060'); 372 | /** 373 | * 颜色值#e4b138 374 | * 375 | */ 376 | DEFINE("YDWX_CARD_COLOR_070", 'Color070'); 377 | /** 378 | * 颜色值#ee903c 379 | * 380 | */ 381 | DEFINE("YDWX_CARD_COLOR_080", 'Color080'); 382 | /** 383 | * 颜色值#f08500 384 | * 385 | */ 386 | DEFINE("YDWX_CARD_COLOR_081", 'Color081'); 387 | /** 388 | * 颜色值#a9d92d 389 | * 390 | */ 391 | DEFINE("YDWX_CARD_COLOR_082", 'Color082'); 392 | /** 393 | * 颜色值#dd6549 394 | * 395 | */ 396 | DEFINE("YDWX_CARD_COLOR_090", 'Color090'); 397 | /** 398 | * 颜色值#cc463d 399 | * 400 | */ 401 | DEFINE("YDWX_CARD_COLOR_100", 'Color100'); 402 | /** 403 | * 颜色值#cf3e36 404 | * 405 | */ 406 | DEFINE("YDWX_CARD_COLOR_101", 'Color101'); 407 | /** 408 | * 颜色值#5E6671 409 | * 410 | */ 411 | DEFINE("YDWX_CARD_COLOR_102", 'Color102'); 412 | 413 | /** 414 | * 文本 415 | * @var unknown 416 | */ 417 | DEFINE("YDWX_CARD_CODE_TYPE_TEXT", "CODE_TYPE_TEXT"); 418 | /** 419 | * 自定义使用按钮 420 | * @var unknown 421 | */ 422 | DEFINE("YDWX_CARD_CODE_TYPE_NONE", "CODE_TYPE_NONE"); 423 | 424 | /** 425 | * 一维码 426 | * @var unknown 427 | */ 428 | DEFINE("YDWX_CARD_CODE_TYPE_BARCODE", "CODE_TYPE_BARCODE"); 429 | /** 430 | * 二维码 431 | * @var unknown 432 | */ 433 | DEFINE("YDWX_CARD_CODE_TYPE_QRCODE", "CODE_TYPE_QRCODE"); 434 | /** 435 | * 二维码无code显示 436 | * @var unknown 437 | */ 438 | DEFINE("YDWX_CARD_CODE_TYPE_ONLY_QRCODE", "CODE_TYPE_ONLY_QRCODE"); 439 | /** 440 | * 一维码无code显示 441 | * @var unknown 442 | */ 443 | DEFINE("YDWX_CARD_CODE_TYPE_ONLY_BARCODE","CODE_TYPE_ONLY_BARCODE"); 444 | /** 445 | * 表示固定日期区间 446 | * @var unknown 447 | */ 448 | DEFINE("YDWX_DATE_TYPE_FIX_TIME_RANGE","DATE_TYPE_FIX_TIME_RANGE"); 449 | /** 450 | * 表示永久有效 451 | * @var unknown 452 | */ 453 | DEFINE("YDWX_DATE_TYPE_PERMANENT","DATE_TYPE_PERMANENT"); 454 | /** 455 | * 表示固定时长(自领取后按天算) 456 | * @var unknown 457 | */ 458 | DEFINE("YDWX_DATE_TYPE_FIX_TERM","DATE_TYPE_FIX_TERM"); 459 | 460 | /** 461 | * API核销卡券 462 | * @var unknown 463 | */ 464 | DEFINE("YDWX_CARD_CONSUME_FROM_API","FROM_API"); 465 | /** 466 | * 公众平台核销 467 | * @var unknown 468 | */ 469 | DEFINE("YDWX_CARD_CONSUME_FROM_MP", "FROM_MP"); 470 | /** 471 | * 卡券商户助手核销(FROM_MOBILE_HELPER)(核销员微信号) 472 | * @var unknown 473 | */ 474 | DEFINE("YDWX_CARD_CONSUME_FROM_MOBILE_HELPER","FROM_MOBILE_HELPER"); 475 | DEFINE("YDWX_JSAPI_ONMENUSHARETIMELINE","onMenuShareTimeline"); 476 | DEFINE("YDWX_JSAPI_ONMENUSHAREAPPMESSAGE","onMenuShareAppMessage"); 477 | DEFINE("YDWX_JSAPI_ONMENUSHAREQQ","onMenuShareQQ"); 478 | DEFINE("YDWX_JSAPI_ONMENUSHAREWEIBO","onMenuShareWeibo"); 479 | DEFINE("YDWX_JSAPI_ONMENUSHAREQZONE","onMenuShareQZone"); 480 | DEFINE("YDWX_JSAPI_STARTRECORD","startRecord"); 481 | DEFINE("YDWX_JSAPI_STOPRECORD","stopRecord"); 482 | DEFINE("YDWX_JSAPI_ONVOICERECORDEND","onVoiceRecordEnd"); 483 | DEFINE("YDWX_JSAPI_PLAYVOICE","playVoice"); 484 | DEFINE("YDWX_JSAPI_PAUSEVOICE","pauseVoice"); 485 | DEFINE("YDWX_JSAPI_STOPVOICE","stopVoice"); 486 | DEFINE("YDWX_JSAPI_ONVOICEPLAYEND","onVoicePlayEnd"); 487 | DEFINE("YDWX_JSAPI_UPLOADVOICE","uploadVoice"); 488 | DEFINE("YDWX_JSAPI_DOWNLOADVOICE","downloadVoice"); 489 | DEFINE("YDWX_JSAPI_CHOOSEIMAGE","chooseImage"); 490 | DEFINE("YDWX_JSAPI_PREVIEWIMAGE","previewImage"); 491 | DEFINE("YDWX_JSAPI_UPLOADIMAGE","uploadImage"); 492 | DEFINE("YDWX_JSAPI_DOWNLOADIMAGE","downloadImage"); 493 | DEFINE("YDWX_JSAPI_TRANSLATEVOICE","translateVoice"); 494 | DEFINE("YDWX_JSAPI_GETNETWORKTYPE","getNetworkType"); 495 | DEFINE("YDWX_JSAPI_OPENLOCATION","openLocation"); 496 | DEFINE("YDWX_JSAPI_GETLOCATION","getLocation"); 497 | DEFINE("YDWX_JSAPI_HIDEOPTIONMENU","hideOptionMenu"); 498 | DEFINE("YDWX_JSAPI_SHOWOPTIONMENU","showOptionMenu"); 499 | DEFINE("YDWX_JSAPI_HIDEMENUITEMS","hideMenuItems"); 500 | DEFINE("YDWX_JSAPI_SHOWMENUITEMS","showMenuItems"); 501 | DEFINE("YDWX_JSAPI_HIDEALLNONBASEMENUITEM","hideAllNonBaseMenuItem"); 502 | DEFINE("YDWX_JSAPI_SHOWALLNONBASEMENUITEM","showAllNonBaseMenuItem"); 503 | DEFINE("YDWX_JSAPI_CLOSEWINDOW","closeWindow"); 504 | DEFINE("YDWX_JSAPI_SCANQRCODE","scanQRCode"); 505 | DEFINE("YDWX_JSAPI_CHOOSEWXPAY","chooseWXPay"); 506 | DEFINE("YDWX_JSAPI_OPENPRODUCTSPECIFICVIEW","openProductSpecificView"); 507 | DEFINE("YDWX_JSAPI_ADDCARD","addCard"); 508 | DEFINE("YDWX_JSAPI_CHOOSECARD","chooseCard"); 509 | DEFINE("YDWX_JSAPI_OPENCARD","openCard"); 510 | DEFINE("YDWX_JSAPI_STARTSEARCHBEACONS","startSearchBeacons"); 511 | DEFINE("YDWX_JSAPI_STOPSEARCHBEACONS","stopSearchBeacons"); 512 | DEFINE("YDWX_JSAPI_ONSEARCHBEACONS","onSearchBeacons"); 513 | /** 514 | * 附近 515 | * @var unknown 516 | */ 517 | DEFINE("YDWX_CARD_SCENE_NEAR_BY","SCENE_NEAR_BY"); 518 | /** 519 | * 二维码 520 | * @var unknown 521 | */ 522 | DEFINE("YDWX_CARD_SCENE_QRCODE","SCENE_QRCODE"); 523 | /** 524 | * 公众号文章 525 | * @var unknown 526 | */ 527 | DEFINE("YDWX_CARD_SCENE_ARTICLE","SCENE_ARTICLE"); 528 | /** 529 | * h5页面 530 | * @var unknown 531 | */ 532 | DEFINE("YDWX_CARD_SCENE_H5","SCENE_H5"); 533 | /** 534 | * 自定义菜单 535 | * @var unknown 536 | */ 537 | DEFINE("YDWX_CARD_SCENE_MENU","SCENE_MENU"); 538 | /** 539 | * 自动回复 540 | * @var unknown 541 | */ 542 | DEFINE("YDWX_CARD_SCENE_IVR","SCENE_IVR"); 543 | /** 544 | * 卡券自定义cell 545 | * @var unknown 546 | */ 547 | DEFINE("YDWX_CARD_SCENE_CARD_CUSTOM_CELL","SCENE_CARD_CUSTOM_CELL"); 548 | //正常 549 | DEFINE("YDWX_CARD_USER_STATUS_NORMAL","NORMAL"); 550 | //已核销 551 | DEFINE("YDWX_CARD_USER_STATUS_CONSUMED","CONSUMED"); 552 | //已过期 553 | DEFINE("YDWX_CARD_USER_STATUS_EXPIRE","EXPIRE"); 554 | //转赠中 555 | DEFINE("YDWX_CARD_USER_STATUS_GIFTING","GIFTING"); 556 | DEFINE("YDWX_CARD_USER_STATUS_GIFT_SUCC","GIFT_SUCC"); 557 | //转赠超时 558 | DEFINE("YDWX_CARD_USER_STATUS_GIFT_TIMEOUT","GIFT_TIMEOUT"); 559 | //已删除 560 | DEFINE("YDWX_CARD_USER_STATUS_DELETE","DELETE"); 561 | //已失效 562 | DEFINE("YDWX_CARD_USER_STATUS_UNAVAILABLE","UNAVAILABLE"); 563 | //code未被添加或被转赠领取的情况则统一报错 564 | DEFINE("YDWX_CARD_USER_STATUS_INVALID_CODE","invalid serial code"); 565 | /** 566 | * 待审核 567 | */ 568 | DEFINE("YDWX_CARD_STATUS_NOT_VERIFY", "CARD_STATUS_NOT_VERIFY"); 569 | /** 570 | * 审核失败 571 | */ 572 | DEFINE("YDWX_CARD_STATUS_VERIFY_FAIL", "CARD_STATUS_VERIFY_FAIL"); 573 | /** 574 | * 通过审核 575 | */ 576 | DEFINE("YDWX_CARD_STATUS_VERIFY_OK", "CARD_STATUS_VERIFY_OK"); 577 | /** 578 | * 卡券被商户删除 579 | */ 580 | DEFINE("YDWX_CARD_STATUS_USER_DELETE", "CARD_STATUS_USER_DELETE"); 581 | /** 582 | * 在公众平台投放过的卡券 583 | */ 584 | DEFINE("YDWX_CARD_STATUS_USER_DISPATCH", "CARD_STATUS_USER_DISPATCH"); 585 | DEFINE("YDWX_CARD_STATUS_DISPATCH", "CARD_STATUS_DISPATCH"); 586 | /** 587 | * 子商户审核中 588 | * @var string 589 | */ 590 | DEFINE("YDWX_CARD_MERCHANT_CHECKING", "CHECKING"); 591 | /** 592 | * 子商户审核通过 593 | * @var string 594 | */ 595 | DEFINE("YDWX_CARD_MERCHANT_APPROVED", "APPROVED"); 596 | /** 597 | * 子商户被驳回 598 | * @var string 599 | */ 600 | DEFINE("YDWX_CARD_MERCHANT_REJECTED", "REJECTED"); 601 | /** 602 | * 子商户过期 603 | * @var string 604 | */ 605 | DEFINE("YDWX_CARD_MERCHANT_EXPIRED", "EXPIRED"); 606 | 607 | /** 608 | * 审核通过 609 | * @var unknown 610 | */ 611 | DEFINE("YDWX_CARD_CHECK_AGENT_QUALIFICATION_RESULT_PASS", "RESULT_PASS"); 612 | /** 613 | * 审核不通过 614 | * @var unknown 615 | */ 616 | DEFINE("YDWX_CARD_CHECK_AGENT_QUALIFICATION_RESULT_NOT_PASS", "RESULT_NOT_PASS"); 617 | /** 618 | * 审核中 619 | * @var unknown 620 | */ 621 | DEFINE("YDWX_CARD_CHECK_AGENT_QUALIFICATION_RESULT_CHECKING", "RESULT_CHECKING"); 622 | /** 623 | * 无提审记录 624 | * @var unknown 625 | */ 626 | DEFINE("YDWX_CARD_CHECK_AGENT_QUALIFICATION_RESULT_NOTHING_TO_CHECK", "RESULT_NOTHING_TO_CHECK"); 627 | 628 | /** 629 | * 普通红包 630 | * @var unknown 631 | */ 632 | DEFINE("YDWX_PACKET_TYPE_NORMAL", "NORMAL"); 633 | /** 634 | * 裂变红包(可分享红包给好友,无关注公众号能力) 635 | * @var unknown 636 | */ 637 | DEFINE("YDWX_PACKET_TYPE_GROUP", "GROUP"); 638 | /** 639 | * 风控设置,正常情况 640 | * @var unknown 641 | */ 642 | DEFINE("YDWX_PACKET_RISK_CNTL_NORMAL", "NORMAL"); 643 | /** 644 | * 风控设置,忽略防刷限制,强制发放; 645 | * @var unknown 646 | */ 647 | DEFINE("YDWX_PACKET_RISK_CNTL_IGN_FREQ_LMT", "IGN_FREQ_LMT"); 648 | /** 649 | * 风控设置,忽略单用户日限额限制,强制发放 650 | * @var unknown 651 | */ 652 | DEFINE("YDWX_PACKET_RISK_CNTL_IGN_DAY_LMT", "IGN_DAY_LMT"); 653 | /** 654 | * 风控设置,忽略防刷和单用户日限额限制,强制发放 655 | * @var unknown 656 | */ 657 | DEFINE("YDWX_PACKET_RISK_CNTL_IGN_FREQ_DAY_LMT", "IGN_FREQ_DAY_LMT"); 658 | /** 659 | * 红包金额设置方式,只对裂变红包生效。ALL_RAND—全部随机 660 | * @var unknown 661 | */ 662 | DEFINE("YDWX_PACKET_AMT_TYPE_ALL_RAND", "ALL_RAND"); 663 | 664 | 665 | define("YDWX_WEIXIN_BASE_URL", "https://api.weixin.qq.com/cgi-bin/"); 666 | define("YDWX_WEIXIN_BASE_URL2", "https://api.weixin.qq.com/"); 667 | define("YDWX_WEIXIN_WEB_BASE_URL", "https://api.weixin.qq.com/sns/"); 668 | define("YDWX_WEIXIN_NO_SSL_URL", "http://api.weixin.qq.com/cgi-bin/"); 669 | define("YDWX_WEIXIN_QY_BASE_URL", "https://qyapi.weixin.qq.com/cgi-bin/"); 670 | define("YDWX_WEIXIN_PAY_URL", "https://api.mch.weixin.qq.com/"); 671 | 672 | ?> -------------------------------------------------------------------------------- /code/ydwx/libs/errorCode.php: -------------------------------------------------------------------------------- 1 | 6 | *
  • -40001: 签名验证错误
  • 7 | *
  • -40002: xml解析失败
  • 8 | *
  • -40003: sha加密生成签名失败
  • 9 | *
  • -40004: encodingAesKey 非法
  • 10 | *
  • -40005: appid 校验错误
  • 11 | *
  • -40006: aes 加密失败
  • 12 | *
  • -40007: aes 解密失败
  • 13 | *
  • -40008: 解密后得到的buffer非法
  • 14 | *
  • -40009: base64加密失败
  • 15 | *
  • -40010: base64解密失败
  • 16 | *
  • -40011: 生成xml失败
  • 17 | * 18 | */ 19 | class ErrorCode 20 | { 21 | public static $OK = 0; 22 | public static $ValidateSignatureError = -40001; 23 | public static $ParseXmlError = -40002; 24 | public static $ComputeSignatureError = -40003; 25 | public static $IllegalAesKey = -40004; 26 | public static $ValidateAppidError = -40005; 27 | public static $EncryptAESError = -40006; 28 | public static $DecryptAESError = -40007; 29 | public static $IllegalBuffer = -40008; 30 | public static $EncodeBase64Error = -40009; 31 | public static $DecodeBase64Error = -40010; 32 | public static $GenReturnXmlError = -40011; 33 | } 34 | 35 | class ErrorCodeZH{ 36 | public static function common($errcode){ 37 | switch ($errcode){ 38 | case -1: return "微信系统错误"; 39 | case 40001: return "获取access_token时AppSecret错误,或者access_token无效。请开发者认真比对AppSecret的正确性,或查看是否正在为恰当的公众号调用接口"; 40 | case 40002: return "不合法的凭证类型"; 41 | case 40003: return "不合法的OpenID,请开发者确认OpenID(该用户)是否已关注公众号,或是否是其他公众号的OpenID"; 42 | case 40004: return "不合法的媒体文件类型"; 43 | case 40005: return "不合法的文件类型"; 44 | case 40006: return "不合法的文件大小"; 45 | case 40007: return "不合法的媒体文件id"; 46 | case 40008: return "不合法的消息类型"; 47 | case 40009: return "不合法的图片文件大小"; 48 | case 40010: return "不合法的语音文件大小"; 49 | case 40011: return "不合法的视频文件大小"; 50 | case 40012: return "不合法的缩略图文件大小"; 51 | case 40013: return "不合法的AppID,请开发者检查AppID的正确性,避免异常字符,注意大小写"; 52 | case 40014: return "不合法的access_token,请开发者认真比对access_token的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口"; 53 | case 40015: return "不合法的菜单类型"; 54 | case 40016: return "不合法的按钮个数"; 55 | case 40017: return "不合法的按钮个数"; 56 | case 40018: return "不合法的按钮名字长度"; 57 | case 40019: return "不合法的按钮KEY长度"; 58 | case 40020: return "不合法的按钮URL长度"; 59 | case 40021: return "不合法的菜单版本号"; 60 | case 40022: return "不合法的子菜单级数"; 61 | case 40023: return "不合法的子菜单按钮个数"; 62 | case 40024: return "不合法的子菜单按钮类型"; 63 | case 40025: return "不合法的子菜单按钮名字长度"; 64 | case 40026: return "不合法的子菜单按钮KEY长度"; 65 | case 40027: return "不合法的子菜单按钮URL长度"; 66 | case 40028: return "不合法的自定义菜单使用用户"; 67 | case 40029: return "不合法的oauth_code"; 68 | case 40030: return "不合法的refresh_token"; 69 | case 40031: return "不合法的openid列表"; 70 | case 40032: return "不合法的openid列表长度"; 71 | case 40033: return "不合法的请求字符,不能包含\uxxxx格式的字符"; 72 | case 40035: return "不合法的参数"; 73 | case 40038: return "不合法的请求格式"; 74 | case 40039: return "不合法的URL长度"; 75 | case 40050: return "不合法的分组id"; 76 | case 40051: return "分组名字不合法"; 77 | case 40053: return "不合法的actioninfo,请开发者确认参数正确。"; 78 | case 40056: return "不合法的Code码。"; 79 | case 40071: return "不合法的卡券类型。"; 80 | case 40072: return "不合法的编码方式。"; 81 | case 40078: return "不合法的卡券状态。"; 82 | case 40079: return "不合法的时间。"; 83 | case 40080: return "不合法的CardExt。"; 84 | case 40094: return "参数不正确,请检查json 字段"; 85 | case 40099: return "卡券已被核销。"; 86 | 87 | case 40100: return "不合法的时间区间。"; 88 | case 40116: return "不合法的Code码。"; 89 | case 40117: return "分组名字不合法"; 90 | case 40118: return "media_id大小不合法"; 91 | case 40119: return "button类型错误"; 92 | case 40120: return "button类型错误"; 93 | case 40121: return "不合法的media_id类型"; 94 | case 40132: return "微信号不合法"; 95 | case 40137: return "不支持的图片格式"; 96 | case 40122: return "不合法的库存数量。"; 97 | case 40124: return "会员卡设置查过限制的 custom_field字段。"; 98 | case 40127: return "卡券被用户删除或转赠中。"; 99 | 100 | case 41001: return "缺少access_token参数"; 101 | case 41002: return "缺少appid参数"; 102 | case 41003: return "缺少refresh_token参数"; 103 | case 41004: return "缺少secret参数"; 104 | case 41005: return "缺少多媒体文件数据"; 105 | case 41006: return "缺少media_id参数"; 106 | case 41007: return "缺少子菜单数据"; 107 | case 41008: return "缺少oauth code"; 108 | case 41009: return "缺少openid"; 109 | case 41011: return "缺少必填字段。"; 110 | case 41012: return "缺少cardid参数。"; 111 | 112 | case 42001: return "access_token超时,请检查access_token的有效期,请参考基础支持-获取access_token中,对access_token的详细机制说明"; 113 | case 42002: return "refresh_token超时"; 114 | case 42003: return "oauth_code超时"; 115 | 116 | case 43001: return "需要GET请求"; 117 | case 43002: return "需要POST请求"; 118 | case 43003: return "需要HTTPS请求"; 119 | case 43004: return "需要接收者关注"; 120 | case 43005: return "需要好友关系"; 121 | case 43009: return "自定义SN权限,请前往公众平台申请。"; 122 | case 43010: return "无储值权限,请前往公众平台申请。"; 123 | 124 | case 44001: return "多媒体文件为空"; 125 | case 44002: return "POST的数据包为空"; 126 | case 44003: return "图文消息内容为空"; 127 | case 44004: return "文本消息内容为空"; 128 | 129 | case 45001: return "多媒体文件大小超过限制"; 130 | case 45002: return "消息内容超过限制"; 131 | case 45003: return "标题字段超过限制"; 132 | case 45004: return "描述字段超过限制"; 133 | case 45005: return "链接字段超过限制"; 134 | case 45006: return "图片链接字段超过限制"; 135 | case 45007: return "语音播放时间超过限制"; 136 | case 45008: return "图文消息超过限制"; 137 | case 45009: return "接口调用超过限制"; 138 | case 45010: return "创建菜单个数超过限制"; 139 | case 45015: return "回复时间超过限制"; 140 | case 45016: return "系统分组,不允许修改"; 141 | case 45017: return "分组名字过长"; 142 | case 45018: return "分组数量超过上限"; 143 | case 45021: return "字段超过长度限制,请参考相应接口的字段说明。"; 144 | case 45030: return "该cardid无接口权限。"; 145 | case 45031: return "库存为0。"; 146 | case 45033: return "用户领取次数超过限制get_limit"; 147 | 148 | case 46001: return "不存在媒体数据"; 149 | case 46002: return "不存在的菜单版本"; 150 | case 46003: return "不存在的菜单数据"; 151 | case 46004: return "不存在的用户"; 152 | 153 | case 47001: return "解析JSON/XML内容错误"; 154 | 155 | case 48001: return "api功能未授权,请确认公众号已获得该接口,可以在公众平台官网-开发者中心页中查看接口权限"; 156 | 157 | case 50001: return "用户未授权该api"; 158 | case 50002: return "用户受限,可能是违规后接口被封禁"; 159 | 160 | case 61451: return "参数错误(invalid parameter)"; 161 | case 61452: return "无效客服账号(invalid kf_account)"; 162 | case 61453: return "客服帐号已存在(kf_account exsited)"; 163 | case 61454: return "客服帐号名长度超过限制(仅允许10个英文字符,不包括@及@后的公众号的微信号)(invalid kf_acount length)"; 164 | case 61455: return "客服帐号名包含非法字符(仅允许英文+数字)(illegal character in kf_account)"; 165 | case 61456: return "客服帐号个数超过限制(10个客服账号)(kf_account count exceeded)"; 166 | case 61457: return "无效头像文件类型(invalid file type)"; 167 | case 61450: return "系统错误(system error)"; 168 | case 61500: return "日期格式错误"; 169 | case 61501: return "日期范围错误"; 170 | 171 | case 65104: return "门店的类型不合法,必须严格按照附表的分类填写"; 172 | case 65105: return "图片url 不合法,必须使用接口1 的图片上传接口所获取的url"; 173 | case 65106: return "门店状态必须未审核通过"; 174 | case 65107: return "扩展字段为不允许修改的状态"; 175 | case 65109: return "门店名为空"; 176 | case 65110: return "门店所在详细街道地址为空"; 177 | case 65111: return "门店的电话为空"; 178 | case 65112: return "门店所在的城市为空"; 179 | case 65113: return "门店所在的省份为空"; 180 | case 65114: return "图片列表为空"; 181 | case 65115: return "poi_id 不正确"; 182 | 183 | case 9001001: return "POST数据参数不合法"; 184 | case 9001002: return "远端服务不可用"; 185 | case 9001003: return "Ticket不合法"; 186 | case 9001004: return "获取摇周边用户信息失败"; 187 | case 9001005: return "获取商户信息失败"; 188 | case 9001006: return "获取OpenID失败"; 189 | case 9001007: return "上传文件缺失"; 190 | case 9001008: return "上传素材的文件类型不合法"; 191 | case 9001009: return "上传素材的文件尺寸不合法"; 192 | case 9001010: return "上传失败"; 193 | case 9001020: return "帐号不合法"; 194 | case 9001021: return "已有设备激活率低于50%,不能新增设备"; 195 | case 9001022: return "设备申请数不合法,必须为大于0的数字"; 196 | case 9001023: return "已存在审核中的设备ID申请"; 197 | case 9001024: return "一次查询设备ID数量不能超过50"; 198 | case 9001025: return "设备ID不合法"; 199 | case 9001026: return "页面ID不合法"; 200 | case 9001027: return "页面参数不合法"; 201 | case 9001028: return "一次删除页面ID数量不能超过10"; 202 | case 9001029: return "页面已应用在设备中,请先解除应用关系再删除"; 203 | case 9001030: return "一次查询页面ID数量不能超过50"; 204 | case 9001031: return "时间区间不合法"; 205 | case 9001032: return "保存设备与页面的绑定关系参数错误"; 206 | case 9001033: return "门店ID不合法"; 207 | case 9001034: return "设备备注信息过长"; 208 | case 9001035: return "设备申请参数不合法"; 209 | case 9001036: return "查询起始值begin不合法"; 210 | case 9001037: return "单个设备绑定页面不能超过30个"; 211 | case 9001038: return "设备总数超过了限额"; 212 | case 9001039: return "不合法的联系人名字"; 213 | case 9001040: return "不合法的联系人电话"; 214 | case 9001041: return "不合法的联系人邮箱"; 215 | case 9001042: return "不合法的行业id"; 216 | case 9001043: return "不合法的资质证明文件url,文件需通过“素材管理”接口上传"; 217 | case 9001044: return "缺少资质证明文件"; 218 | case 9001045: return "申请理由不能超过500字"; 219 | case 9001046: return "公众账号未认证"; 220 | case 9001047: return "不合法的设备申请批次id"; 221 | case 9001048: return "审核状态为审核中或审核已通过,不能再提交申请请求"; 222 | case 9001049: return "获取分组元数据失败"; 223 | case 9001050: return "账号下分组数达到上限,最多为100个"; 224 | case 9001051: return "分组包含的设备数达到上限,最多为10000个"; 225 | case 9001052: return "每次添加到分组的设备数达到上限,每次最多操作1000个设备"; 226 | case 9001053: return "每次从分组删除的设备数达到上限,每次最多操作1000个设备"; 227 | case 9001054: return "待删除的分组仍存在设备"; 228 | case 9001055: return "分组名称过长,上限为100个字符"; 229 | case 9001056: return "分组待添加或删除的设备列表中包含有不属于该分组的设备id"; 230 | case 9001057: return "分组相关信息操作失败"; 231 | case 9001058: return "分组id不存在"; 232 | case 9001059: return "模板页面logo_url为空"; 233 | case 9001060: return "创建红包活动失败"; 234 | case 9001061: return "获得红包活动ID失败"; 235 | case 9001062: return "创建模板页面失败"; 236 | case 9001063: return "红包提供商户公众号ID和红包发放商户公众号ID不一致"; 237 | case 9001064: return "红包权限审核失败"; 238 | case 9001065: return "红包权限正在审核"; 239 | case 9001066: return "红包权限被取消"; 240 | case 9001067: return "没有红包权限"; 241 | case 9001068: return "红包活动时间不在红包权限有效时间内"; 242 | case 9001069: return "设置红包活动开关失败"; 243 | case 9001070: return "获得红包活动信息失败"; 244 | case 9001071: return "查询红包ticket失败"; 245 | case 9001072: return "红包ticket数量超过限制"; 246 | case 9001073: return "sponsor_appid与预下单时的wxappid不一致"; 247 | case 9001074: return "获得红包发送ID失败"; 248 | case 9001075: return "录入活动的红包总数超过创建活动时预设的total"; 249 | case 9001076: return "添加红包发送ID失败"; 250 | case 9001077: return "解码红包发送ID失败"; 251 | case 9001078: return "获取公众号uin失败"; 252 | case 9001079: return "接口调用appid与调用创建活动接口的appid不一致"; 253 | case 9001090: return "录入的所有ticket都是无效ticket,可能原因为ticket重复使用,过期或金额不在1-1000元之间"; 254 | case 9001091: return "活动已过期"; 255 | default :return null; 256 | } 257 | } 258 | } 259 | ?> -------------------------------------------------------------------------------- /code/ydwx/libs/model.php: -------------------------------------------------------------------------------- 1 | "标题名称","type"=>YDWXMenu::TYPEXXX,"key"=>"菜单标识key","url"=跳转url,"sub_button"=[二级菜单]] 25 | * @return YDWXMenu 26 | */ 27 | public static function build(array $msg){ 28 | $obj = new YDWXMenu(); 29 | 30 | $obj->name = $msg['name']; 31 | $obj->type = $msg['type']; 32 | $obj->key = $msg['key']; 33 | $obj->url = $msg['url']; 34 | 35 | $obj->sub_button = array(); 36 | 37 | foreach ($msg['sub_button'] as $subbtn){ 38 | $obj->sub_button[] = YDWXMenu::build($subbtn); 39 | } 40 | return $obj; 41 | } 42 | 43 | public function toArray(){ 44 | $array = array(); 45 | if ($this->type) $array['type'] = $this->type; 46 | if ($this->name) $array['name'] = $this->name; 47 | if ($this->key) $array['key'] = $this->key; 48 | if ($this->url) $array['url'] = $this->url; 49 | if ($this->sub_button) { 50 | foreach ($this->sub_button as $button){ 51 | $array['sub_button'][] = $button->toArray(); 52 | } 53 | } 54 | return $array; 55 | } 56 | } 57 | 58 | /** 59 | * 微信后台创建的菜单内容 60 | * @author leeboo 61 | * 62 | */ 63 | class YDWXSelfMenu extends YDWXMenu{ 64 | /** 65 | * 跳转网页 66 | * @var unknown 67 | */ 68 | const TYPE_VIEW = "view"; 69 | /** 70 | * 返回文本 71 | * @var unknown 72 | */ 73 | const TYPE_TEXT = "text"; 74 | /** 75 | * 返回图片 76 | * @var unknown 77 | */ 78 | const TYPE_IMG = "img"; 79 | /** 80 | * 返回图片 81 | * @var unknown 82 | */ 83 | const TYPE_PHOTO = "photo"; 84 | /** 85 | * 返回视频 86 | * @var unknown 87 | */ 88 | const TYPE_VIDEO = "video"; 89 | /** 90 | * 返回音频 91 | * @var unknown 92 | */ 93 | const TYPE_VOICE = "voice"; 94 | /** 95 | * 图文消息数组,每项是YDWXSelfMenuNewsInfo对象 96 | * 97 | * @var unknown 98 | */ 99 | public $news_info = array(); 100 | public static function build(array $msg){ 101 | $obj = new YDWXSelfMenu(); 102 | 103 | $obj->name = $msg['name']; 104 | $obj->type = @$msg['type']; 105 | $obj->key = @$msg['value']; 106 | $obj->url = @$msg['url']; 107 | 108 | $obj->sub_button = array(); 109 | 110 | foreach (@$msg['sub_button']['list'] as $subbtn){ 111 | $obj->sub_button[] = YDWXMenu::build($subbtn); 112 | } 113 | foreach (@$msg['news_info']['list'] as $news){ 114 | $obj->news_info[] = new YDWXSelfMenuNewsInfo($news); 115 | } 116 | return $obj; 117 | } 118 | 119 | public function toArray(){ 120 | $array = array(); 121 | if ($this->type) $array['type'] = $this->type; 122 | if ($this->name) $array['name'] = $this->name; 123 | if ($this->key) $array['key'] = $this->key; 124 | if ($this->url) $array['url'] = $this->url; 125 | if ($this->sub_button) { 126 | foreach ($this->sub_button as $button){ 127 | $array['sub_button']['list'][] = $button->toArray(); 128 | } 129 | } 130 | if ($this->news_info) { 131 | foreach ($this->news_info as $button){ 132 | $array['news_info']['list'][] = $button->toArray(); 133 | } 134 | } 135 | return $array; 136 | } 137 | } 138 | 139 | class YDWXSelfMenuNewsInfo{ 140 | /** 141 | * 作者 142 | */ 143 | public $author; 144 | /** 145 | * 正文的URL 146 | */ 147 | public $content_url; 148 | /** 149 | * 封面图片的URL 150 | * @var unknown 151 | */ 152 | public $cover_url; 153 | /** 154 | * 摘要 155 | * @var unknown 156 | */ 157 | public $digest; 158 | /** 159 | * 是否显示封面,0为不显示,1为显示 160 | * @var unknown 161 | */ 162 | public $show_cover; 163 | /** 164 | * 原文的URL,若置空则无查看原文入口 165 | */ 166 | public $source_url; 167 | /** 168 | * 图文消息的标题 169 | * @var unknown 170 | */ 171 | public $title; 172 | public function __construct($arr){ 173 | foreach ($arr as $n=>$v){ 174 | $this->$n = $v; 175 | } 176 | } 177 | public function toArray(){ 178 | return get_object_vars($this); 179 | } 180 | } 181 | 182 | /** 183 | * ydwx 接口参数基类 184 | * 185 | * @author leeboo 186 | * 187 | */ 188 | abstract class YDWXRequest{ 189 | public $sign; 190 | public function __toString(){ 191 | return $this->toString(); 192 | } 193 | /** 194 | * 根据设置的属性及微信接口参数要求验证、构建数据,有问题抛出YDWXException 195 | * 这是在toString,toJSONString,toXMLString之前会调用的一步 196 | */ 197 | public abstract function valid(); 198 | 199 | public static function ignoreNull(array $args){ 200 | $array = array(); 201 | foreach($args as $name=>$value){ 202 | if(is_array($value)){ 203 | $array[$name] = YDWXRequest::ignoreNull($value); 204 | }else if( ! is_null($value)){ 205 | $array[$name] = $value; 206 | } 207 | } 208 | return $array; 209 | } 210 | /** 211 | * 使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串, 212 | * 注意这里返回的字符串是urlencode格式的,在某些签名场合注意urldecode出原内容 213 | * @return string 214 | */ 215 | public function toString(){ 216 | $this->valid(); 217 | $args = YDWXRequest::ignoreNull($this->sortArg()); 218 | return http_build_query($args); 219 | } 220 | public function toJSONString(){ 221 | $this->valid(); 222 | $args = YDWXRequest::ignoreNull($this->sortArg()); 223 | return ydwx_json_encode($args); 224 | } 225 | public function toArray(){ 226 | $this->valid(); 227 | return YDWXRequest::ignoreNull($this->sortArg()); 228 | } 229 | public function toXMLString(){ 230 | $this->valid(); 231 | $args = YDWXRequest::ignoreNull($this->sortArg()); 232 | 233 | $xml = ""; 234 | foreach ($args as $name=>$value){ 235 | if(is_array($value)){ 236 | $xml .= "<{$name}>".$this->arrayToXml($value).""; 237 | }else{ 238 | $xml .= "<{$name}>"; 239 | } 240 | } 241 | return $xml.""; 242 | } 243 | private function arrayToXml($array){ 244 | $xml = ""; 245 | foreach($array as $key => $value){ 246 | if( ! is_numeric($key)){ 247 | $xml .= "<{$key}>"; 248 | } 249 | if( is_array($value)){ 250 | $xml .= $this->arrayToXml($value); 251 | }else{ 252 | $xml .= ""; 253 | } 254 | if( ! is_numeric($key)){ 255 | $xml .= ""; 256 | } 257 | } 258 | return $xml; 259 | } 260 | /** 261 | * 构建自己的数据结构,默认实现是把所有的非null属性组成数组返回 262 | * @return multitype: 263 | */ 264 | protected function formatArgs(){ 265 | return YDWXRequest::ignoreNull(get_object_vars($this)); 266 | } 267 | /** 268 | * 返回按字典排序后的属性数组,排序依据是key 269 | */ 270 | public final function sortArg(){ 271 | $args = $this->formatArgs(); 272 | ksort($args); 273 | return $args; 274 | } 275 | /** 276 | * 根据微信的要求进行签名并设置sign属性 277 | * 缺省实现是微信支付的sign实现,见https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_3 278 | * 其它sign规则需要重载该方法 279 | */ 280 | public function sign(){ 281 | 282 | } 283 | } 284 | 285 | class YDWXException extends \Exception{ 286 | public function YDWXException($message=null, $code=null, $previous=null){ 287 | $zhMsg = ErrorCodeZH::common($code); 288 | YDWXHook::do_hook(YDWXHook::YDWX_LOG, $message.$code); 289 | parent::__construct($zhMsg ? $zhMsg."($message)" : $message, $code, $previous); 290 | } 291 | } 292 | 293 | /** 294 | * 微信消息封装基类,便于知道每种消息有什么内容 295 | */ 296 | class YDWXResponse{ 297 | /** 298 | * 真值表示有错误 299 | * @var unknown 300 | */ 301 | public $errcode; 302 | public $errmsg; 303 | public $rawData; 304 | 305 | 306 | public function __construct($msg=null){ 307 | $this->rawData = $msg; 308 | if($msg){ 309 | $this->build($msg); 310 | } 311 | } 312 | /** 313 | * @return 返回bool值,表示微信的业务处理成功 314 | */ 315 | public function isSuccess(){ 316 | return ! $this->errcode; 317 | } 318 | /** 319 | * 解析消息,默认以json字符串进行解析;错误返回格式:{"errcode":,"errmsg":""} 320 | * 321 | * @param string $msg 322 | */ 323 | public function build($msg){ 324 | $info = json_decode($msg, true); 325 | if($info){ 326 | foreach ($info as $name => $value){ 327 | $this->$name = $value; 328 | } 329 | if($this->errcode){ 330 | $this->errmsg .= "(".$this->errcode.")"; 331 | } 332 | }else{ 333 | $this->errcode = -1; 334 | $this->errmsg = "响应字符串格式不对({$msg})"; 335 | } 336 | } 337 | } -------------------------------------------------------------------------------- /code/ydwx/libs/pkcs7Encoder.php: -------------------------------------------------------------------------------- 1 | 32) { 47 | $pad = 0; 48 | } 49 | return substr($text, 0, (strlen($text) - $pad)); 50 | } 51 | 52 | } 53 | 54 | /** 55 | * Prpcrypt class 56 | * 57 | * 提供接收和推送给公众平台消息的加解密接口. 58 | */ 59 | class Prpcrypt 60 | { 61 | public $key; 62 | 63 | function Prpcrypt($k) 64 | { 65 | $this->key = base64_decode($k . "="); 66 | } 67 | 68 | /** 69 | * 对明文进行加密 70 | * @param string $text 需要加密的明文 71 | * @param string $appid 公众号appid,如果是企业号则为cropid 72 | * @return string 加密后的密文 73 | */ 74 | public function encrypt($text, $appid) 75 | { 76 | 77 | try { 78 | //获得16位随机字符串,填充到明文之前 79 | $random = $this->getRandomStr(); 80 | $text = $random . pack("N", strlen($text)) . $text . $appid; 81 | // 网络字节序 82 | $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 83 | $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 84 | $iv = substr($this->key, 0, 16); 85 | //使用自定义的填充方式对明文进行补位填充 86 | $pkc_encoder = new PKCS7Encoder; 87 | $text = $pkc_encoder->encode($text); 88 | mcrypt_generic_init($module, $this->key, $iv); 89 | //加密 90 | $encrypted = mcrypt_generic($module, $text); 91 | mcrypt_generic_deinit($module); 92 | mcrypt_module_close($module); 93 | 94 | //print(base64_encode($encrypted)); 95 | //使用BASE64对加密后的字符串进行编码 96 | return array(ErrorCode::$OK, base64_encode($encrypted)); 97 | } catch (Exception $e) { 98 | //print $e; 99 | return array(ErrorCode::$EncryptAESError, null); 100 | } 101 | } 102 | 103 | /** 104 | * 对密文进行解密 105 | * @param string $encrypted 需要解密的密文 106 | * @return string 解密得到的明文 107 | */ 108 | public function decrypt($encrypted, $appid) 109 | { 110 | 111 | try { 112 | //使用BASE64对需要解密的字符串进行解码 113 | $ciphertext_dec = base64_decode($encrypted); 114 | $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 115 | $iv = substr($this->key, 0, 16); 116 | mcrypt_generic_init($module, $this->key, $iv); 117 | 118 | //解密 119 | $decrypted = mdecrypt_generic($module, $ciphertext_dec); 120 | mcrypt_generic_deinit($module); 121 | mcrypt_module_close($module); 122 | } catch (Exception $e) { 123 | return array(ErrorCode::$DecryptAESError, null); 124 | } 125 | 126 | 127 | try { 128 | //去除补位字符 129 | $pkc_encoder = new PKCS7Encoder; 130 | $result = $pkc_encoder->decode($decrypted); 131 | //去除16位随机字符串,网络字节序和AppId 132 | if (strlen($result) < 16) 133 | return ""; 134 | $content = substr($result, 16, strlen($result)); 135 | $len_list = unpack("N", substr($content, 0, 4)); 136 | $xml_len = $len_list[1]; 137 | $xml_content = substr($content, 4, $xml_len); 138 | $from_appid = substr($content, $xml_len + 4); 139 | } catch (Exception $e) { 140 | //print $e; 141 | return array(ErrorCode::$IllegalBuffer, null); 142 | } 143 | if ($from_appid != $appid) 144 | return array(ErrorCode::$ValidateAppidError, null); 145 | return array(0, $xml_content); 146 | 147 | } 148 | 149 | 150 | /** 151 | * 随机生成16位字符串 152 | * @return string 生成的字符串 153 | */ 154 | function getRandomStr() 155 | { 156 | 157 | $str = ""; 158 | $str_pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; 159 | $max = strlen($str_pol) - 1; 160 | for ($i = 0; $i < 16; $i++) { 161 | $str .= $str_pol[mt_rand(0, $max)]; 162 | } 163 | return $str; 164 | } 165 | 166 | } 167 | 168 | ?> -------------------------------------------------------------------------------- /code/ydwx/libs/sha1.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /code/ydwx/libs/wxBizMsgCrypt.php: -------------------------------------------------------------------------------- 1 | token = $token; 34 | $this->encodingAesKey = $encodingAesKey; 35 | $this->appId = $appId; 36 | } 37 | 38 | /** 39 | * 将公众平台回复用户的消息加密打包. 40 | *
      41 | *
    1. 对要发送的消息进行AES-CBC加密
    2. 42 | *
    3. 生成安全签名
    4. 43 | *
    5. 将消息密文和安全签名打包成xml格式
    6. 44 | *
    45 | * 46 | * @param $replyMsg string 公众平台待回复用户的消息,xml格式的字符串 47 | * @param $timeStamp string 时间戳,可以自己生成,也可以用URL参数的timestamp 48 | * @param $nonce string 随机串,可以自己生成,也可以用URL参数的nonce 49 | * @param &$encryptMsg string 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串, 50 | * 当return返回0时有效 51 | * 52 | * @return int 成功0,失败返回对应的错误码 53 | */ 54 | public function encryptMsg($replyMsg, $timeStamp, $nonce, &$encryptMsg) 55 | { 56 | $pc = new Prpcrypt($this->encodingAesKey); 57 | 58 | //加密 59 | $array = $pc->encrypt($replyMsg, $this->appId); 60 | $ret = $array[0]; 61 | if ($ret != 0) { 62 | return $ret; 63 | } 64 | 65 | if ($timeStamp == null) { 66 | $timeStamp = time(); 67 | } 68 | $encrypt = $array[1]; 69 | 70 | //生成安全签名 71 | $sha1 = new SHA1; 72 | $array = $sha1->getSHA1($this->token, $timeStamp, $nonce, $encrypt); 73 | $ret = $array[0]; 74 | if ($ret != 0) { 75 | return $ret; 76 | } 77 | $signature = $array[1]; 78 | 79 | //生成发送的xml 80 | $xmlparse = new XMLParse; 81 | $encryptMsg = $xmlparse->generate($encrypt, $signature, $timeStamp, $nonce); 82 | return ErrorCode::$OK; 83 | } 84 | 85 | 86 | /** 87 | * 检验消息的真实性,并且获取解密后的明文. 88 | *
      89 | *
    1. 利用收到的密文生成安全签名,进行签名验证
    2. 90 | *
    3. 若验证通过,则提取xml中的加密消息
    4. 91 | *
    5. 对消息进行解密
    6. 92 | *
    93 | * 94 | * @param $msgSignature string 签名串,对应URL参数的msg_signature 95 | * @param $timestamp string 时间戳 对应URL参数的timestamp 96 | * @param $nonce string 随机串,对应URL参数的nonce 97 | * @param $postData string 密文,对应POST请求的数据 98 | * @param &$msg string 解密后的原文,当return返回0时有效 99 | * 100 | * @return int 成功0,失败返回对应的错误码 101 | */ 102 | public function decryptMsg($msgSignature, $timestamp = null, $nonce, $postData, &$msg) 103 | { 104 | if (strlen($this->encodingAesKey) != 43) { 105 | return ErrorCode::$IllegalAesKey; 106 | } 107 | 108 | $pc = new Prpcrypt($this->encodingAesKey); 109 | 110 | //提取密文 111 | $xmlparse = new XMLParse; 112 | $array = $xmlparse->extract($postData); 113 | $ret = $array[0]; 114 | 115 | if ($ret != 0) { 116 | return $ret; 117 | } 118 | 119 | if ($timestamp == null) { 120 | $timestamp = time(); 121 | } 122 | 123 | $encrypt = $array[1]; 124 | $touser_name = $array[2]; 125 | 126 | //验证安全签名 127 | $sha1 = new SHA1; 128 | $array = $sha1->getSHA1($this->token, $timestamp, $nonce, $encrypt); 129 | $ret = $array[0]; 130 | 131 | if ($ret != 0) { 132 | return $ret; 133 | } 134 | 135 | $signature = $array[1]; 136 | if ($signature != $msgSignature) { 137 | return ErrorCode::$ValidateSignatureError; 138 | } 139 | 140 | $result = $pc->decrypt($encrypt, $this->appId); 141 | if ($result[0] != 0) { 142 | return $result[0]; 143 | } 144 | $msg = $result[1]; 145 | 146 | return ErrorCode::$OK; 147 | } 148 | 149 | } 150 | 151 | -------------------------------------------------------------------------------- /code/ydwx/libs/xmlparse.php: -------------------------------------------------------------------------------- 1 | loadXML($xmltext); 22 | $array_e = $xml->getElementsByTagName('Encrypt'); 23 | $array_a = $xml->getElementsByTagName('ToUserName'); 24 | $encrypt = $array_e->item(0)->nodeValue; 25 | $tousername = $array_a->item(0)->nodeValue; 26 | return array(0, $encrypt, $tousername); 27 | } catch (Exception $e) { 28 | //print $e . "\n"; 29 | return array(ErrorCode::$ParseXmlError, null, null); 30 | } 31 | } 32 | 33 | /** 34 | * 生成xml消息 35 | * @param string $encrypt 加密后的消息密文 36 | * @param string $signature 安全签名 37 | * @param string $timestamp 时间戳 38 | * @param string $nonce 随机字符串 39 | */ 40 | public function generate($encrypt, $signature, $timestamp, $nonce) 41 | { 42 | $format = " 43 | 44 | 45 | %s 46 | 47 | "; 48 | return sprintf($format, $encrypt, $signature, $timestamp, $nonce); 49 | } 50 | 51 | } 52 | 53 | 54 | ?> -------------------------------------------------------------------------------- /code/ydwx/libs/ydhttp.php: -------------------------------------------------------------------------------- 1 | appid = $appid; 35 | $this->ci = curl_init(); 36 | } 37 | 38 | public function get($url, $params = array()) 39 | { 40 | if($params){ 41 | $url .= "?".http_build_query($params); 42 | } 43 | return $this->http($url,'GET'); 44 | } 45 | 46 | public function post($url, $params = array(), $multi = false) { 47 | $query = ""; 48 | if( is_array($params)){ 49 | if($multi) 50 | $query = self::build_http_query_multi($params); 51 | else 52 | $query = http_build_query($params); 53 | }else{ 54 | $query = $params; 55 | } 56 | 57 | return $this->http($url,'POST', $query, $multi); 58 | } 59 | 60 | public static function build_http_query_multi($params) { 61 | if (!$params) return ''; 62 | 63 | // Urlencode both keys and values 64 | $keys = array_keys($params); 65 | $values = array_values($params); 66 | $params = array_combine($keys, $values); 67 | 68 | // Parameters are sorted by name, using lexicographical byte value ordering. 69 | // Ref: Spec: 9.1.1 (1) 70 | uksort($params, 'strcmp'); 71 | $pairs = array(); 72 | self::$boundary = $boundary = uniqid('------------------'); 73 | $MPboundary = '--'.$boundary; 74 | $endMPboundary = $MPboundary. '--'; 75 | $multipartbody = ''; 76 | 77 | foreach ($params as $parameter => $value) 78 | { 79 | if($value{0} == '@' ) 80 | { 81 | $url = ltrim( $value , '@' ); 82 | $content = file_get_contents( $url ); 83 | $filename = reset( explode( '?' , basename( $url ) )); 84 | $mime = self::get_image_mime($url); 85 | 86 | $multipartbody .= $MPboundary . "\r\n"; 87 | $multipartbody .= 'Content-Disposition: form-data; name="' . $parameter . '"; filename="' . $filename . '"'. "\r\n"; 88 | $multipartbody .= 'Content-Type: '. $mime . "\r\n\r\n"; 89 | $multipartbody .= $content. "\r\n"; 90 | } 91 | else 92 | { 93 | $multipartbody .= $MPboundary . "\r\n"; 94 | $multipartbody .= 'content-disposition: form-data; name="'.$parameter."\"\r\n\r\n"; 95 | $multipartbody .= $value."\r\n"; 96 | } 97 | } 98 | $multipartbody .= $endMPboundary."\r\n";//微信服务器不加\r\n会提示media data is missing 99 | return $multipartbody; 100 | 101 | } 102 | public static function get_image_mime( $file ) 103 | { 104 | $ext = strtolower(pathinfo( $file , PATHINFO_EXTENSION )); 105 | switch( $ext ) 106 | { 107 | case 'jpg': 108 | case 'jpeg': 109 | $mime = 'image/jpg'; 110 | break; 111 | 112 | case 'png'; 113 | $mime = 'image/png'; 114 | break; 115 | 116 | case 'gif'; 117 | default: 118 | $mime = 'image/gif'; 119 | break; 120 | } 121 | return $mime; 122 | } 123 | /** 124 | * Make an HTTP request 125 | * 126 | * @return API results 127 | */ 128 | protected function http($url, $method, $postfields = NULL, $multi = false) { 129 | $ci = $this->ci; 130 | $this->http_info = array(); 131 | /* Curl settings */ 132 | curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent); 133 | curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout); 134 | curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout); 135 | curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE); 136 | curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:')); 137 | curl_setopt($ci, CURLOPT_HEADER, FALSE); 138 | curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false); 139 | curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, 1); 140 | 141 | switch ($method) { 142 | case 'POST': 143 | curl_setopt($ci, CURLOPT_POST, TRUE); 144 | if (!empty($postfields)) { 145 | curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields); 146 | } 147 | break; 148 | case 'DELETE': 149 | curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE'); 150 | if (!empty($postfields)) { 151 | $url = "{$url}?{$postfields}"; 152 | } 153 | } 154 | 155 | if( $multi ) 156 | { 157 | $header_array = array("Content-Type: multipart/form-data; boundary=" . self::$boundary , "Expect: "); 158 | curl_setopt($ci, CURLOPT_HTTPHEADER, $header_array ); 159 | curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE ); 160 | } 161 | //echo $url; 162 | curl_setopt($ci, CURLOPT_URL, $url); 163 | $response = curl_exec($ci); 164 | $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); 165 | $this->http_info = array_merge($this->http_info, curl_getinfo($ci)); 166 | $this->errno = curl_errno($ci); 167 | $this->error = curl_error($ci); 168 | $this->url = $url; 169 | curl_close ($ci); 170 | return trim($response); 171 | } 172 | 173 | } 174 | /** 175 | * 对于第三方平台,构造函数需要传入所授权appid 176 | * @author leeboo 177 | * 178 | */ 179 | class YDHttps extends YDHttp{ 180 | /** 181 | * 当前微信公众号的类型(公众号,企业号或者第三方平台),见YDWX_WEIXIN_TYPE_XX 182 | * @var boolean 183 | */ 184 | public $type = YDWX_WEIXIN_TYPE_NORMAL; 185 | /** 186 | * Make an HTTP request 187 | * 188 | * @return API results 189 | */ 190 | protected function http($url, $method, $postfields = NULL, $multi = false) { 191 | curl_setopt($this->ci, CURLOPT_SSL_VERIFYPEER, false); 192 | curl_setopt($this->ci, CURLOPT_SSL_VERIFYHOST, 1); 193 | 194 | if($this->type==YDWX_WEIXIN_TYPE_AGENT){ 195 | $cert_file = YDWXHook::do_hook(YDWXHook::GET_HOST_APICLIENT_CERT_PATH, $this->appid); 196 | if(defined("SAE_TMP_PATH")){ 197 | if(copy($cert_file, SAE_TMP_PATH."cert.pem")){ 198 | $cert_file = SAE_TMP_PATH."cert.pem"; 199 | } 200 | } 201 | }else if($this->type==YDWX_WEIXIN_TYPE_CROP){ 202 | $cert_file = YDWX_WEIXIN_QY_APICLIENT_CERT; 203 | }else{ 204 | $cert_file = YDWX_WEIXIN_APICLIENT_CERT; 205 | } 206 | if($cert_file){ 207 | curl_setopt($this->ci,CURLOPT_SSLCERTTYPE,'PEM'); 208 | curl_setopt($this->ci,CURLOPT_SSLCERT, $cert_file); 209 | } 210 | 211 | 212 | if($this->type==YDWX_WEIXIN_TYPE_AGENT){ 213 | $key_file = YDWXHook::do_hook(YDWXHook::GET_HOST_APICLIENT_KEY_PATH, $this->appid); 214 | if(defined("SAE_TMP_PATH")){ 215 | if(copy($key_file, SAE_TMP_PATH."key.pem")){ 216 | $key_file = SAE_TMP_PATH."key.pem"; 217 | } 218 | } 219 | }else if($this->type==YDWX_WEIXIN_TYPE_CROP){ 220 | $key_file = YDWX_WEIXIN_QY_APICLIENT_KEY; 221 | }else{ 222 | $key_file = YDWX_WEIXIN_APICLIENT_KEY; 223 | } 224 | if($key_file){ 225 | curl_setopt($this->ci,CURLOPT_SSLKEYTYPE,'PEM'); 226 | curl_setopt($this->ci,CURLOPT_SSLKEY, $key_file); 227 | } 228 | 229 | 230 | if($this->type==YDWX_WEIXIN_TYPE_AGENT){ 231 | $mch_key = YDWXHook::do_hook(YDWXHook::GET_HOST_MCH_KEY, $this->appid); 232 | }else if($this->type==YDWX_WEIXIN_TYPE_CROP){ 233 | $mch_key = YDWX_WEIXIN_QY_MCH_KEY; 234 | }else{ 235 | $mch_key = YDWX_WEIXIN_MCH_KEY; 236 | } 237 | if($mch_key){ 238 | curl_setopt($this->ci,CURLOPT_SSLKEYPASSWD, $mch_key); 239 | } 240 | 241 | return parent::http($url, $method, $postfields, $multi); 242 | } 243 | } -------------------------------------------------------------------------------- /code/ydwx/libs/ydwxhook.php: -------------------------------------------------------------------------------- 1 | "该用户在企业号后台的账号","OpenId"=>"非企业成员时返回openid", DeviceId=>"手机设备号") 注意大小写 166 | * @var unknown 167 | */ 168 | const AUTH_CROP_SUCCESS = "AUTH_CROP_SUCCESS"; 169 | 170 | /** 171 | * 预支付出现异常 172 | * @var unknown 173 | */ 174 | const PREPARE_PAY_EXCEPTION = "PREPARE_PAY_EXCEPTION"; 175 | /** 176 | * 预支付失败 177 | * @var unknown 178 | */ 179 | const PREPARE_PAY_FAIL = "PREPARE_PAY_FAIL"; 180 | /** 181 | * 预支付成功 182 | * @var unknown 183 | */ 184 | const PREPARE_PAY_SUCCESS = "PREPARE_PAY_SUCCESS"; 185 | 186 | /** 187 | * 微信支付通知 188 | * hook参数 YDWXPaiedNotifyResponse 189 | * https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_7 190 | * 处理hook的函数需要返回bool值,true表示通知已经处理了,微信不用在通知了 191 | * @var unknown 192 | */ 193 | const PAY_NOTIFY_SUCCESS = "PAY_NOTIFY_SUCCESS"; 194 | /** 195 | * 微信支付通知失败 196 | * 返回的参数YDWXPaiedNotifyResponse 197 | * @var unknown 198 | */ 199 | const PAY_NOTIFY_ERROR = "PAY_NOTIFY_ERROR"; 200 | 201 | /** 202 | * 微信扫码支付通知成功 203 | * hook参数YDWXPayingNotifyResponse, hook 函数根据接收的数据在自己的系统中生成订单. 204 | * 参数中有被扫描产品的product id,并构建YDWXPayUnifiedOrderRequest并返回 205 | * 如果出现错误抛出异常, 206 | * @var unknown 207 | */ 208 | const QRCODE_PAY_NOTIFY_SUCCESS = "QRCODE_PAY_NOTIFY_SUCCESS"; 209 | 210 | 211 | /** 212 | * 微信推送来文本消息,YDWXEventMsgText 213 | * @var unknown 214 | */ 215 | const EVENT_MSG_TEXT = "text"; 216 | 217 | /** 218 | * 微信推送来图片消息,参数是YDWXEventMsgImage 219 | * @var unknown 220 | */ 221 | const EVENT_MSG_IMAGE = "image"; 222 | /** 223 | * 微信推送来语音消息,参数是YDWXEventMsgVoice 224 | * @var unknown 225 | */ 226 | const EVENT_MSG_VOICE = "voice"; 227 | 228 | /** 229 | * 微信推送来视频消息,参数是YDWXEventMsgVideo 230 | * @var unknown 231 | */ 232 | const EVENT_MSG_VIDEO = "video"; 233 | /** 234 | * 微信推送来小视频消息,参数是YDWXEventMsgShortVideo 235 | * @var unknown 236 | */ 237 | const EVENT_MSG_SHORTVIDEO = "shortvideo"; 238 | /** 239 | * 微信推送来地理位置消息,参数是YDWXEventMsgLocation 240 | * @var unknown 241 | */ 242 | const EVENT_MSG_LOCATION = "location"; 243 | 244 | /** 245 | * 微信推送来链接消息,参数是YDWXEventMsgLink 246 | * @var unknown 247 | */ 248 | const EVENT_MSG_LINK = "link"; 249 | /** 250 | * 用户订阅事件,参数是YDWXEventSubscribe 251 | * @var unknown 252 | */ 253 | const EVENT_SUBSCRIBE = "event_subscribe"; 254 | /** 255 | * 用户扫描二维码后进行订阅事件 参数YDWXEventSubscribe 256 | * @var unknown 257 | */ 258 | const EVENT_SCAN_SUBSCRIBE = "event_scan_subscribe"; 259 | /** 260 | * 用户取消订阅事件,参数是YDWXEventUnsubscribe 261 | * @var unknown 262 | */ 263 | const EVENT_UNSUBSCRIBE = "event_unsubscribe"; 264 | /** 265 | * 用户扫描二维码后推送事件 参数YDWXEventScan 266 | * @var unknown 267 | */ 268 | const EVENT_SCAN = "event_scan"; 269 | /** 270 | * 菜单点击事件,参数是YDWXEventClick 271 | * @var unknown 272 | */ 273 | const EVENT_CLICK = "event_click"; 274 | /** 275 | * 菜单跳转事件,参数是YDWXEventView 276 | * @var unknown 277 | */ 278 | const EVENT_VIEW = "event_view"; 279 | /** 280 | * 扫码推事件的事件推送,YDWXEventScancode_push 281 | * @var unknown 282 | */ 283 | const EVENT_SCANCODE_PUSH = "event_scancode_push"; 284 | /** 285 | * 扫码推事件且弹出“消息接收中”提示框的事件推送,YDWXEventScancode_waitmsg 286 | * @var unknown 287 | */ 288 | const EVENT_SCANCODE_WAITMSG = "event_scancode_waitmsg"; 289 | 290 | /** 291 | * 弹出系统拍照发图的事件推送,参数是YDWXEventPic_sysphoto 292 | * @var unknown 293 | */ 294 | const EVENT_PIC_SYSPHOTO = "event_pic_sysphoto"; 295 | 296 | /** 297 | * 弹出拍照或者相册发图的事件推送,参数是YDWXEventPic_photo_or_album 298 | * @var unknown 299 | */ 300 | const EVENT_PIC_PHOTO_OR_ALBUM = "event_pic_photo_or_album"; 301 | 302 | /** 303 | * 弹出微信相册发图器的事件推送,参数是YDWXEventPic_Weixin 304 | * @var unknown 305 | */ 306 | const EVENT_PIC_WEIXIN = "event_pic_weixin"; 307 | 308 | /** 309 | * 弹出地理位置选择器的事件推送,参数是YDWXEventLocation_select 310 | * @var unknown 311 | */ 312 | const EVENT_LOCATION_SELECT = "event_location_select"; 313 | const EVENT_LOCATION = "event_location"; 314 | 315 | /** 316 | * 群发推送结果 YDWXEventMASSSENDJOBFINISH 317 | * @var unknown 318 | */ 319 | const EVENT_MASSSENDJOBFINISH = "event_masssendjobfinish"; 320 | 321 | /** 322 | * 第三方平台刷新ticket通知 YDWXEventComponent_verify_ticket 323 | * @var unknown 324 | */ 325 | const EVENT_COMPONENT_VERIFY_TICKET = "event_component_verify_ticket"; 326 | 327 | /** 328 | * 未知事件 YDWXEventUnknow 329 | * @var unknown 330 | */ 331 | const EVENT_UNKONW = "EVENT_UNKONW"; 332 | 333 | /** 334 | * 摇一摇周边事件通知 YDWXEventShakearoundusershake 335 | * @var unknown 336 | */ 337 | const EVENT_SHAKEAROUNDUSERSHAKE = "EVENT_SHAKEAROUNDUSERSHAKE"; 338 | 339 | /** 340 | * 核销事件通知 YDWXEventUser_consume_card 341 | * @var unknown 342 | */ 343 | const EVENT_USER_CONSUME_CARD = "EVENT_USER_CONSUME_CARD"; 344 | 345 | /** 346 | * 微信买单完成时推送 YDWXEventUser_pay_from_pay_cell 347 | * @var unknown 348 | */ 349 | const EVENT_USER_PAY_FROM_PAY_CELL = "EVENT_USER_PAY_FROM_PAY_CELL"; 350 | /** 351 | * 用户领取卡券事件通知 YDWXEventUser_get_card 352 | * @var unknown 353 | */ 354 | const EVENT_USER_GET_CARD = "EVENT_USER_GET_CARD"; 355 | /** 356 | * 生成的卡券通过审核时,微信事件推送YDWXEventCard_pass_check 357 | * @var unknown 358 | */ 359 | const EVENT_CARD_PASS_CHECK = "EVENT_CARD_PASS_CHECK"; 360 | /** 361 | * 生成的卡券没通过审核时,微信事件推送YDWXEventCard_not_pass_check 362 | * @var unknown 363 | */ 364 | const EVENT_CARD_NOT_PASS_CHECK = "EVENT_CARD_NOT_PASS_CHECK"; 365 | /** 366 | * 用户在删除卡券时推送事件YDWXEventUser_del_card 367 | * @var unknown 368 | */ 369 | const EVENT_USER_DEL_CARD = "EVENT_USER_DEL_CARD"; 370 | /** 371 | * 进入会员卡事件推送 YDWXEventUser_view_card 372 | * 需要开发者在创建会员卡时填入need_push_on_view 字段并设置为true。开发者须综合考虑领卡人数和服务器压力,决定是否接收该事件。 373 | * @var unknown 374 | */ 375 | const EVENT_USER_VIEW_CARD = "EVENT_USER_VIEW_CARD"; 376 | /** 377 | * 当用户的会员卡积分余额发生变动时,微信会推送事件告知开发者 378 | * @var YDWXEventUpdate_member_card 379 | */ 380 | const EVENT_UPDATE_MEMBER_CARD = "EVENT_UPDATE_MEMBER_CARD"; 381 | 382 | /** 383 | * 从卡券进入公众号会话事件推送 YDWXEventUser_enter_session_from_card 384 | * @var unknown 385 | */ 386 | const EVENT_USER_ENTER_SESSION_FROM_CARD = "EVENT_USER_ENTER_SESSION_FROM_CARD"; 387 | 388 | /** 389 | * 新创建的门店在审核通过后事件推送 YDWXEventPoi_check_notify 390 | * @var unknown 391 | */ 392 | const EVENT_POI_CHECK_NOTIFY = "EVENT_POI_CHECK_NOTIFY"; 393 | /** 394 | * 红包绑定用户事件通知 395 | * 注:红包绑定用户不等同于用户领取红包。用户进入红包页面后,有可能不拆红包,但该红包ticket已被绑定,不能再被其他用户绑定,过期后会退回商户财付通账户 396 | * YDWXEventShakearoundlotterybind 397 | * @var unknown 398 | */ 399 | const EVENT_SHAKEAROUNDLOTTERYBIND = "EVENT_SHAKEAROUNDLOTTERYBIND"; 400 | 401 | /** 402 | * 会员卡激活,用户填写、提交资料后,会有事件推送给商家,开发者可以在接收到事件通知后调用激活接口, 403 | * 传入会员卡号、初始积分等信息或者调用拉取会员信息接口获取会员信息,进行会员管理。 404 | * YDWXEventSubmit_membercard_user_info 405 | * @var unknown 406 | */ 407 | const EVENT_SUBMIT_MEMBERCARD_USER_INFO = "EVENT_SUBMIT_MEMBERCARD_USER_INFO"; 408 | 409 | /** 410 | * 子商户审核结果通知 411 | * 开发者所代理的子商户审核通过后,会收到微信服务器发送的事件推送。 412 | * YDWXEventCard_merchant_check_result 413 | * @var unknown 414 | */ 415 | const EVENT_CARD_MERCHANT_CHECK_RESULT = "EVENT_CARD_MERCHANT_CHECK_RESULT"; 416 | /** 417 | * 商户审核结果通知 418 | * 当子商户资质审核通过时,开发者将收到微信服务器推送的事件。 419 | * YDWXEventCard_merchant_auth_check_result 420 | * @var unknown 421 | */ 422 | const EVENT_CARD_MERCHANT_AUTH_CHECK_RESULT = "EVENT_CARD_MERCHANT_AUTH_CHECK_RESULT"; 423 | 424 | /** 425 | * 当最后一个用户领券时,会发送事件给商户,事件每隔5min发送一次。 426 | * @var YDWXEventCard_sku_remind 427 | */ 428 | const EVENT_CARD_SKU_REMIND = "EVENT_CARD_SKU_REMIND"; 429 | 430 | /** 431 | * 资质认证成功 432 | * @var YDWXEventQualification_verify_success 433 | */ 434 | const EVENT_QUALIFICATION_VERIFY_SUCCESS="EVENT_QUALIFICATION_VERIFY_SUCCESS"; 435 | /** 436 | * 资质认证失败 437 | * @var YDWXEventQualification_verify_fail 438 | */ 439 | const EVENT_QUALIFICATION_VERIFY_FAIL="EVENT_QUALIFICATION_VERIFY_FAIL"; 440 | /** 441 | * 名称认证成功(即命名成功) 442 | * @var YDWXEventNaming_verify_success 443 | */ 444 | const EVENT_NAMING_VERIFY_SUCCESS = "EVENT_NAMING_VERIFY_SUCCESS"; 445 | /** 446 | * 名称认证失败(这时虽然客户端不打勾,但仍有接口权限) 447 | * @var YDWXEventNaming_verify_fail 448 | */ 449 | const EVENT_NAMING_VERIFY_FAIL = "EVENT_NAMING_VERIFY_FAIL"; 450 | /** 451 | * 公众号年审通知 452 | * @var YDWXEventAnnual_renew 453 | */ 454 | const EVENT_ANNUAL_RENEW = "EVENT_ANNUAL_RENEW"; 455 | /** 456 | * 认证过期失效通知 457 | * @var YDWXEventVerify_expired 458 | */ 459 | const EVENT_VERIFY_EXPIRED = "EVENT_VERIFY_EXPIRED"; 460 | 461 | /** 462 | * Wi-Fi连网成功事件 463 | * @var YDWXEventWificonnected 464 | */ 465 | const EVENT_WIFICONNECTED = "EVENT_WIFICONNECTED"; 466 | 467 | /** 468 | * 公众号对第三方平台取消授权通知 469 | * @var YDWXEventUnauthorized 470 | */ 471 | const EVENT_UNAUTHORIZED = "EVENT_UNAUTHORIZED"; 472 | 473 | /** 474 | * 公众号对第三方平台授权成功通知 475 | * @var YDWXEventAuthorized 476 | */ 477 | const EVENT_AUTHORIZED = "EVENT_AUTHORIZED"; 478 | 479 | /** 480 | * 公众号对第三方平台授权更新通知 481 | * @var YDWXEventUpdateauthorized 482 | */ 483 | const EVENT_UPDATEAUTHORIZED = "EVENT_UPDATEAUTHORIZED"; 484 | 485 | private static $listeners = array (); 486 | /** 487 | * 增加hook 488 | */ 489 | public static function add_hook($event, $func_name, $object = null) { 490 | self::$listeners [$event] [] = array ( 491 | "function" => $func_name, 492 | "object" => $object 493 | ); 494 | } 495 | /** 496 | * 如果没有hook注册,则返回null,如果有hook注册,则返回hook处理后的data,注意每个hook的处理将会进入下一个hook中 497 | * 498 | * @param unknown $filter_name 499 | * @param array $data 500 | * @return NULL|mixed 501 | */ 502 | public static function do_hook($filter_name, $data=array()) { 503 | if (! self::has_hook ( $filter_name )) 504 | return null; 505 | foreach ( self::$listeners [$filter_name] as $listeners ) { 506 | if (is_object ( $listeners ['object'] )) { 507 | $data = call_user_func ( array($listeners ['object'], $listeners ['function']), $data); 508 | } else { 509 | $data = call_user_func ( $listeners ['function'], $data ); 510 | } 511 | } 512 | return $data; 513 | } 514 | 515 | public static function has_hook($filter_name) { 516 | return @self::$listeners [$filter_name]; 517 | } 518 | 519 | public static function allhooks(){ 520 | return self::$listeners; 521 | } 522 | 523 | public static function include_files($dir){ 524 | if( ! file_exists($dir) )return; 525 | foreach(glob($dir."/*") as $file){ 526 | if (is_dir($file)) { 527 | self::include_hooks($file); 528 | }else if(is_file($file)){ 529 | require_once $file; 530 | } 531 | } 532 | } 533 | } 534 | ?> 535 | -------------------------------------------------------------------------------- /code/ydwx/models/base.php: -------------------------------------------------------------------------------- 1 | isPrepaySuccess() && $this->isPrepayResultSuccess(); 83 | } 84 | 85 | protected function isPrepaySuccess(){ 86 | return !$this->return_code || strcasecmp($this->return_code, "success")==0; 87 | } 88 | 89 | protected function isPrepayResultSuccess(){ 90 | return !$this->result_code || strcasecmp($this->result_code, "success")==0; 91 | } 92 | public function build($msg){ 93 | $arr = simplexml_load_string($msg, 'SimpleXMLElement', LIBXML_NOCDATA); 94 | foreach ((array)$arr as $name=>$value){ 95 | $this->$name = $value; 96 | } 97 | if( ! $this->isPrepaySuccess() && $this->return_code){ 98 | $this->errcode = -1; 99 | $this->errmsg = $this->return_msg; 100 | } 101 | if( ! $this->isPrepayResultSuccess() && $this->result_code){ 102 | $this->errcode = -1; 103 | $this->errmsg .= $this->err_code_des; 104 | } 105 | } 106 | } 107 | 108 | /** 109 | * 通过code获取access token 响应 110 | * @author ydhlleeboo 111 | * 112 | */ 113 | class YDWXGetAccessTokenResponse extends YDWXResponse{ 114 | public $access_token; 115 | public $expires_in; 116 | public $refresh_token; 117 | public $openid; 118 | public $scope; 119 | public $unionid; 120 | } -------------------------------------------------------------------------------- /code/ydwx/models/meida.php: -------------------------------------------------------------------------------- 1 | categories; 88 | $photos = array(); 89 | 90 | foreach ((array)$this->photo_list as $photo){ 91 | $photos[] = array("photo_url"=>$photo); 92 | } 93 | 94 | $args['photo_list'] = $photos; 95 | $array['business']['base_info'] = $args; 96 | return $array; 97 | } 98 | } 99 | 100 | /** 101 | * 查询poi结果 102 | * @author leeboo 103 | * 104 | */ 105 | class YDWXPoiGetResponse extends YDWXResponse{ 106 | /** 107 | * 108 | * @var YDWXPoiAddRequest 109 | */ 110 | public $poi; 111 | /** 112 | * 门店是否可用状态。1 表示系统错误、2 表示审核中、3 审核通过、4 审核驳回。当该字段为1、2、4 状态时,poi_id 为空 113 | * @var unknown 114 | */ 115 | public $available_state; 116 | /** 117 | * 扩展字段是否正在更新中。1 表示扩展字段正在更新中,尚未生效,不允许再次更新; 0 表示扩展字段没有在更新中或更新已生效,可以再次更新 118 | * @var unknown 119 | */ 120 | public $update_status; 121 | 122 | public function build($msg){ 123 | parent::build($msg); 124 | $this->poi = new YDWXPoiAddRequest(); 125 | $this->available_state = $this->business['base_info']['available_state']; 126 | $this->update_status = $this->business['base_info']['update_status']; 127 | foreach ($this->business['base_info'] as $name=>$value){ 128 | $this->poi->$name = $value; 129 | } 130 | 131 | } 132 | } 133 | /** 134 | * 查询poi列表结果集 135 | * @author leeboo 136 | * 137 | */ 138 | class YDWXPoiGetListResponse extends YDWXResponse{ 139 | /** 140 | * 门店总数量 141 | */ 142 | public $total_count; 143 | /** 144 | * @var multitype::YDWXPoiGetResponse 145 | */ 146 | public $pois; 147 | 148 | public function build($msg){ 149 | parent::build($msg); 150 | foreach ($this->business_list as $list){ 151 | $poi = new YDWXPoiGetResponse(); 152 | $poi->available_state = $list['base_info']['available_state']; 153 | $poi->update_status = $list['base_info']['update_status']; 154 | $poi->poi = new YDWXPoiAddRequest(); 155 | foreach ($list['base_info'] as $name=>$value){ 156 | $poi->poi->$name = $value; 157 | } 158 | $this->pois[] = $poi; 159 | } 160 | } 161 | } -------------------------------------------------------------------------------- /code/ydwx/models/qy-user.php: -------------------------------------------------------------------------------- 1 | | 142 | * @var string 143 | */ 144 | public $name; 145 | 146 | /** 147 | * 父部门id 148 | * @var unknown 149 | */ 150 | public $parentid; 151 | 152 | /** 153 | * 在父部门中的次序值。order值大的排序靠前。有效的值范围是[0, 2^32) 154 | * @var unknown 155 | */ 156 | public $order; 157 | 158 | /** 159 | * 部门id,整型。指定时必须大于1,否则自动生成 160 | * @var unknown 161 | */ 162 | public $id; 163 | 164 | public function valid(){ 165 | 166 | } 167 | } -------------------------------------------------------------------------------- /code/ydwx/models/user.php: -------------------------------------------------------------------------------- 1 | errmsg = $msg."($errcode)"; 92 | $fail->errcode = $errcode; 93 | return $fail; 94 | } 95 | } 96 | 97 | 98 | /** 99 | * 公众号授权给第三方平台的信息 100 | * @author leeboo 101 | * 102 | */ 103 | class YDWXAgentAuthInfo extends YDWXResponse{ 104 | /** 105 | * 授权方appid 106 | */ 107 | public $authorizer_appid; 108 | /** 109 | * 授权方令牌(在授权的公众号具备API权限时,才有此返回值) 110 | */ 111 | public $authorizer_access_token; 112 | /** 113 | * 有效期(在授权的公众号具备API权限时,才有此返回值) 114 | */ 115 | public $expires_in; 116 | /** 117 | * 刷新令牌(在授权的公众号具备API权限时,才有此返回值),刷新令牌主要用于公众号第三方平台获取和刷新已授权用户的access_token,只会在授权时刻提供,请妥善保存。 一旦丢失,只能让用户重新授权,才能再次拿到新的刷新令牌 118 | */ 119 | public $authorizer_refresh_token; 120 | /** 121 | * 公众号授权给开发者的权限集列表(请注意,当出现用户已经将消息与菜单权限集授权给了某个第三方, 122 | * 再授权给另一个第三方时,由于该权限集是互斥的,后一个第三方的授权将去除此权限集, 123 | * 开发者可以在返回的func_info信息中验证这一点,避免信息遗漏),见YDWX_FUNC_XX常量; 124 | * 请注意,该字段的返回不会考虑公众号是否具备该权限集的权限(因为可能部分具备),请根据公众号的帐号类型和认证情况,来判断公众号的接口权限。 125 | * @var array 126 | */ 127 | public $func_info; 128 | /** 129 | * 地址上的get参数 130 | * @var unknown 131 | */ 132 | public $query; 133 | 134 | public function build($msg){ 135 | parent::build($msg); 136 | $this->authorizer_appid = $this->authorization_info['authorizer_appid']; 137 | $this->authorizer_access_token = $this->authorization_info['authorizer_access_token']; 138 | $this->authorizer_refresh_token = $this->authorization_info['authorizer_refresh_token']; 139 | $this->expires_in = $this->authorization_info['expires_in']; 140 | 141 | foreach ($this->authorization_info['func_info'] as $func){ 142 | $this->func_info[$func['funcscope_category']['id']] = array( 143 | "need_confirm" =>$func['confirm_info']['need_confirm'], 144 | "already_confirm"=>$func['confirm_info']['already_confirm'] 145 | ); 146 | } 147 | } 148 | } 149 | 150 | /** 151 | * 授权给第三方平台的公众号信息 152 | * @author leeboo 153 | * 154 | */ 155 | class YDWXAgentAuthUser extends YDWXResponse{ 156 | /** 157 | * 授权方昵称 158 | */ 159 | public $nick_name; 160 | /** 161 | * 授权方头像 162 | */ 163 | public $head_img; 164 | /** 165 | * 授权方公众号类型,0代表订阅号,1代表由历史老帐号升级后的订阅号,2代表服务号 166 | * 见YDWX_WEIXIN_ACCOUNT_TYPE_XX常量 167 | */ 168 | public $service_type_info; 169 | /** 170 | * 授权方认证类型,-1代表未认证,0代表微信认证, 171 | * 1代表新浪微博认证,2代表腾讯微博认证, 172 | * 3代表已资质认证通过但还未通过名称认证, 173 | * 4代表已资质认证通过、还未通过名称认证,但通过了新浪微博认证, 174 | * 5代表已资质认证通过、还未通过名称认证,但通过了腾讯微博认证 175 | * 见 YDWX_WEIXIN_VERIFY_TYPE_XX常量 176 | */ 177 | public $verify_type_info; 178 | /** 179 | * 授权方公众号的原始ID 180 | */ 181 | public $user_name; 182 | /** 183 | * 授权方公众号所设置的微信号,可能为空 184 | */ 185 | public $alias; 186 | /** 187 | * 二维码图片的URL,开发者最好自行也进行保存 188 | */ 189 | public $qrcode_url; 190 | /** 191 | * 授权方appid 192 | */ 193 | public $appid; 194 | public $func_info; 195 | 196 | public function build($msg){ 197 | parent::build($msg); 198 | $this->nick_name = $this->authorizer_info['nick_name']; 199 | $this->head_img = $this->authorizer_info['head_img']; 200 | $this->service_type_info = $this->authorizer_info['service_type_info']; 201 | $this->verify_type_info = $this->authorizer_info['verify_type_info']; 202 | $this->user_name = $this->authorizer_info['user_name']; 203 | $this->alias = $this->authorizer_info['alias']; 204 | 205 | $this->appid = $this->authorizer_info['appid']; 206 | foreach ($this->authorizer_info['func_info'] as $func){ 207 | foreach ($this->authorizer_info['func_info'] as $func){ 208 | $this->func_info[] = $func['funcscope_category']['id']; 209 | } 210 | } 211 | } 212 | } -------------------------------------------------------------------------------- /code/ydwx/packet.php: -------------------------------------------------------------------------------- 1 | $lottery_id, 16 | "noncestr" => $noncestr, 17 | "openid" => $openid 18 | ); 19 | ksort($array); 20 | $sign = strtoupper(md5(urldecode(http_build_query($array))."&key=".$key)); 21 | echo json_encode(ydwx_success(array( 22 | "noncestr" => $noncestr, 23 | "openid" => $openid, 24 | "sign" => $sign) 25 | )); 26 | ?> -------------------------------------------------------------------------------- /code/ydwx/pay-notify.php: -------------------------------------------------------------------------------- 1 | isSuccess()){ 15 | if($msg->product_id){ 16 | $PayingMsg = new YDWXPayingNotifyResponse($data); 17 | $result = new YDWXPayNotifyRequest(); 18 | YDWXHook::do_hook(YDWXHook::YDWX_LOG, "QRCODE_PAY_NOTIFY_SUCCESS"); 19 | try{ 20 | $arg = YDWXHook::do_hook(YDWXHook::QRCODE_PAY_NOTIFY_SUCCESS, $PayingMsg); 21 | $arg->openid = $PayingMsg->openid; 22 | $order = ydwx_pay_unifiedorder($arg); 23 | $result_code = "SUCCESS"; 24 | $err_code_des = "OK"; 25 | $result->prepay_id = $order->prepay_id; 26 | }catch(YDWXException $e){ 27 | $result_code = "FAIL"; 28 | $err_code_des = $e->getMessage(); 29 | } 30 | 31 | // TODO 这里要考虑YDWX_WEIXIN_MCH_KEY的来源(企业号,第三方平台等) 32 | 33 | $result->appid = $PayingMsg->appid; 34 | $result->mch_id = $PayingMsg->mch_id; 35 | $result->mch_key = YDWX_WEIXIN_MCH_KEY; 36 | $result->return_code = $result_code; 37 | $result->result_code = $result_code; 38 | $result->err_code_des = $err_code_des; 39 | 40 | $result->sign(); 41 | YDWXHook::do_hook(YDWXHook::YDWX_LOG, $result->toXMLString()); 42 | echo $result->toXMLString(); 43 | }else{ 44 | if(YDWXHook::do_hook(YDWXHook::PAY_NOTIFY_SUCCESS, $msg)){ 45 | ob_clean(); 46 | echo ""; 47 | } 48 | } 49 | die; 50 | }else{ 51 | YDWXHook::do_hook(YDWXHook::PAY_NOTIFY_ERROR, $msg); 52 | } -------------------------------------------------------------------------------- /code/ydwx/pay.php: -------------------------------------------------------------------------------- 1 | openid = $_POST['openid']; 10 | $arg->out_trade_no = $_POST['trace_no']; 11 | $arg->total_fee = intval($_POST['price']*100); 12 | $arg->attach = $_POST['attach']; 13 | $arg->body = $_POST['pay_desc']; 14 | 15 | try{ 16 | $mchkey = $appid ? YDWXHook::do_hook(YDWXHook::GET_HOST_MCH_KEY, $appid) : YDWX_WEIXIN_MCH_KEY; 17 | $mchid = $appid ? YDWXHook::do_hook(YDWXHook::GET_HOST_MCH_ID, $appid) : YDWX_WEIXIN_MCH_ID; 18 | if( ! $appid){ 19 | $appid = YDWX_WEIXIN_APP_ID; 20 | } 21 | 22 | $arg->appid = $appid; 23 | $arg->mch_id = $mchid; 24 | $arg->mch_key = $mchkey; 25 | 26 | 27 | $msg = ydwx_pay_unifiedorder($arg); 28 | $str = "appId=".$appid."&nonceStr=".$_POST['noncestr'] 29 | ."&package=prepay_id=".$msg->prepay_id."&signType=MD5&timeStamp=".$_POST['timestamp']; 30 | $sign = strtoupper(md5($str."&key=".$mchkey)); 31 | 32 | echo json_encode(ydwx_success(array( 33 | "prepay_id" => $msg->prepay_id, 34 | "paySign" => $sign, 35 | "trade_no" => $_POST['trace_no'] 36 | ))); 37 | die; 38 | }catch (YDWXException $e){ 39 | echo json_encode(ydwx_error($e->getMessage())); 40 | die; 41 | } -------------------------------------------------------------------------------- /code/ydwx/refresh-agent.php: -------------------------------------------------------------------------------- 1 | getMessage(); 27 | } 28 | 29 | 30 | die("success"); -------------------------------------------------------------------------------- /code/ydwx/refresh-crop.php: -------------------------------------------------------------------------------- 1 | access_token); 30 | 31 | YDWXHook::do_hook(YDWXHook::REFRESH_QY_JSAPI_TICKET, $ticket); 32 | 33 | //刷新微信card api ticket 34 | $ticket = ydwx_refresh_card_jsapi_ticket($accessToken->access_token); 35 | YDWXHook::do_hook(YDWXHook::REFRESH_QY_CARD_JSAPI_TICKET, $ticket); 36 | }catch (\Exception $e){ 37 | echo " accessToken: ".$e->getMessage()."
    "; 38 | } 39 | 40 | die("success"); -------------------------------------------------------------------------------- /code/ydwx/refresh.php: -------------------------------------------------------------------------------- 1 | access_token); 24 | 25 | YDWXHook::do_hook(YDWXHook::REFRESH_JSAPI_TICKET, $ticket); 26 | 27 | //刷新微信card api ticket 28 | $ticket = ydwx_refresh_card_jsapi_ticket($accessToken->access_token); 29 | YDWXHook::do_hook(YDWXHook::REFRESH_CARD_JSAPI_TICKET, $ticket); 30 | }catch (\Exception $e){ 31 | echo " accessToken: ".$e->getMessage()."
    "; 32 | } 33 | 34 | die("success"); -------------------------------------------------------------------------------- /code/ydwx/test.php: -------------------------------------------------------------------------------- 1 | name = "我的标签"; 11 | $menu1->type = YDWXMenu::TYPE_VIEW; 12 | $menu1->url = SITE_URI."app/myqrcodes.php"; 13 | 14 | $menu2 = new YDWXMenu(); 15 | $menu2->name = "购买标签"; 16 | $menu2->type = YDWXMenu::TYPE_VIEW; 17 | $menu2->url = SITE_URI."app/pay.php"; 18 | 19 | $menu3 = new YDWXMenu(); 20 | $menu3->name = "扫描标签"; 21 | $menu3->type = YDWXMenu::TYPE_SCANCODE_PUSH; 22 | $menu3->key = "scan_qrcode"; 23 | 24 | $access_token = lookup("value", "options", "name='access_token'"); 25 | //echo "access token",$access_token,"
    "; 26 | // createMenus($access_token, array($menu1, $menu2, $menu3)); 27 | //removeMenus($access_token); 28 | echo "getmenus:
    "; 29 | print_r(getMenus($access_token)); 30 | 31 | // $gift_number = lookup("value", "options", "name='new_user_gift_number'"); 32 | // createEmptyQrcode($gift_number); 33 | ?> -------------------------------------------------------------------------------- /code/ydwx/webauth.php: -------------------------------------------------------------------------------- 1 | get("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" 31 | .YDWX_WEIXIN_WEB_APP_ID."&secret=".YDWX_WEIXIN_WEB_APP_SECRET."&code=".$_GET['code']."&grant_type=authorization_code"), true); 32 | 33 | if( !@$info['openid']){ 34 | YDWXHook::do_hook(YDWXHook::AUTH_FAIL, YDWXAuthFailResponse::errMsg($info['errmsg'], $info['errcode'])); 35 | die; 36 | } 37 | $user = ydwx_sns_userinfo($info['access_token'], $info['openid']); 38 | $user->state = $_GET['state']; 39 | YDWXHook::do_hook(YDWXHook::AUTH_WEB_SUCCESS, $user); -------------------------------------------------------------------------------- /code/ydwx/yaotv_auth.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /code/ydwx/yaotv_draw.php: -------------------------------------------------------------------------------- 1 | get("http://yao.qq.com/lottery/drawlottery?".http_build_query($vars)."&sign={$sign}"); 43 | $rst = new YDWXYaoTvDrawResult($info); 44 | return json_encode($rst); 45 | -------------------------------------------------------------------------------- /code/ydwx/yaotv_draw_result.php: -------------------------------------------------------------------------------- 1 | get("http://yao.qq.com/lottery/getuserprizeresult?lottery_id={$lottery_id}"); 15 | $rst = new YDWXYaoTvDrawResult($info); 16 | return json_encode($rst); 17 | -------------------------------------------------------------------------------- /code/ydwx/yaotv_hb.php: -------------------------------------------------------------------------------- 1 | $lottery_id, 17 | "noncestr" => $noncestr, 18 | "userid" => $openid 19 | ); 20 | if($captcha){ 21 | $array['captcha'] = $captcha; 22 | } 23 | ksort($array); 24 | $sign = strtoupper(md5(urldecode(http_build_query($array))."&key=".$key)); 25 | echo json_encode(ydwx_success(array( 26 | "noncestr" => $noncestr, 27 | "openid" => $openid, 28 | "captcha" => $captcha, 29 | "sign" => $sign) 30 | )); 31 | ?> -------------------------------------------------------------------------------- /code/ydwxhooks/agent.php: -------------------------------------------------------------------------------- 1 | errmsg));die; 12 | }); 13 | 14 | YDWXHook::add_hook(YDWXHook::AUTH_INAPP_SUCCESS, function(YDWXOAuthUser $userinfo){ 15 | //微信app内登录成功做什么,如判断该微信用户是否在系统中存在,不存在建立用户数据,存在标记为登录状态,并 16 | //导航到登录后看到的页面 17 | 18 | }); 19 | 20 | YDWXHook::add_hook(YDWXHook::AUTH_WEB_SUCCESS, function(YDWXOAuthUser $wxuser){ 21 | 22 | }); 23 | 24 | //公众号授权成功 25 | YDWXHook::add_hook(YDWXHook::AUTH_AGENT_SUCCESS, function(array $info){ 26 | 27 | }); 28 | 29 | 30 | 31 | YDWXHook::add_hook(YDWXHook::AUTH_CROP_SUCCESS, function(YDWXOAuthCropUser $info){ 32 | //微信企业号app登录成功做什么,如判断该微信用户是否在系统中存在,不存在建立用户数据,存在标记为登录状态,并 33 | //导航到登录后看到的页面 34 | }); -------------------------------------------------------------------------------- /code/ydwxhooks/basic.php: -------------------------------------------------------------------------------- 1 |