# UI Implementation Guide

The Get Mini framework is a "Headless" SDK. It does not provide built-in payment screens or storyboards. Instead, it delivers real-time events and data through delegate methods, allowing you to build a user interface that matches your application's native design.

## UI Requirements

Your application must implement UI for three distinct phases of the transaction lifecycle:

1. **Discovery**: Listing paired Bluetooth or Wi-Fi PIN pads.
2. **Transaction Progress**: Showing current hardware states (e.g., "Insert Card," "Enter PIN").
3. **User Interaction**: Modals for specific choices like Currency Conversion (DCC) or Installments.

## 1. Monitoring Transaction Progress

The `onPaymentProcess` method in the `RedsysBTPinpadPaymentDelegate` is your primary tool for updating the UI. The SDK sends string status updates or state objects during the hardware handshake.

### Progress Updates (Swift)

```
func onPaymentProcess(_ result: Any!, orError error: Error!) {
    if let statusMessage = result as? String {
        // Update your UI label on the main thread
        DispatchQueue.main.async {
            self.statusLabel.text = statusMessage
        }
    }
}
```

Common status messages include:
- "Esperando tarjeta..." (Waiting for card)
- "Introduzca PIN..." (Enter PIN)
- "Conectando con el host..." (Connecting to host)

## 2. Handling Interaction (The Feedback Loop)

When the SDK encounters a card that supports multiple payment options (like Dynamic Currency Conversion), it triggers the `onPaymentFeedback` method.

**Critical Implementation Rule**: This method requires a synchronous return value ("true" or "false"). Because UI interaction is asynchronous, you must use a blocking pattern with `NSCondition`.

### Selection UI Pattern (Objective-C)

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

    // 2. Trigger your UI (e.g. UIAlertController) on the main thread
    dispatch_async(dispatch_get_main_queue(), ^{
        [self showDCCPromptWithData:result];
    });

    // 3. Block this background thread until the user clicks a button
    [self.userDecisionCondition lock];
    [self.userDecisionCondition wait];
    [self.userDecisionCondition unlock];

    // 4. Return the user's choice to the SDK
    return self.userAcceptedChoice ? @"true" : @"false";
}
```

## 3. Digital Signatures

If a transaction requires a signature (check `result.reciboSoloCliente == false` and `result.autenticadoPorPin == false`), you must provide a signature pad UI.

Once the user signs, send the image to the Get Mini server using the `envioFirmaDigitalizada` method:

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

RedsysConfigurationManager.envioFirmaDigitalizada(firmaDTO) { result, error in
    // Handle signature upload result
}
```

## UI Best Practices

- **Main Thread Safety**: Always wrap UI updates in `DispatchQueue.main.async`. SDK callbacks may arrive on background threads used for hardware communication.
- **Blocking Navigation**: Once `payWithPinpadBluetooth` starts, disable the "Back" button and side menus. Interrupting the connection during key exchange can lock the terminal.
- **Clarity**: Ensure your status text is large and legible, as users often look at the iPhone screen for instructions rather than the PIN pad's small display.
- **DCC Transparency**: When showing currency choices, legally you must display the exchange rate and the commission markup found in the `RespuestaTransaccionDTO`.

## Troubleshooting UI Issues

**UI Hangs during DCC**
If you use the `NSCondition` wait pattern, ensure that your button actions (Accept/Decline) call `.signal()` on the condition. If you forget to signal, the entire payment process will wait forever.

**No Status Updates**
Verify that your class correctly conforms to `RedsysBTPinpadPaymentDelegate` and that you have assigned `self` as the delegate in the `payWithPinpadBluetooth` call.