# Security and Licensing

Card reading and PIN entry happen on the certified PIN pad, not in your application. This page covers what your app is responsible for: binding the terminal through the licensing model, choosing the execution environment, capturing a signature when the card requires it, and handling logs and credentials safely.

## Terminal Binding & Licensing

A unique security feature of the Get Mini SDK is **Bundle ID Binding**, which prevents unauthorized applications from processing transactions using your merchant credentials.

### License Registration Process

To use the SDK, you must register your app's **Bundle Identifier** with Get Mini:

**Step 1: Provide Bundle ID**

Contact Get Mini support and provide your iOS app's Bundle Identifier (found in Xcode under **General > Identity > Bundle Identifier**).

**Step 2: Receive License Key**

Get Mini issues a license key uniquely linked to your specific Bundle ID. This key binds your merchant credentials to your application.

**Step 3: SDK Validation**

The SDK validates the license during initialization:

```
CommonUtils.setAppLicense("YOUR_LICENSE_KEY")
```

If the Bundle ID of the running app does not match the one associated with the license, the SDK fails to initialize and returns an error.

### Environment Control

You are **strictly prohibited** from setting the environment to `"real"` (Production) until your implementation has been certified by Get Mini:

```
// Development/Testing only
CommonUtils.setEntorno("des")  // Allowed during development

// Production - ONLY after certification
CommonUtils.setEntorno("real")  // Requires Get Mini approval
```

This control prevents unauthorized production transactions and ensures all implementations undergo proper security review before processing live payments.

## Signature as a Security Fallback

Not all transactions are authorized via PIN. In specific scenarios, the SDK requires capturing a digital signature to finalize the legal validity of the sale.

### When Signature Is Required

If the cardholder did not authenticate via PIN, the transaction response indicates this through the `AutenticadoPorPin` field:

```
func onPaymentFinished(_ result: RespuestaTransaccionDTO!, orError error: Error!) {
    if let transaction = result, transaction.AutenticadoPorPin == false {
        // Signature capture required
        captureCustomerSignature()
    }
}
```

This commonly occurs with:
- **Offline transactions** where PIN verification wasn't possible
- **Specific card types** that don't support PIN authentication
- **International cards** with different authentication requirements

### Submitting the Signature

Your application must capture the customer's digital signature as an image and submit it using the `envioFirmaDigitalizada` method:

```
let signatureDTO = EnvioFirmaDTO(
    withTerminal: terminalDataDTO,
    withFirma: signatureImage,      // UIImage of signature
    Format: 2,                      // 2 = JPEG format
    andOperacion: operationDTO
)

RedsysConfigurationManager.envioFirmaDigitalizada(signatureDTO) { result, error in
    if error == nil {
        // Signature submitted successfully
    }
}
```

<Callout type="warning">

The signature submission is a **mandatory security requirement** to complete transactions where `AutenticadoPorPin == false`. Without the signature, the transaction may not meet legal validity requirements.

</Callout>

## Developer Security Responsibilities

While the SDK handles data encryption, developers must adhere to security best practices as outlined in the **"PRECAUCIÓN"** section (Section 3) of the technical manual.

### Environment Guardrails

**Never use production credentials in test environments:**

- Use `"des"` (Development), `"int"` (Integration), or `"ccal"` (Pre-production) during development and testing
- Only switch to `"real"` (Production) after Get Mini certification approval
- Maintain separate merchant credentials for each environment

### Log Management

**Do not log sensitive transaction data:**

```
// ❌ BAD: Logs entire response object
print("Transaction result: \(result)")

// ✅ GOOD: Logs only non-sensitive fields
print("Transaction completed with status: \(result.status)")
```

Response objects from `onPaymentFinished` contain transaction metadata and authorization codes that should not be stored in:
- Console logs
- System logs
- External analytics services
- Crash reporting tools
- Local files

### Credential Protection

**Protect merchant identifiers:**

FUC (Merchant ID) and Terminal IDs should be:
- **Injected at build time** via build configurations
- **Retrieved from secure remote configuration** at runtime
- **Never hardcoded in cleartext** in source code or version control

```
// ❌ BAD: Hardcoded credentials
let fuc = "999008881"

// ✅ GOOD: Retrieved from secure configuration
let fuc = Configuration.shared.merchantFUC
```

## Next Steps

* [Transaction Lifecycle](/en/get-mini/ios-sdk/core-concepts/ios-lifecycle) - See how security states transition during a sale
* [Configure iOS Permissions](/en/get-mini/ios-sdk/first-steps/configure-ios-permissions) - Ensure your Info.plist is properly configured