status() >= 400) { return true; } $contentType = $response->header('Content-Type') ?? ''; if (str_contains($contentType, 'application/json')) { $data = $response->json(); if (isset($data['error']) || (isset($data['ErrorCode']) && (string) $data['ErrorCode'] !== '0')) { return true; } } return false; } /** * Get the custom exception for the failed request. */ public function getRequestException(Response $response, ?Throwable $senderException): ?Throwable { $requestId = $response->header('X-Request-ID') ?? 'Unknown'; $errorCode = 'UNKNOWN'; $errorDescription = 'No description'; $contentType = $response->header('Content-Type') ?? ''; if (str_contains($contentType, 'application/json')) { $data = $response->json(); $errorCode = $data['error'] ?? $data['ErrorCode'] ?? 'HTTP_' . $response->status(); $rawDescription = $data['error_description'] ?? $data['message'] ?? 'Request failed'; $errorDescription = $this->decodeBankMessage($rawDescription); } else { $errorCode = 'HTTP_' . $response->status(); $errorDescription = 'Request failed with status ' . $response->status(); } return new AlfaBankException( $response, (string) $errorCode, "({$requestId}) {$errorDescription}" ); } private function decodeBankMessage(string $message): string { $decoded = preg_replace_callback( '/%u([0-9A-Fa-f]{4})/', fn ($m) => mb_convert_encoding(pack('H*', $m[1]), 'UTF-8', 'UCS-2BE'), $message ); return urldecode($decoded); } }