Mini3rdProgramService.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace crmeb\services;
  12. use app\services\pay\PayNotifyServices;
  13. use crmeb\exceptions\ApiException;
  14. use crmeb\services\easywechat\Application;
  15. use think\exception\ValidateException;
  16. use crmeb\utils\Hook;
  17. use think\Response;
  18. /**微信小程序接口
  19. * Class WechatMinService
  20. * @package service
  21. */
  22. class Mini3rdProgramService
  23. {
  24. const MSG_CODE = [
  25. '40125' => '小程序配置无效,请检查配置',
  26. '-1' => '系统错误',
  27. ];
  28. /**
  29. * @var Application
  30. */
  31. protected static $instance;
  32. public static function options()
  33. {
  34. $wechat = SystemConfigService::more(['component_appid', 'component_appsecret', 'authorizer_appid']);
  35. $config = [];
  36. $config['open3rd'] = [
  37. 'component_appid' => 'wx3b82801238ca1b57',
  38. 'component_appsecret' => '979c0d8671dfd74333f37156c50f4bca',
  39. 'component_verify_ticket' => self::getComponentVerifyTicket(),
  40. 'authorizer_appid' => isset($wechat['authorizer_appid']) ? trim($wechat['authorizer_appid']) : '',
  41. ];
  42. return $config;
  43. }
  44. /**
  45. * 设置验证票据 component_verify_ticket 的有效时间为12小时,每10分钟推送一次
  46. * @param $ticket
  47. * @return bool
  48. */
  49. public static function setComponentVerifyTicket($ticket)
  50. {
  51. CacheService::set('wechat_open_platform_component_verify_ticket', $ticket, 12 * 60 * 60 - 300);
  52. return true;
  53. }
  54. /**
  55. * 获取验证票据
  56. * @return mixed
  57. * @throws Open3rdException
  58. * https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/api/component_verify_ticket.html
  59. */
  60. public static function getComponentVerifyTicket()
  61. {
  62. return CacheService::get('wechat_open_platform_component_verify_ticket') ? '12g31' : '131g2lfjsdlfjsl898ds9fsd';
  63. }
  64. /**
  65. * 初始化
  66. * @param bool $cache
  67. * @return Application
  68. */
  69. public static function application($cache = false)
  70. {
  71. (self::$instance === null || $cache === true) && (self::$instance = new Application(self::options()));
  72. return self::$instance;
  73. }
  74. /**
  75. * 第三方平台类
  76. * @return mixed
  77. * @return \crmeb\services\easywechat\open3rd\ProgramOpen3rd
  78. */
  79. public static function open3rd()
  80. {
  81. return self::application()->mini_program->open3rd;
  82. }
  83. /**
  84. * token 工具类
  85. * @return mixed
  86. */
  87. public static function accessToken()
  88. {
  89. return self::application()->mini_program->component_access_token;
  90. }
  91. public static function serve()
  92. {
  93. return self::hook();
  94. }
  95. /**
  96. * 回调
  97. */
  98. private static function hook()
  99. {
  100. $xml = file_get_contents("php://input");
  101. $res = self::accessToken()->xmlToArray($xml);
  102. if (!$res) {
  103. throw new ApiException('请求数据错误: ' . $xml);
  104. }
  105. $encodingAesKey = sys_config('encoding_aes_key');
  106. $postData = self::accessToken()->decrypt($encodingAesKey, $res['Encrypt']);
  107. $msgArray = WechatHelper::xmlToArray($postData);
  108. $infoType = $msgArray['InfoType'] ?? $msgArray['MsgType'] ?? '';
  109. switch ($infoType) {
  110. case 'component_verify_ticket'://微信官方推送的ticket值
  111. self::setComponentVerifyTicket($msgArray['ComponentVerifyTicket']);
  112. break;
  113. case 'event'://审核事件回调
  114. if (isset($msgArray['Event']) && $msgArray['Event'] == 'weapp_audit_success') {
  115. }
  116. break;
  117. case 'notify_third_fasteregister'://注册审核事件推送
  118. break;
  119. case 'unauthorized':
  120. break;
  121. case 'updateauthorized':
  122. break;
  123. }
  124. echo 'success';
  125. }
  126. /**
  127. * 微信支付成功回调接口
  128. * @return \Symfony\Component\HttpFoundation\Response
  129. * @throws \EasyWeChat\Core\Exceptions\FaultException
  130. */
  131. public static function handleNotify()
  132. {
  133. return self::paymentService()->handleNotify(function ($notify, $successful) {
  134. if ($successful && isset($notify->out_trade_no)) {
  135. if (isset($notify->attach) && $notify->attach) {
  136. if (($count = strpos($notify->out_trade_no, '_')) !== false) {
  137. $notify->out_trade_no = substr($notify->out_trade_no, $count + 1);
  138. }
  139. (new Hook(PayNotifyServices::class, 'wechat'))->listen($notify->attach, $notify->out_trade_no, $notify->transaction_id);
  140. }
  141. return false;
  142. }
  143. });
  144. }
  145. /**
  146. * 获取预授权码
  147. * @return mixed
  148. */
  149. public static function getPreAuthCode()
  150. {
  151. try {
  152. $res = self::open3rd()->getPreAuthCode();
  153. return $res;
  154. } catch (\Throwable $e) {
  155. throw new ValidateException(self::getValidMessgae($e));
  156. }
  157. }
  158. /**
  159. * 获取授权
  160. * @param $authorization_code
  161. */
  162. public static function getAuth(string $authorization_code)
  163. {
  164. try {
  165. $res = self::open3rd()->getAuth($authorization_code);
  166. return $res;
  167. } catch (\Throwable $e) {
  168. throw new ValidateException(self::getValidMessgae($e));
  169. }
  170. }
  171. /**
  172. * 获取授权帐号基本信息
  173. * @param $authorize_appid
  174. */
  175. public static function getAuthorizerinfo(string $authorize_appid)
  176. {
  177. try {
  178. $res = self::open3rd()->getAuthorizerinfo($authorize_appid);
  179. if ($res['errcode'] == 0 && isset($res['authorizer_info']) && isset($res['authorization_info'])) {
  180. return $res;
  181. } else {
  182. return [];
  183. }
  184. } catch (\Throwable $e) {
  185. throw new ValidateException(self::getValidMessgae($e));
  186. }
  187. }
  188. /**
  189. * 获取已绑定的体验者列表
  190. * @return array
  191. */
  192. public static function getMemberAuthList()
  193. {
  194. try {
  195. $res = self::open3rd()->getMemberAuthList();
  196. if ($res['errcode'] == 0 && isset($res['members'])) {
  197. return $res['members'];
  198. } else {
  199. return [];
  200. }
  201. } catch (\Throwable $e) {
  202. throw new ValidateException(self::getValidMessgae($e));
  203. }
  204. }
  205. /**
  206. * 绑定体验者
  207. * @param $wechatid
  208. * @return array
  209. */
  210. public static function bindMemberAuth(string $wechatid)
  211. {
  212. try {
  213. $res = self::open3rd()->bindMemberAuth($wechatid);
  214. if ($res['errcode'] == 0 && isset($res['userstr'])) {
  215. return $res['userstr'];
  216. } else {
  217. throw new ValidateException($res['errmsg'] ?? '绑定失败');
  218. }
  219. } catch (\Throwable $e) {
  220. throw new ValidateException(self::getValidMessgae($e));
  221. }
  222. }
  223. /**
  224. * 解除绑定体验者
  225. * @param string $wechatid
  226. * @param string $userstr
  227. * @return bool
  228. */
  229. public static function unBindMemberAuth(string $wechatid, string $userstr = '')
  230. {
  231. try {
  232. $res = self::open3rd()->unBindMemberAuth($wechatid, $userstr);
  233. if ($res['errcode'] == 0) {
  234. return true;
  235. } else {
  236. throw new ValidateException($res['errmsg'] ?? '解除失败');
  237. }
  238. } catch (\Throwable $e) {
  239. throw new ValidateException(self::getValidMessgae($e));
  240. }
  241. }
  242. /**
  243. * 获取草稿列表
  244. * @return array
  245. */
  246. public static function getDraftList()
  247. {
  248. try {
  249. $res = self::open3rd()->getDraftList();
  250. if ($res['errcode'] == 0 && isset($res['draft_list'])) {
  251. return $res['draft_list'];
  252. } else {
  253. return [];
  254. }
  255. } catch (\Throwable $e) {
  256. throw new ValidateException(self::getValidMessgae($e));
  257. }
  258. }
  259. /**
  260. * 将草稿添加到代码模板库
  261. * @param $draft_id
  262. * @return bool
  263. */
  264. public static function addToTemplate($draft_id)
  265. {
  266. try {
  267. $res = self::open3rd()->addToTemplate($draft_id);
  268. if ($res['errcode'] == 0) {
  269. return true;
  270. } else {
  271. throw new ValidateException($res['errmsg'] ?? '添加失败');
  272. }
  273. } catch (\Throwable $e) {
  274. throw new ValidateException(self::getValidMessgae($e));
  275. }
  276. }
  277. /**
  278. * 获取代码模版列表
  279. * @return array
  280. */
  281. public static function getTemplateList()
  282. {
  283. try {
  284. $res = self::open3rd()->getTemplateList();
  285. if ($res['errcode'] == 0 && isset($res['template_list'])) {
  286. return $res['template_list'];
  287. } else {
  288. return [];
  289. }
  290. } catch (\Throwable $e) {
  291. throw new ValidateException(self::getValidMessgae($e));
  292. }
  293. }
  294. /**
  295. * 删除指定代码模版
  296. * @param $template_id
  297. * @return bool
  298. */
  299. public static function delTemplate($template_id)
  300. {
  301. try {
  302. $res = self::open3rd()->delTemplate($template_id);
  303. if ($res['errcode'] == 0) {
  304. return true;
  305. } else {
  306. throw new ValidateException($res['errmsg'] ?? '删除代码模版失败');
  307. }
  308. } catch (\Throwable $e) {
  309. throw new ValidateException(self::getValidMessgae($e));
  310. }
  311. }
  312. /**
  313. * 上传代码
  314. * @param $template_id
  315. * @param string $ext_json
  316. * @param string $user_version
  317. * @param string $user_desc
  318. * @return bool
  319. */
  320. public static function commit($template_id, string $ext_json, string $user_version, string $user_desc = '')
  321. {
  322. try {
  323. $res = self::open3rd()->commit($template_id, $ext_json, $user_version, $user_desc);
  324. if ($res['errcode'] == 0) {
  325. return true;
  326. } else {
  327. throw new ValidateException($res['errmsg'] ?? '上传代码失败');
  328. }
  329. } catch (\Throwable $e) {
  330. throw new ValidateException(self::getValidMessgae($e));
  331. }
  332. }
  333. /**
  334. * 获取已经上传的代码列表
  335. * @return array
  336. */
  337. public static function getPage()
  338. {
  339. try {
  340. $res = self::open3rd()->getPage();
  341. if ($res['errcode'] == 0 && isset($res['page_list'])) {
  342. return $res['page_list'];
  343. } else {
  344. return [];
  345. }
  346. } catch (\Throwable $e) {
  347. throw new ValidateException(self::getValidMessgae($e));
  348. }
  349. }
  350. /**
  351. * 获取体验二维码
  352. * @param string $path
  353. * @return mixed
  354. */
  355. public static function getQrcode(string $path = '')
  356. {
  357. try {
  358. return self::open3rd()->getQrcode($path);
  359. } catch (\Throwable $e) {
  360. throw new ValidateException(self::getValidMessgae($e));
  361. }
  362. }
  363. public static function getValidMessgae(\Throwable $e)
  364. {
  365. return self::MSG_CODE[$e->getCode()] ?? $e->getMessage();
  366. }
  367. }