TencentMarket.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2017 https://www.sapixx.com All rights reserved.
  4. * @license Licensed (http://www.apache.org/licenses/LICENSE-2.0).
  5. * @author pillar<ltmn@qq.com>
  6. * 腾讯云市场
  7. */
  8. namespace app\system\controller\event;
  9. use think\Controller;
  10. use think\helper\Time;
  11. use app\common\model\SystemApis;
  12. use app\common\model\SystemWeb;
  13. use app\common\model\SystemMember;
  14. use app\common\model\SystemMemberMiniapp;
  15. use app\common\model\SystemMemberMiniappOrder;
  16. use app\common\model\SystemMiniapp;
  17. use app\common\model\SystemMemberCloud;
  18. use app\common\model\SystemMemberMiniappCloud;
  19. use app\common\model\SystemMemberBankBill;
  20. use app\common\model\SystemMemberCloudProduct;
  21. use think\facade\Log;
  22. class TencentMarket extends Controller{
  23. public function auth(){
  24. $param = $this->request->param();
  25. if(empty($param['accountId']) || empty($param['action'])){
  26. return json(['success' => "false",'msg' => 'accountId or action not is null']);
  27. }
  28. switch ($param['action']){
  29. case 'verifyInterface': //身份校验接口
  30. if(!$param['signature'] || !$param['timestamp'] || !$param['eventId']){
  31. return json(['success' => "false",'msg' => 'signature not is null']);
  32. }
  33. $config = SystemApis::config('wechatcloud');
  34. if(empty($config)){
  35. return json(['success' => "false",'msg' => 'config not is null']);
  36. }
  37. $token = $config['token'];
  38. $check = self::checkSignature($param['signature'], $token, $param['timestamp'], $param['eventId']);//这里使用的是腾讯云提供的签名校验函数
  39. if (!$check) {
  40. return json(['success' => "false",'msg' => 'Verification failed']);
  41. } else {
  42. return json(['echoback' => $param['echoback']]);
  43. }
  44. break;
  45. case 'createInstance': //购买应用
  46. $memberCloudProduct = SystemMemberCloudProduct::where(['product_id' => $param['productId']])->find();
  47. if(empty($memberCloudProduct)){
  48. return json(['success' => "false"]);
  49. }
  50. $miniapp_id = $memberCloudProduct->miniapp_id;
  51. $orderId = $param['orderId'];
  52. $accountId = $param['accountId'];
  53. //$requestId = $param['requestId'];
  54. $openId = $param['openId'];
  55. $productInfo = $param['productInfo'];
  56. //创建云市场用户
  57. $info = SystemMemberCloud::where(['openId' => $openId])->find();
  58. if(empty($info)){
  59. $data['username'] = '腾讯云'.getcode(5);
  60. $data['password'] = password_hash(md5($openId),PASSWORD_DEFAULT);
  61. $data['safe_password'] = password_hash(md5('123456'),PASSWORD_DEFAULT);
  62. $data['login_time'] = time();
  63. $data['update_time'] = time();
  64. $data['create_time'] = time();
  65. $data['login_ip'] = request()->ip();
  66. $last_id = SystemMember::insertGetId($data);
  67. SystemMemberCloud::create(['member_id'=>$last_id,'openId' => $openId,'create_time'=> time()]);
  68. }else{
  69. $last_id = $info->member_id;
  70. }
  71. $miniapp = SystemMiniapp::where(['id' => $miniapp_id,'is_lock' => 0])->field('id,sell_price,template_id,title')->find();
  72. if(empty($miniapp)){
  73. return json(['success' => "false",'msg' => 'product is miss']);
  74. }
  75. //新增购买列表
  76. $order['member_id'] = $last_id;
  77. $order['miniapp_id'] = $miniapp_id;
  78. $order['update_var'] = (int)$miniapp->template_id;
  79. $order['start_time'] = time();
  80. if($productInfo['isTrial'] == 'true'){
  81. $order['end_time'] = Time::daysAfter(7); //试用版
  82. }else{
  83. $order['end_time'] = self::formatDate($productInfo['timeUnit'],$productInfo['timeSpan']); //正式版
  84. }
  85. $member_order_id = SystemMemberMiniappOrder::insertGetId($order);
  86. $member_miniapp_id = SystemMemberMiniapp::insertGetId([
  87. 'miniapp_order_id' => $member_order_id,
  88. 'member_id' => $last_id,
  89. 'miniapp_id' => $miniapp_id,
  90. 'appname' => $miniapp->title,
  91. 'create_time' => time()
  92. ]);
  93. SystemMemberMiniapp::where(['id' => $member_miniapp_id])->update(['service_id' => uuid(3,true,$member_miniapp_id)]); //更新服务ID
  94. self::createBill($last_id,$miniapp);
  95. //同时我们需要向腾讯云返回一个免登后台地址,在这里我选用signid作为免登的token
  96. $signid = create_code(time());
  97. //创建云产品
  98. SystemMemberMiniappCloud::create([
  99. 'member_id' => $last_id,
  100. 'signId' => $signid,
  101. 'orderId' => $orderId,
  102. 'accountId' => $accountId,
  103. 'openId' => $openId,
  104. 'productId' => $miniapp_id,
  105. // 'requestId' => $requestId,
  106. 'productInfo' => json_encode($productInfo),
  107. 'create_time' => time(),
  108. 'member_order_id' => $member_order_id,
  109. 'member_miniapp_id' => $member_miniapp_id
  110. ]);
  111. //这里构造个腾讯云接口规定的返回参数,返回
  112. $SystemWeb = SystemWeb::config();
  113. $post_data = [
  114. 'signId'=> $signid,//返回给腾讯云实例标识,之后的接口腾讯云会带着这个参数
  115. 'appInfo'=>[
  116. 'website'=> 'https://'.$SystemWeb->url, //网站地址
  117. 'authUrl'=> url('system/passport.login/cloud',['token' => $signid],'html',true) //后台免登地址
  118. ],
  119. ];
  120. return json($post_data);
  121. break;
  122. case 'renewInstance': //实例续费通知接口
  123. $signid = $param['signId'];
  124. $instanceExpireTime = $param['instanceExpireTime'];//这个参数是datetime格式的实例到期日期,我们通过此参数修改数据库内的商家到期时间
  125. $userCloud = SystemMemberMiniappCloud::where(['signId' => $signid])->find();
  126. if($userCloud){
  127. SystemMemberMiniappOrder::where(['id' => $userCloud->member_order_id])->update(['end_time' => strtotime($instanceExpireTime)]);
  128. self::createBill($userCloud->member_id,SystemMiniapp::where(['id' => $userCloud->productId])->find());
  129. return json(['success' => "true"]);
  130. }else{
  131. return json(['success' => "false"]);
  132. }
  133. break;
  134. case 'modifyInstance': //实例配置变更通知接口 这个接口是在商家试用转正式版支付完成时调用的
  135. $signid = $param['signId'];
  136. $instanceExpireTime = $param['instanceExpireTime'];
  137. $userCloud = SystemMemberMiniappCloud::where(['signId' => $signid])->find();
  138. if($userCloud){
  139. SystemMemberMiniappOrder::where(['id' => $userCloud->member_order_id])->update(['end_time' => strtotime($instanceExpireTime)]);
  140. //创建帐单
  141. self::createBill($userCloud->member_id,SystemMiniapp::where(['id' => $userCloud->productId])->find());
  142. return json(['success' => "true"]);
  143. }else{
  144. return json(['success' => "false"]);
  145. }
  146. break;
  147. case 'expireInstance': //实例过期通知接口
  148. return json(['success' => "true"]);
  149. break;
  150. case 'destroyInstance': //实例销毁通知接口
  151. $signid = $param['signId'];
  152. $userCloud = SystemMemberMiniappCloud::where(['signId' => $signid])->find();
  153. if($userCloud){
  154. SystemMemberMiniapp::where(['id' => $userCloud->member_miniapp_id])->update(['is_lock' => 1]);
  155. return json(['success' => "true"]);
  156. }else{
  157. return json(['success' => "false"]);
  158. }
  159. break;
  160. }
  161. }
  162. /**
  163. * 腾讯云签名校验
  164. * @param $signature
  165. * @param $token
  166. * @param $timestamp
  167. * @param $eventId
  168. * @return bool
  169. */
  170. protected function checkSignature($signature, $token, $timestamp, $eventId){
  171. $currentTimestamp = time();
  172. if ($currentTimestamp - $timestamp > 30) {
  173. return false;
  174. }
  175. $timestamp = (string)$timestamp;
  176. $eventId = (string)$eventId;
  177. $params = array($token, $timestamp, $eventId);
  178. sort($params, SORT_STRING);
  179. $str = implode('', $params);
  180. $requestSignature = hash('sha256', $str);
  181. return $signature === $requestSignature;
  182. }
  183. /**
  184. * @param $timeUnit
  185. * @param $timeSpan
  186. * @return false|string
  187. * 格式化时间
  188. */
  189. protected function formatDate($timeUnit,$timeSpan){
  190. $maturity_date = 0;
  191. switch ($timeUnit){
  192. case 'y':
  193. //购买年
  194. $maturity_date = strtotime("+".$timeSpan." year");
  195. break;
  196. case 'm':
  197. //购买月
  198. $maturity_date = strtotime("+".$timeSpan." month");
  199. break;
  200. case 'd':
  201. //购买日
  202. $maturity_date = strtotime("+".$timeSpan." day");
  203. break;
  204. }
  205. return $maturity_date;
  206. }
  207. /**
  208. * 创建账单
  209. * @param [type] $last_id
  210. * @param [type] $miniapp
  211. * @return void
  212. */
  213. protected function createBill($last_id,$miniapp){
  214. $billData = [
  215. 'state' => 1,
  216. 'money' => 0,
  217. 'member_id' => $last_id,
  218. 'message' => '通过云市场购买应用程序' . $miniapp->title,
  219. 'update_time' => time(),
  220. ];
  221. SystemMemberBankBill::create($billData);
  222. }
  223. }