appKey = 1594082399; $this->appSecret = '9025c4f5ad93e8e08e947f02d0cde652'; } else { $this->appKey = 1741530942; $this->appSecret = '07b3f83d19a4a9f89322976c936faf92'; } // 根据环境设置沙箱标志 $this->isSandbox = !$isProduction; } /** * 设置重定向URI * 需要进行URLEncode编码 * * @param string $redirectUri 重定向地址 */ public function setRedirectUri($redirectUri) { $this->redirectUri = $redirectUri; return $this; } /** * 生成授权URL * 用户需要通过浏览器访问此URL进行授权 * * @param string $redirectUri 重定向地址(回调地址) * @return string 授权URL */ public function generateAuthUrl($mainId) { $params = [ 'dev_id' => $this->appKey, 'out_shop_id' => $mainId, ]; // 构建URL $queryString = http_build_query($params); return self::AUTHORIZE_URL . '?' . $queryString; } /** * 获取AccessToken * 使用授权码换取令牌 * * 文档:/oauth/token (GET请求) * 入参:grant_type, client_id, code, isSandbox * 出参:access_token, refresh_token, expires_in * * @param string $code 授权码(来自授权页面重定向) * @return array 返回格式:['success' => true/false, 'access_token' => '', 'refresh_token' => '', 'expires_in' => 0, 'error' => ''] */ public function getAccessToken($code) { $params = [ 'grant_type' => '', 'client_id' => $this->appKey, 'code' => $code, 'isSandbox' => $this->isSandbox ? 'true' : 'false', ]; $response = HttpClient::get(self::TOKEN_URL, $params); Yii::info("[HuoLalaAuthGetToken] Response: " . json_encode($response)); return $this->parseResponse($response); } /** * 刷新AccessToken * 使用刷新令牌获取新的AccessToken * * 文档:/oauth/token (GET请求) * 入参:grant_type, client_id, refresh_token, isSandbox * 出参:access_token, refresh_token, expires_in * * @param string $refreshToken 刷新令牌 * @return array 返回格式:['success' => true/false, 'access_token' => '', 'refresh_token' => '', 'expires_in' => 0, 'error' => ''] */ public function refreshAccessToken($refreshToken) { $params = [ 'grant_type' => '', 'client_id' => $this->appKey, 'refresh_token' => $refreshToken, 'isSandbox' => $this->isSandbox ? 'true' : 'false', ]; $response = HttpClient::get(self::TOKEN_URL, $params); Yii::info("[HuoLalaAuthRefreshToken] Response: " . json_encode($response)); return $this->parseResponse($response); } /** * 解析API响应 * * 货拉拉 API 返回格式: * { * "ret": 0, * "msg": "success", * "data": { * "auth_mobile": "17168665598", * "access_token": "a3207b6b5ad04249ad1dbf6a9824dbea", * "refresh_token": "4ccbbab0e9e443159c518d1d10741ad", * "auth_end_time": "2020-06-07 15:35:08" * } * } * * @param array $response HTTP响应 * @return array 标准化的响应格式 */ protected function parseResponse($response) { // 检查 ret 字段(0 表示成功) if (!isset($response['ret'])) { return [ 'success' => false, 'error' => $response['msg'] ?? '响应格式错误,缺少 ret 字段', ]; } // 如果 ret 不等于 0,表示请求失败 if ($response['ret'] != 0) { return [ 'success' => false, 'error' => $response['msg'] ?? 'API返回异常', 'ret' => $response['ret'], ]; } // 提取 data 字段中的数据 $data = $response['data'] ?? []; // 检查是否包含必需的token信息 if (empty($data['access_token'])) { return [ 'success' => false, 'error' => $response['msg'] ?? '未获取到 access_token', ]; } // 成功响应 return [ 'success' => true, 'access_token' => $data['access_token'] ?? '', 'refresh_token' => $data['refresh_token'] ?? '', 'auth_mobile' => $data['auth_mobile'] ?? '', 'auth_end_time' => $data['auth_end_time'] ?? '', ]; } /** * 获取AppKey * * @return string */ public function getAppKey() { return $this->appKey; } /** * 获取AppSecret * * @return string */ public function getAppSecret() { return $this->appSecret; } /** * 获取是否为沙箱环境 * * @return bool */ public function isSandbox() { return $this->isSandbox; } }