request->get(); $valid = \Yii::$app->services->validate->validate($data, [ [['signature', 'timestamp', 'nonce', 'echostr'], 'required'], ]); \Yii::error(__METHOD__ . '->params: ' . var_export($data, true)); if ($valid === false) return false; $signature = $data["signature"]; $timestamp = $data["timestamp"]; $nonce = $data["nonce"]; $mall_ids = Mall::getEnableMallIds(); foreach ($mall_ids as $mall_id) { $config = \Yii::$app->services->setting->addons->get($mall_id, WechatVideoShopEnums::ADDONS_NAME, 'basic'); if (empty($config['is_enable'])) continue; $shop_list = WechatVideoShop::lists(['where' => [['mall_id' => $mall_id], ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]]]); if (empty($shop_list)) continue; foreach ($shop_list as $val) { if(empty($val['wechat_token'])) continue; $token = $val['wechat_token']; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr, SORT_STRING); $tmpStr = implode($tmpArr); $tmpStr = sha1($tmpStr); if ($tmpStr == $signature) { // 执行验证 \Yii::$app->services->rabbitMq->push(RabbitMqEnum::EXCHANGE_TASK, RabbitMqEnum::TASK_QUEUE, ['mall_id' => $mall_id], ShopService::class, 'auth'); return $data['echostr']; } } } return false; } public function actionCallback() { try { // 校验token if (\Yii::$app->request->isGet && !empty(\Yii::$app->request->get('echostr'))) { return $this->actionIndex(); } $params = $this->request->get(); $encryptData = $this->request->post(); \Yii::error(__METHOD__ . '->params: ' . var_export($params, true) . '->encryptData: ' . var_export($encryptData, true)); $save_data['req'] = $params ?? []; $save_data['org_post'] = !empty($encryptData) ? var_export($encryptData, true) : ''; // 解密? $mall_ids = Mall::getEnableMallIds(); $decryptData = null; /** @var int|null $current_mall_id */ $current_mall_id = null; /** @var int|null $current_shop_id */ $current_shop_id = null; foreach ($mall_ids as $mall_id) { $config = \Yii::$app->services->setting->addons->get($mall_id, WechatVideoShopEnums::ADDONS_NAME, 'basic'); if (empty($config['is_enable'])) continue; $shop_list = WechatVideoShop::lists(['where' => [['mall_id' => $mall_id], ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]]]); if (empty($shop_list)) continue; foreach ($shop_list as $val) { if (empty($val['wechat_token']) || empty($val['wechat_secret']) || empty($val['wechat_aes_key'])) continue; try { $crypto = new Crypto($val['wechat_token'], $val['wechat_aes_key']); $ret = $crypto->de($encryptData['Encrypt'], $params['msg_signature'], $params['nonce'], $params['timestamp']); if ($ret[0] != StatusEnum::DISABLED) throw new \Exception("解密失败"); if ($ret[1]['wechat_appid'] != $val['wechat_appid']) throw new \Exception("不属于同一个应用"); // 不属于同一个应用 $current_mall_id = $mall_id; $current_shop_id = $val['id']; $decryptData = $ret[1]; break; } catch (\Exception $e) { // 有可能是解密失败的 这里不需要管 } } } // 解密成功 - 不一定要解密 if (!empty($decryptData)) { $decryptData['local_shop_id'] = $current_shop_id; $save_data['post'] = $decryptData; $save_data['mall_id'] = $current_mall_id; $callback = new WeChatCallbackLogic($current_mall_id, $current_shop_id, 0, $decryptData); $method = $decryptData['Event'] ?? 'call'; if (method_exists($callback, $method)) { $callback->{$method}([]); } else { $callback->call([]); // $method = 'call'; } // 投递 // \Yii::$app->services->rabbitMq->delay(600, ['mall_id' => $current_mall_id, 'shop_id' => $current_shop_id, 'data' => $decryptData], // WeChatCallbackLogic::class, $method); } else { $save_data['exception'] = [ 'msg' => '解密失败' ]; } } catch (\Exception $e) { $save_data['exception'] = [ 'file' => $e->getFile(), 'code' => $e->getCode(), 'line' => $e->getLine(), 'msg' => $e->getMessage(), ]; } if (empty($save_data['post'])) $save_data['post'] = []; if (empty($save_data['exception'])) $save_data['exception'] = []; // 记录事件 $eventModel = new WechatVideoShopEvents(); if ($eventModel->load($save_data, '')) { if ($eventModel->save() && !empty($eventModel->getErrorMessage())) { \Yii::error(__METHOD__ . " event model error: {$eventModel->getErrorMessage()}"); } } else { \Yii::error(__METHOD__ . " event model error: {$eventModel->getErrorMessage()}"); } return empty($eventModel['exception']) ? 'success' : 'fail'; } }