Introducción

El SDK de Clip para iOS permite integrar la experiencia de pago de Clip en tu aplicación nativa de iOS.

El SDK para iOS permite que los desarrolladores puedan crear aplicaciones personalizadas de venta y tomar los pagos utilizando los beneficios que ya ofrece la plataforma de Clip, como el cumplimiento con los estándares PCI y compatibilidad con tarjetas de débito, crédito y otras.

La integración con dispositivos iOS extiende su uso a dispositivos móviles como celulares y tabletas, ofreciendo versatilidad en la experiencia del usuario.

Las características que ofrece la integración del lector Clip con tu aplicación son:

  • Conectividad con Clip Plus y Clip Plus 2
  • Flujos de inicio y cierre de sesión
  • Métodos de pago por medio de banda magnética, tarjetas con chip y contactless
  • Propinas y pagos diferidos en mensualidades
  • Historial de transacciones
  • Personalización del número de referencia del pago

Cómo funciona

El SDK de Clip es una librería que extiende las capacidades de tu aplicación de punto de venta.

Las funciones que permite desarrollar la librería son:

  • Aceptar pagos con tarjeta
  • Obtener el historial de transacciones
  • Iniciar y cerrar la sesión de Clip desde tu aplicación
  • Configurar los ajustes del dispositivo (Settings)

Integración con iOS

Para integrar la librería de Clip, sólo es necesario importarla en tu proyecto de iOS como parte de las dependencias.

El SDK de Clip te ofrece un proyecto demo para integrar el SDK a tu aplicación y poder analizar ejemplos de código para integrar la solución personalizada a tu propia aplicación móvil de iOS.

El SDK de Clip para iOS soporta la integración con aplicaciones desarrolladas en Swift y Objective-C.

Prerrequisitos

Para poder integrar el SDK de Clip a tu aplicación de iOS, debes cumplir los siguientes prerrequisitos:

  • Tener una cuenta de Clip
  • Tener una aplicación iOS con versión mínima iOS 10 o superior
  • Agregar las librerías del SDK como dependencias en el proyecto de iOS
  • Configurar los permisos del dispositivo requeridos por el SDK
  • Utilizar Carthage versión 0.38

Ambientes de desarrollo

NOTA: Por el momento no existe un ambiente “sandbox” para pruebas y sólo está disponible el ambiente de producción.

Configuración del proyecto

Es necesario configurar los ajustes iniciales en tu proyecto para poder integrar tu solución con las librerías del SDK de Clip.

Agregando las librerías

Es necesario agregar las librerías para el SDK de Clip como dependencias de tu proyecto de iOS.

  • Librerías de Clip: las librerías de Clip se proporcionan con los archivos del proyecto SDK y se integran de forma directa.
  • Librerías externas: las librerías de terceros están disponibles por medio de Carthage, una herramienta diseñada para manejar dependencias.

Librerías de Clip

  1. Abre con Xcode el proyecto de tu aplicación iOS para el SDK de Clip.
  2. Selecciona tu proyecto de la lista Target en la parte superior izquierda.
  3. Dirígete a la sección Linked Frameworks and Libraries en la pestaña General de tu proyecto.
  4. Agrega los siguientes archivos con extensión .framework:
ClipAuthenticationSDK.framework
ClipCommonSDK.framework
ClipPaymentSDK.framework
ClipPaymentUISDK.framework
ClipReaderSDK.framework

Librerías externas

Para poder integrar las librerías externas, es necesario utilizar el manejador de dependencias Carthage.

Los siguientes pasos muestran cómo implementar las librerías con Carthage:

  1. Instala Carthage siguiendo la referencia de la documentación oficial. https://github.com/Carthage/Carthage#quick-start

  2. Incluye las siguientes dependencias en el Cartfile:

github "JohnSundell/Wrap" "3.0.1"
github "evsinev/BerTlv" "0.2.3"
github "SnapKit/SnapKit" ~> 5.0.0
github "lyft/mapper"
github "airbnb/lottie-ios" "master"
  1. Agrega los framework generados por Carthage en la configuración de tu proyecto.

Configurando Info

