# Inicio rápido: Tu primera venta

Este tutorial te guía a través de los pasos esenciales para procesar tu primera transacción de pago utilizando el SDK de Get Mini. Inicializarás el entorno del SDK, iniciarás sesión como comercio, te conectarás a un dispositivo PIN pad físico y ejecutarás una transacción de venta con gestión de resultados basada en delegados.

## Requisitos

Antes de empezar, asegúrate de tener:

- **SDK integrado** en tu proyecto de Xcode con los linker flags `-ObjC`, `-lstdc++` y `-lsqlite3` configurados
- **Protocolos de External Accessory** añadidos a tu Info.plist (ej., `com.datecs.PIN pad`)
- **Credenciales de prueba** proporcionadas por Get Mini: FUC (identificador único del comercio), Terminal, Licencia de la Aplicación y credenciales de inicio de sesión
- **Dispositivo iOS físico** para pruebas (El Simulator no soporta la comunicación Bluetooth con el PIN pad)
- **Dispositivo PIN pad Bluetooth** encendido y dentro del alcance

<Callout type="warning">

Debes completar [Instalar el SDK](/es/get-mini/ios-sdk/first-steps/install-the-sdk) y [Configurar Permisos de iOS](/es/get-mini/ios-sdk/first-steps/configure-ios-permissions) antes de continuar con este tutorial.

</Callout>

## Proceso de pago

Esta sección te guía a través del flujo de pago completo, desde la inicialización hasta la gestión del resultado de la transacción.

### Paso 1: Fijar el entorno de ejecución

El SDK debe inicializarse con tu licencia de aplicación y el entorno de ejecución antes de cualquier operación. Esta configuración se realiza normalmente en tu `AppDelegate` o en una clase gestora de pagos dedicada:

```
// Import via Bridging Header: CommonUtils.h
func initializeSDK() {
    // Set environment: "des" (Desarrollo), "int" (Integración), "ccal" (CCAL), "real" (Producción)
    CommonUtils.setEntorno("des")

    // Set your license key provided by Get Mini
    CommonUtils.setAppLicense("YOUR_LICENSE_KEY")
}
```

Llama a este método de inicialización en `application(_:didFinishLaunchingWithOptions:)` antes de cualquier operación del SDK. La configuración del entorno determina a qué servidores de TPV PC se conecta el SDK para procesar las transacciones.

<Callout type="warning">

Utiliza siempre el entorno de pruebas (`"des"`) durante el desarrollo. Cambia a producción (`"real"`) únicamente al desplegar en entornos reales con credenciales de producción válidas.

</Callout>

### Paso 2: Ejecutar el login del comercio

Antes de procesar transacciones, recupera la configuración del comercio desde Get Mini. La operación de login devuelve los datos del comercio (FUC, Terminal, etc.) requeridos para las operaciones de pago:

```
// Import via Bridging Header: DatosLoginDTO.h, RedsysConfigurationManager.h
func performMerchantLogin() {
    let loginDTO = DatosLoginDTO(user: "your_username", andPass: "your_password")

    RedsysConfigurationManager.obtenerDatosComercioLogin(loginDTO) { result, error in
        if let merchantData = result {
            print("Login successful for: \(merchantData.nombreComercio ?? "Merchant")")
            // Store merchantData for use in payment operations
            self.saveMerchantData(merchantData)
        } else {
            print("Login failed: \(error?.localizedDescription ?? "Unknown error")")
        }
    }
}
```

El objeto `DatosLoginResponseDTO` devuelto en caso de éxito contiene la configuración esencial del comercio, incluyendo el FUC, el Terminal ID y otros ajustes necesarios para crear el objeto `MerchanDTO` para el procesamiento de pagos.

### Paso 3: Implementar protocolos de delegados

Tu view controller debe conformar los protocolos de delegados del SDK para recibir callbacks durante la inicialización y el procesamiento del pago. Añade los protocolos requeridos a la declaración de tu clase:

```
// Import via Bridging Header: RedsysPinpadManager.h
class PaymentViewController: UIViewController,
                             RedsysDelegateGeneric,
                             RedsysBTPinpadInitDelegate,
                             RedsysBTPinpadPaymentDelegate {

    var pinpadManager: RedsysPinpadManager!
    var selectedDevice: Any?
    var pinpadConfig: PinpadConfig?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Manager initialization will happen when starting the payment flow
    }

    // MARK: - Init Delegate Methods

    func onInitFinished(_ result: Any!, orError error: Error!) {
        if let config = result as? PinpadConfig {
            print("PIN pad initialized successfully")
            self.pinpadConfig = config
            // Proceed to payment
        } else {
            print("Initialization failed: \(error?.localizedDescription ?? "")")
        }
    }

    // MARK: - Payment Delegate Methods

    func onPaymentProcess(_ result: Any!, orError error: Error!) {
        // Called during payment processing to notify progress
        print("Payment in progress...")
    }

    func onPaymentFinished(_ result: RespuestaTransaccionDTO!, orError error: Error!) {
        if let transaction = result, error == nil {
            print("Sale Approved! Auth Code: \(transaction.codigoAutorizacion ?? "")")
        } else {
            print("Sale Failed: \(error?.localizedDescription ?? "")")
        }
    }
}
```

Los métodos del delegado proporcionan callbacks en diferentes etapas: `onInitFinished` confirma que el PIN pad está listo, `onPaymentProcess` notifica las actualizaciones de progreso y `onPaymentFinished` entrega el resultado final de la transacción.

### Paso 4: Inicializar el manager del PIN pad

