API Reference

Instalación

Milio SDK para iOS

Visión General

El SDK de Milio para iOS proporciona una solución sencilla y segura para gestionar pagos y transferencias dentro de tus aplicaciones iOS. Diseñado en SwiftUI, el SDK permite una integración fluida con aplicaciones creadas en SwiftUI o UIKit, garantizando conformidad con estándares como PCI DSS para la seguridad de datos sensibles.


Instalación

Requisitos Previos

Antes de integrar el SDK, asegúrate de tener:

  • Xcode 14.0 o superior.
  • Swift 5.0 o superior.
  • macOS Ventura o superior.

Instalación con CocoaPods

Sigue estos pasos para instalar el SDK usando CocoaPods:

  1. Instalar CocoaPods (si no está instalado):
  • seguir los pasos :
sudo gem install cocoapods
  • Verifica la instalación con:
pod --version
  • Crea un archivo Podfile si no existe:
pod init

Abre el Podfile y agrega (local)

 pod 'sdk-mobile-ios', :git => 'https://bitbucket.org/miliopay/sdk-mobile-ios.git', :tag => '0.0.25'

Si el SDK de Milio se distribuye a través de un repositorio privado de CocoaPods, agrégalo en tu Podfile (ios/Podfile):

# Uncomment the next line to define a global platform for your project
platform :ios, '16.0'

use_frameworks!

target 'projectTestSdk' do
  
 pod 'sdk-mobile-ios', :git => 'https://bitbucket.org/miliopay/sdk-mobile-ios.git', :tag => '0.0.25'
  
end


  • Instala las dependencias:
pod install --repo-update

Nota

Xcode en versiones recientes activa por defecto sandboxing para proteger el entorno de ejecución de scripts. Esto puede bloquear tareas como copiar archivos (rsync, cp, etc.) si el script no tiene los permisos adecuados. Al desactivar la opción ENABLE_USER_SCRIPT_SANDBOXING, le dices a Xcode que permita que tus scripts corran sin esas restricciones extra.

Uso del SDK

🔐 Proceso de Encriptación y Seguridad en el SDK

El sistema de transferencias y recargas del SDK utiliza un mecanismo de encriptación de datos basado en criptografía de clave pública para garantizar la seguridad de la información en cada transacción.

🔑 1. ¿Por qué se usa una llave pública?

La llave pública, generada por un endpoint especializado, es la herramienta que permite cifrar la información antes de enviarla a través del SDK. Al encriptar los datos con esta llave, aseguramos que solo el servidor que tiene la llave privada correspondiente pueda descifrarlos, evitando accesos no autorizados o modificaciones en la información.

📲 2. Procesos que requieren encriptación con la llave pública

Cada una de las transacciones en el SDK debe pasar por este proceso de encriptación antes de ser enviada al servidor:

1️⃣ Transferencia con QR

Se escanea un código QR con los datos de la transacción.
La información se encripta con la llave pública antes de enviarla.
El servidor recibe los datos cifrados y los desencripta con su llave privada.

2️⃣ Transferencia Manual

El usuario ingresa manualmente los datos de la transacción (monto, cuenta destino, etc.).
Antes de enviarlos al SDK, los datos se cifran con la llave pública.
El servidor procesa la información tras desencriptarla.

3️⃣ Transferencia Inmediata

Similar a la transferencia manual, pero con una ejecución más rápida.
La información viaja encriptada con la llave pública para evitar manipulación en el proceso.

4️⃣ Recarga de Billetera

Para recargar fondos en la billetera digital, los datos (monto, origen, destino) se protegen con encriptación.
Solo el servidor, con su llave privada, podrá acceder a la información real y procesar la recarga.

🚀 3. Beneficios de este proceso de seguridad

✅ Protección de datos sensibles en cada transacción.
✅ Evita que terceros accedan o modifiquen la información.
✅ Cumple con estándares de seguridad y auditoría en encriptación.

Cada vez que se realiza una transferencia o recarga en el SDK, los datos deben encriptarse con la llave pública antes de enviarse. Solo el servidor con la llave privada correcta podrá descifrarlos y procesar la transacción, garantizando un entorno seguro y confiable para el usuario. 🔒


  1. Configuración Inicial

    Importa el SDK y configúralo con tu token de autenticación:
