Create a Pre-authorized Payment
Pre-authorization transactions allow you to verify card validity and reserve funds without immediate capture. This is a two-step process: creating the pre-authorization and later confirming it (capturing the funds).
This guide walks you through creating pre-authorizations, storing transaction references, and confirming (capturing) the reserved funds.
Requirements
Before you begin, ensure you have:
- Pre-authorization permission enabled on your merchant account (service code
100101or100201) - SDK initialized with environment and license via
CommonUtils - PIN pad connected and initialized (received
PinpadConfigfromonInitFinished) - Delegates implemented:
RedsysDelegateGeneric,RedsysBTPinpadInitDelegate,RedsysBTPinpadPaymentDelegate
Use peticionPerfilComercio to verify your account has permitePreauto set to YES before attempting pre-authorizations.
Pre-authorization Process
Step 1: Create the Pre-authorization
To initiate a pre-authorization, use the payWithPinpadBluetooth method with a PagoDTO configured for pre-authorization type.
Configure the PagoDTO
Create the payment DTO and set the transaction type to PREAUTORIZACION:
// Import via Bridging Header: PagoDTO.h
func createPreauthorization() {
let amount: Float = 150.00 // Maximum amount to reserve
// Initialize PagoDTO with amount in cents
let pagoDTO = PagoDTO(
valor: Int(amount * 100), // 15000 cents = €150.00
mMoneda: 978, // ISO 4217 code (978 = EUR)
nFactura: "PREAUTH001", // Unique invoice number
email: "",
tlfCliente: "",
datosPropietarios: ""
)
// Set transaction type to Pre-authorization
pagoDTO.setTipoPago("PREAUTORIZACION")
// Execute the pre-authorization
executePreauth(pagoDTO)
}Execute Pre-authorization
Use the same payWithPinpadBluetooth method as regular payments:
func executePreauth(_ pagoDTO: PagoDTO) {
// Create MerchanDTO with required fields
let merchantDTO = MerchanDTO()
merchantDTO.fuc = "999008881"
merchantDTO.fucExtendido = "999008881"
merchantDTO.terminal = "001"
merchantDTO.password = "merchant_pass"
// Execute pre-authorization
pinpadManager.payWithPinpadBluetooth(
selectedDevice,
merchan: merchantDTO,
config: pinpadConfig,
andPagoDTO: pagoDTO,
withDelegate: self
)
}The SDK handles card reading, PIN entry, and gateway communication. The customer must present their card to establish the fund reservation.
Step 2: Store Transaction References
When the pre-authorization is successful, the onPaymentFinished delegate receives a RespuestaTransaccionDTO. You must store the identificadorRTS to confirm the operation later:
func onPaymentFinished(_ result: RespuestaTransaccionDTO!, orError error: Error!) {
if let transaction = result, error == nil {
// Verify transaction state
if transaction.estado == "F" { // F = Finished
if transaction.resultado == "Autorizada" {
// Pre-authorization successful
let rtsID = transaction.identificadorRTS ?? ""
print("Pre-auth successful. RTS ID: \(rtsID)")
// Store RTS ID for later confirmation
savePreAuthReference(rtsID: rtsID, forBooking: bookingID)
}
}
} else {
print("Pre-authorization failed: \(error?.localizedDescription ?? "")")
}
}The identificadorRTS is a 24-character string that uniquely identifies the pre-authorization transaction. This ID is required to confirm or cancel the transaction later.
| Field | Purpose |
|---|---|
identificadorRTS | 24-character identifier for confirmation (required) |
estado | Transaction state: “F” (Finished), “P” (Processing), “A” (Cancelled) |
resultado | Transaction result: “Autorizada” (Approved), “Denegada” (Declined) |
Pre-authorizations expire if they are not confirmed. Consult your merchant agreement for specific expiration policies.
Step 3: Confirm the Pre-authorization
To capture the funds, perform a confirmation operation. This requires the original identificadorRTS from Step 2.
Query and Confirm Using Filters
The SDK uses query filters to manage confirmations:
// Import via Bridging Header: ConsultaFechasDTOFiltros.h, RedsysTransactionManager.h
func confirmPreauthorization(rtsID: String) {
// Create filter for confirmation operations
let filtros = ConsultaFechasDTOFiltros()
filtros.setTipoOperacion("CONFIRMACION")
// Create query DTO with the RTS identifier
let consulta = ConsultaFechasDTO()
// Configure consulta with terminal data and RTS ID
// Execute confirmation query
RedsysTransactionManager.peticionConsultaFechaPagina(
consulta,
conValores: filtros.dictValores()
) { result, error in
if let operations = result, error == nil {
// Process confirmation result
print("Confirmation processed")
} else {
print("Confirmation failed: \(error?.localizedDescription ?? "")")
}
}
}The confirmation captures the reserved funds. The final amount can be less than or equal to the originally pre-authorized amount. If you capture less, the remaining funds are released back to the customer’s available balance.
You cannot confirm an amount greater than the original pre-authorization. This will result in an error: “No es posible realizar más confirmaciones sobre la preautorización original.”
Step 4: Cancel a Pre-authorization (Optional)
If service is cancelled and you want to release reserved funds immediately, perform a cancellation. Pre-authorizations that are not confirmed automatically expire after their validity period (typically 7 days), but explicit cancellation provides immediate fund release.
Use the query filter with PREAUTORIZACION type to identify and cancel the specific transaction using the stored identificadorRTS.
Key Technical Constraints
| Requirement | Description |
|---|---|
| RTS Identifier | You must store the identificadorRTS from the original pre-authorization to confirm later |
| Amount Limit | Confirmation amount cannot exceed the original pre-authorized value |
| Currency Match | The currency must match the original transaction’s currency code |
| Transaction Status | Always verify estado == "F" and resultado == "Autorizada" before considering success |
| Confirmation Limits | You cannot perform more confirmations than allowed by the original pre-authorization |
Best Practices
Store Transaction References
Save the identificadorRTS in your database indexed by booking or service reference:
func savePreAuthReference(rtsID: String, forBooking bookingID: String) {
// Link RTS ID to booking record
database.save(rtsID: rtsID, bookingID: bookingID, expiration: Date().addingTimeInterval(7*24*60*60))
}Implement Expiration Tracking
Monitor pre-authorizations approaching expiration and prompt staff to finalize or cancel them before automatic expiration occurs.
Communicate with Customers
Clearly explain to customers when pre-authorizations are placed and when they’ll be finalized to reduce confusion about pending charges on their statements.
Troubleshooting
Merchant Not Enabled for Pre-authorizations
If you receive the error “El comercio no tiene habilitada la operativa de Preautorizaciones”, contact Get Mini support to enable pre-authorization permissions on your merchant account.
Pre-authorization Expired
If confirmation fails with expiration errors, the pre-authorization exceeded its validity period. Process a new single-step payment for the actual charge amount.
Confirmation Limit Exceeded
Error “No es posible realizar más confirmaciones sobre la preautorización original” means you’ve already captured the maximum allowed confirmations. Check your transaction history for previous confirmation attempts.
Currency Mismatch
The currency in the confirmation must match the original pre-authorization’s currency. Verify both transactions use the same ISO 4217 currency code.
Next Steps
Explore related payment operations:
- Create a Single-Step Payment - Standard sale transactions
- Transaction Lifecycle - Understand transaction processing phases
- Security and Licensing - Learn about payment security