# Crear un pago preautorizado

Aprende a gestionar el ciclo de vida completo de las preautorizaciones utilizando el `PreauthorizationRepository`. Una preautorización permite verificar y reservar un importe específico en la tarjeta de un cliente sin la captura inmediata de los fondos. Esto garantiza la disponibilidad del importe para un pago futuro, siendo la solución ideal para el sector de la hostelería, alquiler de vehículos o cualquier escenario donde el precio final del servicio se define solo al finalizar el mismo.

El ciclo de vida de una preautorización consta de cuatro operaciones principales:

1. **Crear (Create)**: Reserva los fondos en la tarjeta.
2. **Confirmar (Confirm)**: Finaliza el cargo (captura el importe).
3. **Sustituir (Replace)**: Modifica el importe reservado anteriormente.
4. **Anular (Annul)**: Cancela la reserva y libera el límite del cliente.

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

## 1. Crear una preautorización

Para iniciar el flujo, utiliza el método `makePreauthorization`. Esto verifica si la tarjeta dispone de fondos suficientes y realiza una retención sobre ellos.

**Función**: `makePreauthorization`

**Parámetros**:

* `amount`: El objeto `Money` que representa el importe a reservar.
* `shiftInfo` (Opcional): Información sobre el turno actual.
* `proprietaryExtraData` (Opcional): Datos de terceros.
* `language` (Opcional): Idioma para la interfaz del servicio.

**Ejemplo**:

```kotlin
suspend fun reserveFunds(amount: Money) {
    val result = preauthorizationRepository.makePreauthorization(
        amount = amount
    )
    handlePreauthResult(result)
}
```

## 2. Confirmar una preautorización

Una vez que se conozca el importe final (p. ej., en el momento del checkout), debes confirmar la preautorización para hacer efectivo el cargo en la tarjeta. Necesitarás el `operationId` devuelto en el paso de creación.

**Función**: `confirmPreauthorization`

**Parámetros**:

* `amount`: El importe final a cargar.
* `operationId`: El identificador de la preautorización original.
* `shiftInfo` (Opcional): Información del turno.
* `proprietaryExtraData` (Opcional): Datos de terceros.
* `language` (Opcional): Idioma para la interfaz del servicio.

**Ejemplo**:

```kotlin
suspend fun finalizeCharge(originalId: String, finalAmount: Money) {
    val result = preauthorizationRepository.confirmPreauthorization(
        operationId = originalId,
        amount = finalAmount
    )
    handlePreauthResult(result)
}
```

## 3. Sustituir (modificar) una preautorización

Si el coste estimado cambia (p. ej., extensión de un alquiler), puedes actualizar el importe reservado.

**Función**: `replacePreauthorization`

**Parámetros**:

* `amount`: El nuevo importe a reservar.
* `operationId`: El identificador de la preautorización original.
* `shiftInfo` (Opcional): Información del turno.
* `proprietaryExtraData` (Opcional): Datos de terceros.
* `language` (Opcional): Idioma para la interfaz del servicio.

**Ejemplo**:

```kotlin
suspend fun updateReservation(originalId: String, newAmount: Money) {
    val result = preauthorizationRepository.replacePreauthorization(
        operationId = originalId,
        amount = newAmount
    )
    handlePreauthResult(result)
}
```

## 4. Anular una preautorización

Si el servicio se cancela o la reserva ya no es necesaria, puedes liberar la retención de los fondos.

**Función**: `annulPreauthorization`

**Parámetros**:

* `operationId`: El identificador de la preautorización a cancelar.
* `language` (Opcional): Idioma para la interfaz del servicio.

**Ejemplo**:

```kotlin
suspend fun cancelReservation(originalId: String) {
    val result = preauthorizationRepository.annulPreauthorization(
        operationId = originalId
    )
    handlePreauthResult(result)
}
```

## Interpretar el resultado

Las cuatro operaciones devuelven un `RepositoryResult` que contiene un `PreauthorizationResult`.

### Estados del resultado

* **Aceptado (`PreauthorizationResult.Accepted`)**: La operación fue aprobada por el host.
  * **Datos**: Contiene un objeto `Transaction`. Para el paso de creación, guarda el `transaction.operationInfo.identifier` para usarlo en las llamadas posteriores de Confirmar/Sustituir/Anular.
* **Denegado (`PreauthorizationResult.Denied`)**: La operación fue rechazada.

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

```kotlin
fun handlePreauthResult(result: RepositoryResult<PreauthorizationResult>) {
    when (result) {
        is RepositoryResult.Success -> {
            when (val preAuthOutcome = result.data) {
                is PreauthorizationResult.Accepted -> {
                    val tx = preAuthOutcome.data
                    println("✅ Operation Approved. ID: ${tx.operationInfo.identifier}")
                    // Save tx.operationInfo.identifier for future use
                }
                is PreauthorizationResult.Denied -> {
                    println("❌ Operation Denied")
                }
            }
        }
        is RepositoryResult.ConnectionError -> println("❌ Connection Error")
        is RepositoryResult.Cancelled -> println("⚠️ Cancelled by user")
        is RepositoryResult.ProtocolError -> println("❌ Error: ${result.type}")
    }
}
```

## Próximos pasos

* [**Gestionar Turnos y Sesiones**](/es/get-smart/get-smart-sdk/integration-guides/business-management/manage-shifts-and-sessions): Gestiona el tiempo operativo.