Crea la instancia del manager del PIN pad e inicialízala para la comunicación Bluetooth:

```
func startPaymentFlow() {
    // Initialize manager with Bluetooth technology
    pinpadManager = RedsysPinpadManager(bluetoothTech: "GENERAL")

    // Get available Bluetooth devices
    let availableDevices = pinpadManager.bluetoothDevicesList()

    guard let devices = availableDevices as? [Any], !devices.isEmpty else {
        print("No PIN pad devices found")
        return
    }

    // Select first available device
    selectedDevice = devices[0]

    // Configure the selected device
    connectAndConfigureDevice()
}

func connectAndConfigureDevice() {
    // Create MerchanDTO from login response
    let merchantDTO = MerchanDTO()
    merchantDTO.fuc = "999008881"  // From DatosLoginResponseDTO
    merchantDTO.fucExtendido = "999008881"
    merchantDTO.terminal = "001"
    merchantDTO.password = "your_password"

    // Connect and configure the device
    pinpadManager.connectAndConfigureDevice(selectedDevice,
                                           merchan: merchantDTO,
                                           withDelegate: self)
}
```

El manager busca dispositivos Bluetooth emparejados y establece una conexión. El método delegado `onInitFinished` será llamado cuando el dispositivo esté listo para realizar transacciones.

### Paso 5: Ejecutar el pago

Una vez que el PIN pad esté inicializado (confirmado en `onInitFinished`), crea el DTO de pago y ejecuta la transacción:

```
func executePayment() {
    guard let config = pinpadConfig else {
        print("PIN pad not initialized")
        return
    }

    // Create payment DTO
    let amount: Float = 10.50  // Amount in currency units
    let pagoDTO = PagoDTO(
        valor: Int(amount * 100),  // Convert to cents
        mMoneda: 978,              // ISO 4217 code (978 = EUR)
        nFactura: "TEST\(Int.random(in: 1000...9999))",  // Unique invoice number
        email: "",
        tlfCliente: "",
        datosPropietarios: ""
    )

    // Create MerchanDTO (same as in Step 4)
    let merchantDTO = MerchanDTO()
    merchantDTO.fuc = "999008881"
    merchantDTO.fucExtendido = "999008881"
    merchantDTO.terminal = "001"
    merchantDTO.password = "your_password"

    // Execute payment
    pinpadManager.payWithPinpadBluetooth(
        selectedDevice,
        merchan: merchantDTO,
        config: config,
        andPagoDTO: pagoDTO,
        withDelegate: self
    )
}
```

El SDK gestiona el flujo completo de la transacción, incluyendo la solicitud de inserción de la tarjeta, la introducción del PIN, la comunicación con los servidores de TPV PC y la devolución del resultado a través del callback delegado `onPaymentFinished`.

| Parámetro | Tipo | Descripción |
| :---- | :---- | :---- |
| `valor` | Int | Importe de la transacción en céntimos (ej., 1050 para 10,50 €) |
| `mMoneda` | Int | Código de moneda ISO 4217 (978 = EUR, 840 = USD) |
| `nFactura` | String | Nombre de la factura de la operación (caracteres permitidos: a-z, A-Z, 0-9, "_ - / ; : , ( ) + ? #"; no admite "ñ"/"Ñ") |

### Paso 6: Gestionar los resultados de la transacción

Procesa el resultado de la transacción en el callback delegado `onPaymentFinished`:

```
func onPaymentFinished(_ result: RespuestaTransaccionDTO!, orError error: Error!) {
    if let transaction = result, error == nil {
        // Transaction successful
        let authCode = transaction.codigoAutorizacion ?? ""
        let amount = transaction.importeTotal ?? ""

        print("Payment Approved")
        print("Auth Code: \(authCode)")
        print("Amount: \(amount)")

        // Save to database
        saveTransaction(authCode: authCode, amount: amount)

        // Show success message
        showSuccessAlert(authCode: authCode)
    } else {
        // Transaction failed
        print("Payment Failed: \(error?.localizedDescription ?? "")")
        showErrorAlert(message: error?.localizedDescription ?? "Transaction failed")
    }
}
```

Guarda siempre el código de autorización (`codigoAutorizacion`) de las transacciones exitosas. Este código es necesario para reembolsos y la conciliación.

## Resolución de problemas

**Fallo (Crash) al Inicializar RedsysPinpadManager**

Verifica que el linker flag `-ObjC` esté añadido en **Other Linker Flags**. La falta de este flag provoca bloqueos (crashes) de "Selector not recognized".

**No se Encuentran Dispositivos PIN pad**

Asegúrate de que `UISupportedExternalAccessoryProtocols` en Info.plist incluya el protocolo correcto para tu dispositivo (ej., `com.datecs.PIN pad` para dispositivos Itos/Castles). Confirma que el dispositivo está emparejado en los Ajustes de iOS > Bluetooth.

**Error de Entorno Durante el Login**

Si el login falla con errores de entorno, verifica que `CommonUtils.setEntorno` esté establecido en `"des"` para credenciales de prueba o `"real"` para credenciales de producción. El entorno debe coincidir con tus credenciales.

## Próximos pasos

Ahora que has procesado con éxito tu primer pago, explora capacidades adicionales del SDK:

* [Visión General del SDK de iOS](/es/get-mini/ios-sdk/ios-sdk-overview) - Aprende sobre el soporte multivendor y las características de seguridad
* [Configurar Permisos de iOS](/es/get-mini/ios-sdk/first-steps/configure-ios-permissions) - Revisa todos los protocolos y permisos obligatorios