environment('production')) { $integrationCode = 'telepagos_homo'; } $this->integrationCode = $integrationCode; } /** * Get the headers for Telepagos integration. * * @return array * @throws Exception */ public function getHeaders(): array { return [ 'Authorization' => 'Bearer ' . $this->getToken(), 'Content-Type' => 'application/json', 'Accept' => 'application/json', ]; } /** * Get a valid token, either from cache or by performing a login. * * @return string * @throws Exception */ public function getToken(): string { if (!$this->tenantIntegration) { throw new Exception("Tenant integration is not loaded. Call forTenant() first."); } $cacheKey = "integration_token:{$this->tenantCode}:{$this->integrationCode}"; $token = Cache::get($cacheKey); if ($token) { return $token; } return $this->login(); } /** * Authenticate with Telepagos and cache the returned token. * * @return string * @throws Exception */ public function login(): string { $username = $this->getIntegrationSetting('username'); $password = $this->getIntegrationSetting('password'); if (empty($username) || empty($password)) { throw new Exception("Missing username or password in Telepagos integration settings."); } $url = $this->getUrl('/v2/auth/token'); $response = Http::post($url, [ 'username' => $username, 'password' => $password, ]); $data = $this->handleResponse($response, 'authentication', [ 'username' => $username, ]); $token = $data['token'] ?? null; $expiresAtStr = $data['expires_at'] ?? null; if (!$token || !$expiresAtStr) { throw new Exception("Telepagos authentication response is missing token or expires_at."); } $expiresAt = Carbon::parse($expiresAtStr); // Calculate TTL and subtract a buffer of 60 seconds $ttlSeconds = max(1, $expiresAt->diffInSeconds(now()) - 60); $cacheKey = "integration_token:{$this->tenantCode}:{$this->integrationCode}"; Cache::put($cacheKey, $token, $ttlSeconds); return $token; } /** * Send a request to Telepagos, handling 401 Unauthorized for token refresh. * * @param string $method * @param string $endpoint * @param array $data * @return \Illuminate\Http\Client\Response */ protected function sendRequest(string $method, string $endpoint, array $data = []): \Illuminate\Http\Client\Response { $response = $this->client()->$method($endpoint, $data); if ($response->status() === 401) { Log::info("Telepagos 401 Unauthorized. Refreshing token and retrying..."); $this->clearToken(); $response = $this->client()->$method($endpoint, $data); } return $response; } /** * Generate a QR code for cash-in. * * @param float $amount * @param string $concept * @param string $description * @return array * @throws Exception */ public function generateQr(float $amount, string $concept, string $description): array { $payload = [ 'amount' => $amount, 'concept' => $concept, 'description' => $description, ]; $response = $this->sendRequest('post', '/v2/payment/cashin/qr/generate', $payload); return $this->handleResponse($response, 'QR generation', $payload); } /** * Get the details of a cash-in payment. * * @param int $cashinId * @return array * @throws Exception */ public function getCashinDetails(string $cashinId): array { $response = $this->sendRequest('get', "/v2/payment/cashin/{$cashinId}"); return $this->handleResponse($response, 'get cash-in details', [ 'cashin_id' => $cashinId, ]); } /** * Get the account info. * * @return array * @throws Exception */ public function getAccountInfo(): array { $response = $this->sendRequest('get', '/v2/account/info'); return $this->handleResponse($response, 'get account info'); } /** * Handle the Telepagos API response, logging any failures and throwing Exceptions. * * @param \Illuminate\Http\Client\Response $response * @param string $actionDescription * @param array $context * @return array * @throws Exception */ protected function handleResponse(\Illuminate\Http\Client\Response $response, string $actionDescription, array $context = []): array { if ($response->failed() || $response->json('status') !== 'ok') { $errorMessage = $response->json('message') ?? $response->body(); Log::error("Telepagos {$actionDescription} failed: {$errorMessage}", array_merge([ 'response_status' => $response->status(), 'response_body' => $response->json() ?? $response->body(), ], $context)); throw new Exception("Telepagos {$actionDescription} failed: {$errorMessage}"); } return $response->json() ?? []; } /** * Clear the cached token. * * @return void */ public function clearToken(): void { $cacheKey = "integration_token:{$this->tenantCode}:{$this->integrationCode}"; Cache::forget($cacheKey); } /** * Perform initial setup validation for Telepagos. * * @return void * @throws Exception */ public function onSetup(): void { // Realiza un login de prueba para validar que las credenciales son correctas. $this->login(); } }