Esta sección contiene información relacionada a configuraciones en la pestaña de Info en tu proyecto.

En la sección de Localizations, agrega soporte para idioma Español.

Configurando Build Phases

Esta sección contiene información relacionada a configuraciones en la pestaña de Build Phases en el Target de tu proyecto.

Agrega el siguiente Run Script .

/usr/local/bin/carthage copy-frameworks

Agrega el siguiente Input File, reemplazando Project_Name por el nombre de tu proyecto.

$(SRCROOT)/Carthage/Build/iOS/*Project_Name*.framework

Configurando los permisos en info.plist

Para poder integrar el SDK de Clip en tu aplicación de iOS, es necesario incluir las siguientes propiedades dentro de tu archivo info.plist para el dispositivo que utilizará la aplicación.

Configura tu info.plist con los siguientes permisos:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>Clip uses your device's bluetooth to connect to card readers</string>

<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs to use bluetooth to communicate with the Clip Reader</string>

<key>NSLocationUsageDescription</key>
<string>This app needs to know your location in order to charge payments</string>

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs to know your location in order to charge payments</string>

La tabla siguiente incluye una descripción para cada uno de los permisos requeridos:

Permiso

Funcionalidad

Descripción

NSBluetoothAlwaysUsageDescription

Bluetooth

Para descubrir y emparejar nuevos dispositivos desde la aplicación iOS.

NSBluetoothPeripheralUsageDescription

Bluetooth

Para conectarse con la terminal de Clip.

NSLocationUsageDescription

Ubicación

Para poder tomar y procesar el pago.

NSLocationWhenInUseUsageDescription

Ubicación

Para poder tomar y procesar el pago.

En el mismo archivo, agrega las siguientes configuraciones para asegurar la compatibilidad de tu aplicación con el SDK de Clip:

<key>UIUserInterfaceStyle</key>
    <string>Light</string>

<key>UISupportedInterfaceOrientations</key>
    <array>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    </array>

<key>UISupportedInterfaceOrientations~ipad</key>
    <array>
    <string>UIInterfaceOrientationLandscapeLeft</string>
    <string>UIInterfaceOrientationLandscapeRight</string>
    <string>UIInterfaceOrientationPortrait</string>
    <string>UIInterfaceOrientationPortraitUpsideDown</string>
    </array>

<key>CFBundleLocalizations</key>
    <array>
       <string>en</string>
       <string>es</string>
    </array>

La tabla siguiente incluye una descripción para cada una de las configuraciones requeridas:

Configuración

Descripción

UIUserInterfaceStyle

Compatibilidad de la interfaz para temas claros (light theme).

El SDK sólo es compatible con un tema claro para tu aplicación. Si se utiliza un tema oscuro algunos elementos pueden no mostrarse correctamente.

UISupportedInterfaceOrientations

Compatibilidad con la orientación de la aplicación para iPhone con soporte para retrato y panorama.

UISupportedInterfaceOrientations~ipad

Compatibilidad con la orientación de la aplicación para iPad con soporte para retrato y panorama.

CFBundleLocalizations

Compatibilidad con idiomas español e inglés.

Trabajando con el proyecto demo

Clip SDK para iOS te ofrece un proyecto demo para integrar el SDK a tu aplicación y contiene ejemplos de uso de las funciones de la librería.

Las funciones que permite desarrollar la librería son:

  • Crear un objeto de pago
  • Inicio y cierre de sesión de Clip desde tu aplicación

Código de ejemplo

El siguiente bloque de código muestra un ejemplo del ViewController de la implementación del SDK de Clip en una aplicación de iOS.

Las secciones siguientes, contienen descripciones detalladas de los componentes más importantes de este ejemplo.

//
//  ViewController.swift
//  ExampleSDKClipCarthage
//
//  Created by MiguelJasso on 15/09/20.
//  Copyright © 2020 MiguelJasso. All rights reserved.
//
 
import UIKit
 
import ClipCommonSDK
import ClipPaymentUISDK
import ClipAuthenticationSDK
import ClipPaymentSDK
 
class ViewController: UIViewController{
    
    var sdk: ClipAuthentication! = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        sdk = ClipSDKModule.createClipSDKModule(delegate: self)
 
        // Do any additional setup after loading the view.
    }
    
    @IBAction func login(_ sender: Any) {
           sdk.login()
       }
       
    @IBAction func logout(_ sender: Any) {
           sdk.logout()
       }
}
 
 
extension ViewController : ClipAuthenticationDelegate {
    func didLLoginSDKProtocologinSuccess() {

        let payWrapper = PaymentProcessManager()
            .set(amount: NSDecimalNumber(value: ))
                    .set(baseView: )
                    .set(tips:  )
                    .set(contaclessEnabled: )
                    .set(delegate: )
                    .set(payWithPoints: )
                    payWrapper.startPayment()
    }
    
    func didFailLoginWith(error: StatusCode) {
        
    }
    
    func didLogout() {
        
    }
    
    func didFailLogout(error: StatusCode) {
        
    }
 
}
 
extension ViewController: PaymentProcessDelegate {
    func onErrorOcurred(_ error: StatusCode, _ subStatusDetail: SubStatusDetail?) {
        
    }
    
    func successTransaction(_ payment: Payment) {
        
    }
    
}

Inicializando la aplicación

Agrega las librerías importadas anteriormente a tu aplicación.

import UIKit

import ClipCommonSDK
import ClipPaymentUISDK
import ClipAuthenticationSDK
import ClipPaymentSDK

Crea una instancia de ClipAuthentication para iniciar sesión y hacer uso del token de autenticación.

var sdk: ClipAuthentication! = nil

👍

Mira cómo hacerlo

Consulta la receta con los pasos necesarios para configurar el SDK en tu proyecto.



Iniciar la sesión de Clip

Desde tu aplicación, puedes iniciar la sesión de Clip en tu aplicación.

Para iniciar la sesión de Clip desde la aplicación, implementa la siguiente función:

sdk.login()

Esta función también permite validar si ya existe una sesión abierta de Clip para continuar recibiendo pagos. Es importante validar el estado de tu sesión de Clip antes de iniciar una transacción, de lo contrario se regresará un código de error.

Cerrar la sesión de Clip

Desde tu aplicación, puedes solicitar cerrar la sesión de Clip en tu aplicación.

Para cerrar la sesión de Clip desde la aplicación, implementa la siguiente función:

sdk.logout()

Configurar los ajustes del dispositivo

La librería de Clip permite configurar ciertos ajustes del dispositivo Clip desde tu aplicación de iOS.

Actualmente, los ajustes de configuración que se pueden consultar son:

  • Batería: muestra el nivel de batería en el dispositivo Clip.
  • Firmware: muestra la versión de firmware instalada en el dispositivo Clip.
  • Tiempo de apagado: permite configurar el tiempo de apagado automático en tu Clip Plus 2 para ahorrar batería.
  • Sesión de Clip: la pantalla de ajustes permite cerrar sesión en la cuenta Clip.
  • Lector conectado: permite conectar o desconectar un lector Clip por medio de conexión Bluetooth.

📘

Nota

La configuración de Tiempo de apagado solo está disponible para el dispositivo Clip Plus 2.

Para agregar la función de configuración de ajustes en tu aplicación iOS, agrega la siguiente función :

Settings.presentView(self, logoutEnabled: logoutSwitch.isOn)

La siguiente tabla incluye una descripción para los parámetros de la función:

Elemento

Descripción

presentView

Permite mostrar la pantalla de ajustes del dispositivo.

logoutEnabled

Permite cerrar la sesión de la cuenta Clip desde la aplicación iOS y mostrar un botón para la acción.
Posibles valores:

  • logoutSwitch: true
  • logoutSwitch: false

Crear un objeto de Pago

Para integrar la función de pago con Clip, se requiere:

  • Crear un objeto de pago en la aplicación
  • Agregar un botón o elemento gráfico de pago en tu aplicación

Para crear un objeto de pago, implementa la siguiente función dentro del estado de login didLLoginSDKProtocologinSuccess():

let payWrapper = PaymentProcessManager()
     .set(amount: NSDecimalNumber(value: ))
     .set(baseview: )
     .set(tips: )
     .set(contactlessEnabled: )
     .set(delegate: )
     .set(payWithPoints: )
     .set(reference: )
     payWrapper.startPayment()

La siguiente tabla describe los elementos del objeto PaymentProcessManager:

Elemento

Tipo de Dato

Descripción

amount

 NSDecimalNumber

Cantidad de la transacción.

baseView

ViewController

Clase base que presenta las vistas que se utilizan en la aplicación.

tips

Boolean

Permite mostrar la pantalla de selección de propina en el flujo de pago. Se modifica con las propiedades noTip  o enabled .

.noTip

Propinas desactivadas.

.enabled

Propinas activadas. Tiene propiedades adicionales para calcular con o sin centavos.

.roundUp

Redondea la cantidad de propina.

.exact

Propinas exactas con pesos y centavos.

contactlessEnabled

Boolean

Permite recibir pagos contactless en terminales Clip Plus 2.

delegate

Clase

Clase que recibe los errores y status del proceso de la transacción.

payWithPoints

Boolean

Permite recibir pagos con los puntos que otorga el banco al usuario de la tarjeta.

reference

String

Referencia personalizada proporcionada por el cliente.

Longitud: 100 caracteres

Validación: cadena alfanumérica y los siguientes caracteres especiales @ # $ & ( ) _ - , .

Iniciar una transacción

En el listener del botón de pago de tu aplicación, agrega la siguiente función:

.startPayment()

Implementar la clase Delegate

Después de crear un objeto de pago, se requiere implementar un Delegate para poder manejar el estado de éxito o error que resulta de la transacción.

Crea una extensión de la clase PaymentProcessDelegate:

Extension PrincipalViewController: PaymentProcessDelegate{

     func onErrorOcurred(_ error: StatusCode, _ subStatusDetail: SubStatusDetail?){

     }

     func successTransaction(_ payment: Payment) {

     }

}

La siguiente tabla muestra una descripción de las funciones contenidas en la clase PaymentProcessDelegate:

Elemento

Descripción

onErrorOcurred

Regresa un error de tipo StatusCode. Algunos errores incluyen una descripción adicional subStatusDetail .

successTransaction

Regresa un objeto tipo Payment con la información del pago que se realizó.

Esquema del objeto Payment:

ClipTransaction {
   var totalAmount: Decimal
   let cardType: CardType
   let currency: String?
   let paymentDate: Date
   let invoiceNumber: String?
   let last4: String
   let latitude: String?
   let longitude: String?
   let receiptNumber: String
   let installment: Installment?
   let amount: Decimal
   let tip: Decimal?
   let status: TransactionStatus
}

La siguiente tabla incluye una descripción para los parámetros del objeto tipo Payment:

Elemento

Descripción

Tipo de dato

receiptNumber

Identificador único de la transacción

String

amount

Cantidad del pago

Decimal

tip

Cantidad de la propina

Decimal

totalAmount

Cantidad total del pago incluyendo propina

Decimal

cardType

Tipo de tarjeta utilizada para el pago:

CardType  

  • .amex
  • .discover
  • .jcb
  • .mastercard
  • .visa
  • .sivale
  • .edenred
  • .carnet
  • .privateCard
  • .electron
  • .sodexo
  • .unknown

Enum

last4

Últimos cuatro dígitos de la tarjeta utilizada para el pago

String

installment

Indica si el pago se difiere en mensualidades:

Installment

  • .ThreeMonth
  • .SixMonth
  • .NineMonth
  • .TwelveMonth
  • .PayInFull

Enum

merchantInvoiceId

Referencia alfanumérica proporcionada por el vendedor

String

status

Estado de la transacción.

Lista de posibles estados de la transacción:

TransactionStatus

  • .Paid
  • .Refunded
  • .Cancelled
  • .Declined
  • .Error

Enum

currency

Código de divisa para la transacción del pago conforme a ISO 4217

String

paymentDate

Fecha de creación del pago

Date

latitude

Coordenada de latitud para la ubicación de la transacción

String

longitude

Coordenada de longitud para la ubicación de la transacción

String

👍

Mira cómo hacerlo

Consulta la receta con los pasos necesarios para recibir un pago con tarjeta en tu proyecto.



Obtener el historial de transacciones

El SDK de Clip permite obtener el historial de transacciones que se han realizado.

Las funciones disponibles para trabajar con el historial son las siguientes:

  • getTransactionHistory(by: TransactionHistoryQuery): permite realizar una búsqueda de transacciones del mismo día y aplicar distintos filtros.
do {
    try TransactionHistory.shared.getTransactionHistory(by:.date(Date()) { (result) in
                switch result {
                case .success(let transactions):
                case .failure(let error):
                }

    catch {
        print(error)
}

Elemento

Tipo de Dato

Descripción

TransactionHistoryQuery

 Enum

Tipo de búsqueda

.card(last4: String)

Últimos 4 dígitos de la tarjeta.

Se valida que el parámetro tenga el siguiente formato: "^\\d{0,4}$"

De no cumplir con el formato se regresa un error de tipo: InvalidParameterFormat

.date(Foundation.Date)

Fecha en que se realizó el pago.

.receipt(receiptNum: String)

Número de evoucher generado por Clip.

Se valida que el parámetro tenga el siguiente formato: "^[a-zA-Z0-9-_]{0,}$"

De no cumplir con el formato se regresa un error de tipo: InvalidParameterFormat

La siguiente tabla muestra los elementos en el objeto de respuesta ClipTransaction que regresan las funciones anteriores:

Elemento

Descripción

Tipo de dato

receiptNumber

Identificador único de la transacción

String

amount

Cantidad del pago

Decimal

tip

Cantidad de la propina

Decimal

totalAmount

Cantidad total del pago incluyendo propina

Decimal

cardType

Tipo de tarjeta utilizada para el pago:

CardType  

  • .amex
  • .discover
  • .jcb
  • .mastercard
  • .visa
  • .sivale
  • .edenred
  • .carnet
  • .privateCard
  • .electron
  • .sodexo
  • .unknown

Enum

last4

Últimos cuatro dígitos de la tarjeta utilizada para el pago

String

installment

Indica si el pago se difiere en mensualidades:

Installment

  • .ThreeMonth
  • .SixMonth
  • .NineMonth
  • .TwelveMonth
  • .PayInFull

Enum

merchantInvoiceId

Referencia alfanumérica proporcionada por el vendedor

String

status

Estado de la transacción.

Lista de posibles estados de la transacción:

TransactionStatus

  • .Paid
  • .Refunded
  • .Cancelled
  • .Declined
  • .Error

Enum

currency

Código de divisa para la transacción del pago conforme a ISO 4217

String

paymentDate

Fecha de creación del pago

Date

latitude

Coordenada de latitud para la ubicación de la transacción

String

longitude

Coordenada de longitud para la ubicación de la transacción

String

Refund Transaction

Una transacción se puede reembolsar al enviar el id (String) del evoucher.

Si una transacción ya fue reembolsada o existe algún error en el proceso, se regresa el error 13002:
PAYMENT_HISTORY_REFUND_FAILED

El método regresa un success con dos posibles estados:

  • True: indica que el reembolso fue exitoso
  • False: indica que el reembolso no fue exitoso

También se retorna el estado de la transacción del tipo PaymentCancelStatus, esta puede ser:

enum PaymentCancelStatus: Int{
    case processed = 1
    case refundUnavailable = -2
    case error = -3
    case timeout = -4
}

Estado

Descripción

processed

La cancelación se realizó de forma exitosa.

refundUnavailable

La cancelación no pudo realizarse. El tiempo para hacerlo ha pasado o se trata de un pago hecho con una tarjeta de puntos.

error

Ocurrió un error al realizar la cancelación.

timeout

Se solicitó la cancelación pero no hubo respuesta del servicio.

El siguiente ejemplo de código muestra la implementación de la función para reembolso de transacción.

do {
            try TransactionHistory.shared.refundTransaction(by:  String , completion: { (result) in
                switch result {
                case .success(let success, let status):
                    print(success)
    print(status)
                case .failure(let error):
    print(error)
                }
            })
        } catch {
    print(error)
        }