# Gestión de respuestas y errores

El Get Smart SDK (`redsys-tpv-business-lib`) utiliza un enfoque unificado para manejar los resultados de las operaciones asíncronas. Cada función de repositorio es una función `suspend` que devuelve un envoltorio (wrapper) `RepositoryResult<T>`.

Este envoltorio sirve para dos propósitos principales:

1. **Seguridad**: Te obliga a manejar explícitamente los casos de fallo, evitando que las excepciones no controladas provoquen el cierre (crash) de tu aplicación.
2. **Consistencia**: Proporciona una estructura estándar para éxito, errores de red, cancelaciones de usuario y problemas de protocolo en todas las funciones (Pagos, Devoluciones, Inicialización, etc.).

## La estructura RepositoryResult

`RepositoryResult<T>` es una `sealed class` (clase sellada) de Kotlin. Esto significa que cuando consumes un resultado utilizando una expresión `when`, el compilador se asegurará de que manejes todos los resultados posibles (o utilices una rama `else`).

### Tipos de resultado

Al llamar a una función como `paymentRepository.makePayment(...)`, el resultado será uno de los siguientes:

#### 1. Éxito (`Success<T>`)

La operación se completó correctamente y el SDK recibió una respuesta válida del Get Smart SDK Payment Service.

* **Propiedades**: Contiene una propiedad `data` de tipo `T`.
* **Uso**: Accede a `result.data` para obtener el payload real (p. ej., `PaymentResult`, `TpvInfo`, `Transaction`).
<Callout type="note">

Para los pagos, `T` es `PaymentResult`. Debes verificar dentro de `data` si el pago fue `Accepted` (Aceptado) o `Denied` (Denegado).

</Callout>

#### 2. Error de conexión (`ConnectionError`)

La comunicación con el servicio o con el Host falló.

* **Causa**: Generalmente indica un problema de red o que el Get Smart SDK Payment Service no se está ejecutando o no está instalado en el dispositivo.
* **Propiedades**: Este objeto no tiene propiedades adicionales (`data object`).
* **Acción**: Pide al usuario que compruebe su conexión a internet o reintenta la operación.

#### 3. Cancelado (`Cancelled`)

La operación fue cancelada manualmente por el usuario o por el sistema.

* **Causa**: El usuario pulsó el botón "Cancelar" en la pantalla del TPV durante un pago u otro flujo interactivo.
* **Propiedades**: Contiene un string `message` que explica el motivo de la cancelación.
* **Acción**: Informa al usuario de que el proceso se ha detenido.

#### 4. Error de protocolo (`ProtocolError`)

Representa un error de integración o lógico que impide la ejecución de la operación.

* **Propiedades**:
    * `type`: Un enum `ProtocolErrorType` que indica la categoría del error.
    * `description`: Un string opcional con más detalles.

## Referencia de ProtocolErrorType

El enum `ProtocolErrorType` te ayuda a diagnosticar problemas de integración de forma programática:

| Tipo | Descripción |
| :---- | :---- |
| `MAPPING_DATA` | Error al mapear datos entre el SDK y el servicio en segundo plano. Generalmente interno. |
| `MAPPING_DOMAIN` | Error al mapear los datos de solicitud de tu aplicación. Comprueba tus parámetros. |
| `TPV_NOT_INITIALIZED` | **Crítico**: El TPV no ha sido inicializado. Debes llamar a `InitializationRepository.initTpv()` con éxito antes de reintentarlo. |

## Ejemplo de implementación

A continuación se muestra un patrón práctico para manejar resultados en tu capa de ViewModel o UseCase. Observa la comprobación anidada para `PaymentResult` dentro del bloque de éxito.

```kotlin
import es.redsys.adquirencia.tpva.service.model.RepositoryResult
import es.redsys.adquirencia.tpva.service.model.ProtocolErrorType

suspend fun processPayment(amount: Money) {
    // 1. Call the repository
    val result = paymentRepository.makePayment(amount)

    // 2. Handle all possible outcomes
    when (result) {
        is RepositoryResult.Success -> {
            // Operation succeeded, business logic continues here
            // Note: For payments, you still need to check the business result (Accepted/Denied) inside 'data'
            val paymentOutcome = result.data
            handlePaymentOutcome(paymentOutcome)
        }

        is RepositoryResult.ConnectionError -> {
            // Infrastructure failure
            viewState.showError("Connection failed. Please check internet and try again.")
        }

        is RepositoryResult.Cancelled -> {
            // User abort
            viewState.showInfo("Operation cancelled: ${result.message}")
        }

        is RepositoryResult.ProtocolError -> {
            // Developer/Integration error
            if (result.type == ProtocolErrorType.TPV_NOT_INITIALIZED) {
                viewState.showError("Critical: TPV not initialized.")
                // Trigger re-initialization logic
            } else {
                viewState.showError("Integration Error: ${result.description}")
            }
        }
    }
}
```

## Próximos pasos

Ahora que comprendes el envoltorio de resultado genérico, estás listo para implementar funciones específicas:

* [**Inicializar el TPV**](/es/get-smart/get-smart-sdk/integration-guides/payment-operations/initialize-the-tpv): El primer paso obligatorio para cualquier integración.
* [**Crear un Pago Preautorizado**](/es/get-smart/get-smart-sdk/integration-guides/payment-operations/create-a-pre-authorized-payment): Aprende cómo procesar una transacción de preautorización.
* [**Crear un Pago a Plazos (Plazox)**](/es/get-smart/get-smart-sdk/integration-guides/payment-operations/create-a-payment-with-installments-plazox): Aprende cómo realizar pagos a plazos.