# 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 `100101` or `100201`)
- **SDK initialized** with environment and license via `CommonUtils`
- **PIN pad connected** and initialized (received `PinpadConfig` from `onInitFinished`)
- **Delegates implemented**: `RedsysDelegateGeneric`, `RedsysBTPinpadInitDelegate`, `RedsysBTPinpadPaymentDelegate`

<Callout type="warning">

Use `peticionPerfilComercio` to verify your account has `permitePreauto` set to `YES` before attempting pre-authorizations.

</Callout>

## 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) |

<Callout type="warning">

Pre-authorizations expire if they are not confirmed. Consult your merchant agreement for specific expiration policies.

</Callout>

### 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.

<Callout type="warning">

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."

</Callout>

### 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](/en/get-mini/ios-sdk/guides/single-step-payment-ios) - Standard sale transactions  
* [Transaction Lifecycle](/en/get-mini/ios-sdk/core-concepts/ios-lifecycle) - Understand transaction processing phases
* [Security and Licensing](/en/get-mini/ios-sdk/core-concepts/security-pci) - Learn about payment security