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:
- Crear (Create): Reserva los fondos en la tarjeta.
- Confirmar (Confirm): Finaliza el cargo (captura el importe).
- Sustituir (Replace): Modifica el importe reservado anteriormente.
- 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.
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 objetoMoneyque 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:
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:
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:
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:
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 eltransaction.operationInfo.identifierpara usarlo en las llamadas posteriores de Confirmar/Sustituir/Anular.
- Datos: Contiene un objeto
- Denegado (
PreauthorizationResult.Denied): La operación fue rechazada.
Ejemplo de lógica de gestión
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: Gestiona el tiempo operativo.