import MilioSDK

MilioSDK.configure(withToken: "TU_TOKEN_DE_AUTENTICACIÓN")


Ejemplo de Integración

El SDK facilita la implementación de funcionalidades de transferencia y pago. A continuación, un ejemplo de transferencia por QR.

Ejemplo global de Encriptación

Este método se debe utilizar antes de enviar la información en las siguientes transacciones:

  1. Transferencia por QR
  2. Transferencia manual
  3. Transferencia inmediata
  4. Recarga de billetera

Cada transacción debe encriptar los datos sensibles antes de enviarlos al SDK de Milio.

import Foundation
import Security

// Llave pública proporcionada por Milio (esto es solo un ejemplo, usa la real en producción)
let publicKeyPem = """
-----BEGIN RSA PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7...
-----END RSA PUBLIC KEY-----
"""

/**
 * 🔒 Método para encriptar información con la llave pública de Milio.
 *
 * @param publicKeyPem Llave pública en formato PEM.
 * @param data Información que se desea encriptar.
 * @return Datos encriptados en Base64 o nil en caso de error.
 */
func encryptWithPublicKey(publicKeyPem: String, data: String) -> String? {
    guard let publicKey = getPublicKey(from: publicKeyPem) else {
        print("❌ Error: No se pudo obtener la llave pública.")
        return nil
    }
    
    guard let dataToEncrypt = data.data(using: .utf8) else {
        print("❌ Error: No se pudo convertir la data a formato UTF-8.")
        return nil
    }
    
    let bufferSize = SecKeyGetBlockSize(publicKey)
    var encryptedData = Data(count: bufferSize)
    
    var encryptedLength = bufferSize
    let status = encryptedData.withUnsafeMutableBytes { encryptedBytes in
        dataToEncrypt.withUnsafeBytes { plainTextBytes in
            SecKeyEncrypt(publicKey,
                          .oaep,
                          plainTextBytes.baseAddress!,
                          dataToEncrypt.count,
                          encryptedBytes.baseAddress!,
                          &encryptedLength)
        }
    }
    
    guard status == errSecSuccess else {
        print("❌ Error en el cifrado RSA: \(status)")
        return nil
    }
    
    encryptedData.count = encryptedLength
    return encryptedData.base64EncodedString()
}

/**
 * 🔑 Convierte una clave pública en formato PEM a un objeto SecKey.
 */
func getPublicKey(from pemString: String) -> SecKey? {
    let keyString = pemString
        .replacingOccurrences(of: "-----BEGIN RSA PUBLIC KEY-----", with: "")
        .replacingOccurrences(of: "-----END RSA PUBLIC KEY-----", with: "")
        .replacingOccurrences(of: "\n", with: "")
    
    guard let keyData = Data(base64Encoded: keyString) else {
        print("❌ Error: No se pudo convertir la llave pública en Base64.")
        return nil
    }
    
    let options: [String: Any] = [
        kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
        kSecAttrKeyClass as String: kSecAttrKeyClassPublic,
        kSecAttrKeySizeInBits as String: 2048
    ]
    
    return SecKeyCreateWithData(keyData as CFData, options as CFDictionary, nil)
}


Transferencia con QR

import MilioSDK
import Security
import SwiftUI

struct ContentView: View {
  var body: some View {
    VStack(spacing: 16) {
      // Botón: Transferencia con QR
      ActionButton(
        title: "Transferencia con QR",
        iconName: "svg_ic_qrcode",
        iconBackgroundColor: Color(.systemGray6),
        iconColor: .blue,
        horizontalPadding: 24,
        verticalPadding: 18
      ) {
        let transactionData = """
          {
              "amount": 2000.0
          }
          """
        if let encryptedData = encryptWithPublicKey(
          publicKeyPem: PUBLIC_KEY_PEM, data: transactionData)
        {
          MilioSDK.shared.openWindow(
            windowType: .transferQRCode,
            token: authToken,
            value: encryptedData,
            presentingViewController: UIApplication.shared.windows.first?.rootViewController
              ?? UIViewController()
          )
        } else {
          print("❌ Error al encriptar la información")
        }
      }

    }
    .padding()
  }
}

Grafico

Transferencia manual

import MilioSDK
import Security
import SwiftUI

