Create a Pre-Authorized Payment
Learn how to manage the full lifecycle of pre-authorizations using the PreauthorizationRepository. A pre-authorization allows you to verify and reserve a specific amount on a customer’s card without immediately capturing the funds. This ensures the availability of the amount for a future payment, making it the ideal solution for the hospitality industry, car rentals, or any scenario where the final service price is only determined upon completion of the service.
The lifecycle of a pre-authorization consists of four main operations:
- Create: Reserve the funds.
- Confirm: Finalize the charge.
- Replace: Modify the reserved amount.
- Annul: Cancel the reservation.
Before performing any operation, ensure you have initialized the TPV.
1. Creating a Pre-authorization
To start the flow, use makePreauthorization. This verifies the card has sufficient funds and places a hold on them.
Function: makePreauthorization
Parameters:
amount: TheMoneyobject representing the amount to reserve.shiftInfo(Optional): Information about the current shift.proprietaryExtraData(Optional): Third-party data.language(Optional): Language for the service UI.
Example:
suspend fun reserveFunds(amount: Money) {
val result = preauthorizationRepository.makePreauthorization(
amount = amount
)
handlePreauthResult(result)
}2. Confirming a Pre-authorization
Once the final amount is known (e.g., checkout time), you must confirm the pre-authorization to actually charge the card. You need the operationId returned from the creation step.
Function: confirmPreauthorization
Parameters:
amount: The final amount to charge.operationId: The identifier of the original pre-authorization.shiftInfo(Optional): Shift information.proprietaryExtraData(Optional): Third-party data.language(Optional): Language for the service UI.
Example:
suspend fun finalizeCharge(originalId: String, finalAmount: Money) {
val result = preauthorizationRepository.confirmPreauthorization(
operationId = originalId,
amount = finalAmount
)
handlePreauthResult(result)
}3. Replacing (Modifying) a Pre-authorization
If the estimated cost changes (e.g., extending a rental), you can update the reserved amount.
Function: replacePreauthorization
Parameters:
amount: The new amount to reserve.operationId: The identifier of the original pre-authorization.shiftInfo(Optional): Shift information.proprietaryExtraData(Optional): Third-party data.language(Optional): Language for the service UI.
Example:
suspend fun updateReservation(originalId: String, newAmount: Money) {
val result = preauthorizationRepository.replacePreauthorization(
operationId = originalId,
amount = newAmount
)
handlePreauthResult(result)
}4. Annulling a Pre-authorization
If the service is cancelled or the reservation is no longer needed, you can release the hold on the funds.
Function: annulPreauthorization
Parameters:
operationId: The identifier of the pre-authorization to cancel.language(Optional): Language for the service UI.
Example:
suspend fun cancelReservation(originalId: String) {
val result = preauthorizationRepository.annulPreauthorization(
operationId = originalId
)
handlePreauthResult(result)
}Interpreting the Result
All four operations return a RepositoryResult containing a PreauthorizationResult.
Result States
- Accepted (
PreauthorizationResult.Accepted): The operation was approved by the host.- Data: Contains a
Transactionobject. For the creation step, save thetransaction.operationInfo.identifierto use in subsequent Confirm/Replace/Annul calls.
- Data: Contains a
- Denied (
PreauthorizationResult.Denied): The operation was rejected.
Example Handling Logic
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}")
}
}Next Steps
- Manage Shifts and Sessions: Manage operational timing.
- Transaction History: Review past operations.