# Devolver un pago

El framework Get Mini proporciona dos formas de devolver fondos a los clientes: devoluciones estándar (vinculadas a una transacción anterior) y devoluciones independientes (sin la referencia de la transacción original).

## Requisitos

Antes de comenzar, asegúrate de haber verificado los permisos y la disponibilidad de datos. El comercio debe tener permiso para devoluciones (100201) y, para devoluciones independientes, el indicador específico `permiteDevolSinOrigin` habilitado. Para devoluciones estándar, debes poseer el `OperacionDTO` original o el `identificadorRTS`. Ten en cuenta que las devoluciones independientes requieren que el cliente esté físicamente presente con su tarjeta para completar la transacción en el PIN pad.

## Opción 1: Devolución estándar

Las devoluciones estándar están vinculadas a una transacción anterior en tu historial. Utiliza el `RedsysTransactionManager` para procesarlas vía Servicio Web.

### Paso 1: Obtener la operación original
Para iniciar una devolución vinculada, primero debes recuperar el objeto `OperacionDTO` correspondiente a la transacción original. Puedes hacer esto consultando el historial de transacciones.

```
// 1. Configurar la consulta de búsqueda
let userInfo = RedsysUserInfoManager.getInfo(user)
let dateFrom = Date().addingTimeInterval(-86400 * 30) // ej., últimos 30 días
let dateTo = Date()

// 'termTPVPC' es de tipo TerminalDataDTO (Tipo 2 para Terminal PC)
let consulta = ConsultaFechasDTO(
    terminal: termTPVPC,
    dateInitial: dateFrom,
    dateEnd: dateTo,
    andPage: 0,
    andUserInfo: userInfo
)

// 2. (Opcional) Aplicar filtros para encontrar transacción específica
let filtros = ConsultaFechasDTOFiltros()
filtros.setResultado("AUTORIZADAS")
filtros.setTipoOperacion("PAGO")
filtros.setFactura("INV-001") // Filtrar por tu ID de Factura

// 3. Ejecutar consulta
RedsysTransactionManager.peticionConsultaFechaPagina(
    consulta,
    conValores: filtros.dictValores()
) { (result, error) in
    if let result = result, let operations = result.operaciones as? [OperacionDTO] {
        // Encontrar el objeto de operación específico necesario para la devolución
        if let originalOp = operations.first {
             print("Operación encontrada: \(originalOp.numAutorizacion)")
             // Proceder al Paso 2 con 'originalOp'
        }
    }
}
```

### Paso 2: Iniciar la devolución
Usa `peticionDevolucion` con un objeto `EnvioDevolucionDTO`.

```
// 1. Configurar Información de Usuario
let userInfo = RedsysUserInfoManager.getInfo(user)

// 2. Configurar el Objeto de Devolución (usando un OperacionDTO existente)
// Asumiendo que 'termTPVPC' es tu TerminalDataDTO y 'operacionOriginal' es OperacionDTO
let devolucion = EnvioDevolucionDTO(
    terminal: termTPVPC,
    andOperacion: operacionOriginal,
    andUserInfo: userInfo
)

// 3. Establecer el importe (ej., "10.00")
devolucion.importedevol = "10.00"

// 4. Ejecutar
RedsysTransactionManager.peticionDevolucion(devolucion) { (result, error) in
    if let result = result {
        print("Devolución exitosa: \(result)")
    } else if let error = error {
        print("Error de devolución: \(error.localizedDescription)")
    }
}
```

<Callout type="note">

Para devoluciones entre diferentes comercios del mismo grupo, usa el constructor extendido incluyendo `ComercioOriginal`, `FechaOperacion`, y `NumAutorizacion`.

</Callout>

## Opción 2: Devolución sin original (independiente)

Si no tienes los detalles de la transacción original o estás procesando una devolución manual, usa el método de Devolución Bluetooth. Esto requiere que el cliente presente su tarjeta al PIN pad.

### Paso 1: Ejecutar la devolución
Crea un `EnvioDevolucionSinOriginalDTO` con el importe en céntimos y ejecútalo usando el pinpadManager.

```
// Importe en céntimos (ej., 10.00€ = 1000)
// 'termTPVPC' es tu TerminalDataDTO
let devolucionSinOriginal = EnvioDevolucionSinOriginalDTO(
    terminal: termTPVPC,
    andImporteDevolucion: "1000",
    forFactura: "INV-001"
)

// Ejecutar usando el pinpadManager
// Asumiendo que 'pinpadElegido', 'merchanElegido', y 'pinpadConfig' están inicializados
pinpadManager.devolucionBluetooth(
    pinpadElegido,
    merchan: merchanElegido,
    config: pinpadConfig,
    andDevolucionDTO: devolucionSinOriginal,
    withDelegate: self
)
```

### Paso 2: Manejar callbacks del PIN pad
Debes implementar `onDevolucionFinished` para recibir el resultado, que será devuelto como un `DevolucionResponseDTO`.

## Restricciones y errores de devolución

| Restricción | Descripción |
| :---- | :---- |
| **Límite de Importe** | Una devolución estándar no puede exceder el importe de la transacción original (Código de Error 200: TPV-PC0009). |
| **Permiso** | Las devoluciones independientes deben estar habilitadas en el perfil del comercio (`permiteDevolSinOrigin`). |
| **Estado de Transacción** | Solo puedes realizar una devolución en operaciones con un Estado de "F" (Finalizada). |

## Solución de problemas

**Código de Error 200 (TPV-PC0009)**
El importe de la devolución excede el importe de la transacción original. Verifica el saldo restante del pedido original si se emitieron devoluciones parciales previamente.

**Código de Error 262 (TPV-PC0100)**
El tipo de operación específico no permite una devolución (ej., intentando devolver una transacción que no se ha liquidado aún o ya está anulada).

**Permisos de Comercio**
Si una devolución independiente falla inmediatamente, verifica `PerfilComercioManager` para ver si `permiteDevolSinOrigin` es YES.

## Próximos pasos

- [Crear una venta](/es/get-mini/ios-sdk/guides/single-step-payment-ios) - Transacciones de venta estándar
- [Crear un pago con plazos](/es/get-mini/ios-sdk/guides/create-installments-ios) - Manejar moneda y opciones de financiación
- [Inicializar el SDK](/es/get-mini/ios-sdk/guides/initialize-ios-sdk) - Configurar SDK