struct ContentView: View {
  var body: some View {
    VStack(spacing: 16) {

      // Botón: Transferencia Manual
      ActionButton(
        title: "Transferencia Manual",
        iconName: "svg_ic_transfer",
        iconBackgroundColor: Color(.systemGray6),
        iconColor: .green,
        horizontalPadding: 24,
        verticalPadding: 18
      ) {
        let transactionData = """
          {
              "amount": 1500.0,
              "type": "OUT",
              "thirdBankUUID": "dfb56715-ed55-4839-b5d0-18645da02dd0"
          }
          """
        if let encryptedData = encryptWithPublicKey(
          publicKeyPem: PUBLIC_KEY_PEM, data: transactionData)
        {
          MilioSDK.shared.openWindow(
            windowType: .manualTransfer,
            token: authToken,
            value: encryptedData,
            presentingViewController: UIApplication.shared.windows.first?.rootViewController
              ?? UIViewController()
          )
        } else {
          print("❌ Error al encriptar la información")
        }
      }

    }
    .padding()
  }
}


Grafico

Transferencia inmediata

import MilioSDK
import Security
import SwiftUI

struct ContentView: View {
  var body: some View {
    VStack(spacing: 16) {

      // Botón: Transferencia Inmediata
      ActionButton(
        title: "Transferencia Inmediata",
        iconName: "svg_ic_flash",
        iconBackgroundColor: Color(.systemGray6),
        iconColor: .red,
        horizontalPadding: 24,
        verticalPadding: 18
      ) {
        let transactionData = """
          {
              "amount": 1500.0,
              "type": "OUT",
              "thirdBankUUID": "dfb56715-ed55-4839-b5d0-18645da02dd0"
          }
          """
        if let encryptedData = encryptWithPublicKey(
          publicKeyPem: PUBLIC_KEY_PEM, data: transactionData)
        {
          MilioSDK.shared.openWindow(
            windowType: .instantTransfer,
            token: authToken,
            value: encryptedData,
            presentingViewController: UIApplication.shared.windows.first?.rootViewController
              ?? UIViewController()
          )
        } else {
          print("❌ Error al encriptar la información")
        }
      }

    }
    .padding()
  }
}

Grafico

Transferencia inmediata (Tarjeta manual)

Grafico

Recarga de billetera

import MilioSDK
import Security
import SwiftUI

struct ContentView: View {
  var body: some View {
    VStack(spacing: 16) {

      // Botón: Recarga de Billetera
      ActionButton(
        title: "Recargar Billetera",
        iconName: "svg_ic_wallet",
        iconBackgroundColor: Color(.systemGray6),
        iconColor: .orange,
        horizontalPadding: 24,
        verticalPadding: 18
      ) {
        let transactionData = """
          {
              "amount": 1500.0,
              "type": "IN",
              "thirdBankUUID": "dfb56715-ed55-4839-b5d0-18645da02dd0"
          }
          """
        if let encryptedData = encryptWithPublicKey(
          publicKeyPem: PUBLIC_KEY_PEM, data: transactionData)
        {
          MilioSDK.shared.openWindow(
            windowType: .walletRecharge,
            token: authToken,
            value: encryptedData,
            presentingViewController: UIApplication.shared.windows.first?.rootViewController
              ?? UIViewController()
          )
        } else {
          print("❌ Error al encriptar la información")
        }
      }
    }
    .padding()
  }
}



Conclusión

Milio SDK ofrece una arquitectura robusta y flexible para manejar diversos tipos de transferencias y recargas. Los puntos clave incluyen:

  • Escalabilidad: Los flujos se adaptan tanto a usuarios que prefieren métodos manuales como a aquellos que buscan la comodidad de los códigos QR.
  • Interoperabilidad: La lógica permite integrar diferentes procesos dentro de un solo SDK, mejorando la experiencia del usuario final.
  • Seguridad: Se prioriza la validación mediante tokens y datos encriptados, alineándose con los estándares de la industria como PCI DSS.
  • Flexibilidad: El diseño modular permite personalizar los flujos según las necesidades de la aplicación.

Este SDK es una herramienta clave para facilitar las operaciones financieras digitales en un entorno moderno, garantizando una experiencia fluida y segura tanto para los desarrolladores como para los usuarios finales.