config = $config ?? config('DigitMotor'); $this->tokenModel = new MotorTokenModel(); helper('api'); } /** * Return a valid Bearer access token, refreshing from Digit when needed. * * @throws DigitApiException */ public function getToken(bool $forceRefresh = false): string { if (!$forceRefresh) { $cached = $this->tokenModel->getByEnvironment($this->config->environment); if ($cached && !empty($cached['access_token']) && !empty($cached['expires_at'])) { $expiresAt = strtotime($cached['expires_at']); if ($expiresAt !== false && ($expiresAt - $this->config->tokenLeewaySec) > time()) { return $cached['access_token']; } } } return $this->fetchAndStoreToken(); } /** * Force refresh (e.g. after 401). * * @throws DigitApiException */ public function refreshToken(): string { return $this->getToken(true); } /** * @throws DigitApiException */ protected function fetchAndStoreToken(): string { if ($this->config->username === '' || $this->config->password === '') { throw new DigitApiException( 'Digit Motor credentials are not configured. Set DIGIT_MOTOR_USERNAME and DIGIT_MOTOR_PASSWORD in .env.', 'CONFIG', 0 ); } $url = $this->config->baseUrl . $this->config->authPath; $headers = ['Content-Type: application/json']; $body = [ 'username' => $this->config->username, 'password' => $this->config->password, ]; $response = call_third_party_api($url, 'POST', $headers, $body); $httpCode = (int) ($response['code'] ?? 0); $data = $response['data'] ?? []; if (is_string($data)) { $decoded = json_decode($data, true); $data = is_array($decoded) ? $decoded : []; } $accessToken = $data['access_token'] ?? $data['accessToken'] ?? $data['token'] ?? null; if (empty($accessToken) || empty($response['status'])) { $msg = $data['message'] ?? $data['error'] ?? 'Digit token generation failed.'; throw new DigitApiException( is_string($msg) ? $msg : 'Digit token generation failed.', $data['code'] ?? (string) $httpCode, $httpCode, $data ); } $expiresIn = (int) ($data['expires_in'] ?? $data['expiresIn'] ?? 900); $refreshToken = $data['refresh_token'] ?? $data['refreshToken'] ?? null; $expiresAt = date('Y-m-d H:i:s', time() + max(60, $expiresIn)); $this->tokenModel->upsertToken( $this->config->environment, $accessToken, $refreshToken, $expiresAt ); return $accessToken; } }