# Handle Responses and Errors

The Get Smart SDK (`redsys-tpv-business-lib`) uses a unified approach to handle the outcomes of asynchronous operations. Every repository function is a `suspend` function that returns a `RepositoryResult<T>` wrapper.

This wrapper serves two main purposes:

1. **Safety**: It forces you to explicitly handle failure cases, preventing unhandled exceptions from crashing your app.  
2. **Consistency**: It provides a standard structure for success, network errors, user cancellations, and protocol issues across all features (Payments, Refunds, Initialization, etc.).

## The RepositoryResult Structure

`RepositoryResult<T>` is a Kotlin `sealed class`. This means when you consume a result using a `when` expression, the compiler will ensure you handle all possible outcomes (or use an `else` branch).

### Result Types

When you call a function like `paymentRepository.makePayment(...)`, the result will be one of the following:

#### 1\. Success (`Success<T>`)

The operation completed successfully, and the SDK received a valid response from the Get Smart SDK Payment Service.

* **Properties**: Contains a `data` property of type `T`.  
* **Usage**: Access `result.data` to get the actual payload (e.g., `PaymentResult`, `TpvInfo`, `Transaction`).
<Callout type="note">

For payments, `T` is `PaymentResult`. You must check inside `data` to see if the payment was `Accepted` or `Denied`.

</Callout>

#### 2\. Connection Error (`ConnectionError`)

Communication with the service or the Host failed.

* **Cause**: Usually indicates a network issue or that the Get Smart SDK Payment Service is not running/installed on the device. 
* **Properties**: This object has no extra properties (`data object`). 
* **Action**: Prompt the user to check their internet connection or retry the operation.

#### 3\. Cancelled (`Cancelled`)

The operation was manually cancelled by the user or the system.

* **Cause**: The user pressed the "Cancel" button on the TPV screen during a payment or other interactive flow.  
* **Properties**: Contains a `message` string explaining the cancellation reason.  
* **Action**: Inform the user that the process was stopped.

#### 4\. Protocol Error (`ProtocolError`)

Represents an integration or logical error preventing the operation from executing.

* **Properties**:  
  * `type`: A `ProtocolErrorType` enum indicating the category of the error.  
  * `description`: An optional string with more details. 

## ProtocolErrorType Reference

The `ProtocolErrorType` enum helps you diagnose integration issues programmatically:

| Type | Description |
| :---- | :---- |
| `MAPPING_DATA` | Error mapping data between the SDK and the background service. usually internal. |
| `MAPPING_DOMAIN` | Error mapping your application's request data. Check your parameters. |
| `TPV_NOT_INITIALIZED` | **Critical**: The TPV has not been initialized. You must call `InitializationRepository.initTpv()` successfully before retrying. |

## Example Implementation

Here is a practical pattern for handling results in your ViewModel or UseCase layer. Note the nested check for PaymentResult inside the success block.

```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}")
            }
        }
    }
}
```

## Next Steps

Now that you understand the generic result wrapper, you are ready to implement specific features:

* [**Initialize the TPV**](/en/get-smart/get-smart-sdk/integration-guides/payment-operations/initialize-the-tpv): The mandatory first step for any integration.  
* [**Create a Pre-Authorized Payment**](/en/get-smart/get-smart-sdk/integration-guides/payment-operations/create-a-pre-authorized-payment): Learn how to process a pre-authorization transaction. 
* [**Create a Payment with Installments (Plazox)**](/en/get-smart/get-smart-sdk/integration-guides/payment-operations/create-a-payment-with-installments-plazox): Learn how to perform payments with installments.