# Devolver un pago

Esta guía detalla cómo implementar operaciones de devolución utilizando el `RefundRepository`. Las devoluciones permiten devolver fondos a la tarjeta de un cliente, ya sea vinculados a una transacción anterior o como una operación independiente.

Antes de realizar cualquier devolución, asegúrate de haber [**inicializado el TPV**](/es/get-smart/get-smart-sdk/integration-guides/payment-operations/initialize-the-tpv).

## Métodos de devolución

El `RefundRepository` admite tres flujos de devolución distintos:

### 1. Devolución estándar (por ID)

Utiliza este método cuando dispongas del identificador de la transacción original (`operationId`) y quieras devolver un importe específico contra ella. Este es el escenario más común.

**Función**: `makeRefund`

**Parámetros**:

* `operationId`: El identificador único de la venta original.  
* `amount`: El objeto `Money` que representa el importe a devolver.  
* `proprietaryExtraData` (Opcional): Datos de terceros.  
* `language` (Opcional): Idioma para la interfaz del servicio.

**Ejemplo**:

```kotlin
suspend fun refundTransaction(originalId: String, amount: Money) {
    val result = refundRepository.makeRefund(
        operationId = originalId,
        amount = amount
    )
    handleRefundResult(result)
}
```

### 2. Devolución con lectura de tarjeta

Utiliza este método cuando dispongas del `operationId` original pero quieras obligar al cliente a presentar su tarjeta de nuevo (p. ej., por motivos de seguridad o cumplimiento).

**Función**: `makeRefundReadingCard`

**Parámetros**: Los mismos que la Devolución Estándar.

**Ejemplo**:

```kotlin
suspend fun refundWithCardCheck(originalId: String, amount: Money) {
    val result = refundRepository.makeRefundReadingCard(
        operationId = originalId,
        amount = amount
    )
    handleRefundResult(result)
}
```

### 3. Devolución sin original

Utiliza este método para emitir una devolución sin vincularla a una transacción anterior. Esta funcionalidad suele requerir que se habilite una configuración específica (`noOriginal`) en el TPV.

**Función**: `makeRefundWithoutOriginal`

**Parámetros**:

* `amount`: El objeto `Money` que representa el importe a devolver.  
* `proprietaryExtraData` (Opcional): Datos de terceros.  
* `language` (Opcional): Idioma para la interfaz del servicio.

**Ejemplo**:

```kotlin
suspend fun adhocRefund(amount: Money) {
    val result = refundRepository.makeRefundWithoutOriginal(
        amount = amount
    )
    handleRefundResult(result)
}
```

## Interpretar el RefundResult

Cuando la llamada al repositorio es exitosa (`RepositoryResult.Success`), devuelve una interfaz sellada `RefundResult`. Debes gestionar los siguientes estados:

### 1. Aceptado (RefundResult.Accepted)

La devolución fue autorizada por el host.

* **Datos**: Contiene un objeto `Transaction` con los detalles de la operación de devolución.  
* **Acción**: Imprime el recibo de la devolución y confirma el éxito al usuario.

### 2. Denegado (`RefundResult.Denied`)

La devolución fue rechazada.

* **Datos**: Contiene un objeto `Transaction`, posiblemente con un motivo de rechazo.  
* **Acción**: Informa al usuario de que la devolución fue denegada.

### 3. Importe excedido (`RefundResult.ExceededAmount`)

Error específico que indica que el importe de la devolución solicitada es superior al importe de la transacción original.

* **Acción**: Muestra un error indicando que el importe es demasiado alto.

### Ejemplo de lógica de gestión

```kotlin
fun handleRefundResult(result: RepositoryResult<RefundResult>) {
    when (result) {
        is RepositoryResult.Success -> {
            when (val refundOutcome = result.data) {
                is RefundResult.Accepted -> {
                    println("✅ Refund Approved: ${refundOutcome.data.operationInfo.authorizationNumber}")
                }
                is RefundResult.Denied -> {
                    println("❌ Refund Denied")
                }
                is RefundResult.ExceededAmount -> {
                    println("⚠️ Error: Refund amount exceeds original transaction")
                }
            }
        }
        is RepositoryResult.ConnectionError -> println("❌ Connection Error")
        is RepositoryResult.Cancelled -> println("⚠️ Cancelled by user")
        is RepositoryResult.ProtocolError -> println("❌ Protocol Error: ${result.type}")
    }
}
```

## Próximos pasos

* [**Crear un Pago Preautorizado**](/es/get-smart/get-smart-sdk/integration-guides/payment-operations/create-a-pre-authorized-payment): Aprende sobre la reserva de fondos en una tarjeta.