# Guía de implementación de UI

El framework Get Mini es un SDK "Headless" (sin interfaz gráfica). No proporciona pantallas de pago ni storyboards integrados. En su lugar, entrega eventos y datos en tiempo real a través de métodos delegados, permitiéndote construir una interfaz de usuario que coincida con el diseño nativo de tu aplicación.

## Requisitos de UI

Tu aplicación debe implementar UI para tres fases distintas del ciclo de vida de la transacción:

1. **Descubrimiento**: Listado de PIN pads Bluetooth o Wi-Fi emparejados.
2. **Progreso de Transacción**: Mostrar estados actuales del hardware (p. ej., "Inserte tarjeta", "Introduzca PIN").
3. **Interacción del Usuario**: Modales para elecciones específicas como selección de moneda (DCC) o plazos.

## 1. Monitorización del progreso de la transacción

El método `onPaymentProcess` en el `RedsysBTPinpadPaymentDelegate` es tu herramienta principal para actualizar la UI. El SDK envía las actualizaciones de estado como cadenas de texto o como objetos de estado durante el intercambio inicial de señales con el hardware.

### Actualizaciones de progreso (Swift)

```
func onPaymentProcess(_ result: Any!, orError error: Error!) {
    if let statusMessage = result as? String {
        // Actualiza tu etiqueta de UI en el hilo principal
        DispatchQueue.main.async {
            self.statusLabel.text = statusMessage
        }
    }
}
```

Mensajes de estado comunes incluyen:
- "Esperando tarjeta..."
- "Introduzca PIN..."
- "Conectando con el host..."

## 2. Manejo de interacción (El Bucle de Retroalimentación)

Cuando el SDK encuentra una tarjeta que soporta múltiples opciones de pago (como DCC (Dynamic Currency Conversion)), dispara el método `onPaymentFeedback`.

**Regla de Implementación Crítica**: Este método requiere un valor de retorno síncrono (`true` o `false`). Debido a que la interacción de UI es asíncrona, debes usar un patrón de bloqueo con `NSCondition`.

### Patrón de UI de selección (Objective-C)

```
-(id)onPaymentFeedback:(RespuestaTransaccionDTO *)result orError:(NSError *)error {
    // 1. result contiene datos DCC: ImporteOriginal, ImporteDivisa, TasaCambio

    // 2. Disparar tu UI (ej. UIAlertController) en el hilo principal
    dispatch_async(dispatch_get_main_queue(), ^{
        [self showDCCPromptWithData:result];
    });

    // 3. Bloquear este hilo de fondo hasta que el usuario haga clic en un botón
    [self.userDecisionCondition lock];
    [self.userDecisionCondition wait];
    [self.userDecisionCondition unlock];

    // 4. Retornar la elección del usuario al SDK
    return self.userAcceptedChoice ? @"true" : @"false";
}
```

## 3. Firmas digitales

Si una transacción requiere una firma (revisa `result.ReciboSoloCliente == false` y `result.AutenticadoPorPin == false`), debes proporcionar una UI de panel de firma.

Una vez que el usuario firme, envía la imagen al servidor de Get Mini usando el método `envioFirmaDigitalizada`:

```
let firmaDTO = EnvioFirmaDTO(
    terminal: activeTerminal,
    withFirma: signatureImage,
    format: 2, // 2 = JPG
    andOperacion: lastOperation
)

RedsysConfigurationManager.envioFirmaDigitalizada(firmaDTO) { result, error in
    // Manejar resultado de subida de firma
}
```

## Mejores prácticas de UI

- **Seguridad del Hilo Principal**: Siempre envuelve las actualizaciones de UI en `DispatchQueue.main.async`. Los callbacks del SDK pueden llegar en hilos de fondo utilizados para la comunicación con el hardware.
- **Bloqueo de Navegación**: Una vez que `payWithPinpadBluetooth` comience, deshabilita el botón "Atrás" y los menús laterales. Evita interrumpir la conexión mientras el PIN pad está procesando la operación, ya que podría dejar el terminal en un estado inconsistente.
- **Claridad**: Asegúrate de que tu texto de estado sea grande y legible, ya que los usuarios a menudo miran la pantalla del iPhone en busca de instrucciones en lugar de la pequeña pantalla del PIN pad.
- **Transparencia DCC**: Al mostrar opciones de moneda, legalmente debes mostrar la tasa de cambio y el margen de comisión encontrados en el `RespuestaTransaccionDTO`.

## Solución de Problemas de UI

**UI se Cuelga durante DCC**
Si usas el patrón de espera `NSCondition`, asegúrate de que tus acciones de botón (Aceptar/Rechazar) llamen a `.signal()` en la condición. Si olvidas señalar, todo el proceso de pago esperará para siempre.

**Sin Actualizaciones de Estado**
Verifica que tu clase cumpla correctamente con `RedsysBTPinpadPaymentDelegate` y que hayas asignado `self` como el delegado en la llamada `payWithPinpadBluetooth`.