Lectura de tarjetas
ℹ️
Este proceso es obligatorio
En esta fase se procede a la recuperación de datos de la tarjeta mediante la implementación del estándar EMV, haciendo uso del kernel del dispositivo.
Requisitos
- Inyección y configuración de llaves
- Listado de tags EMV
- Monto de la transacción
- Tipo de transacción
- Código de país
- Código de moneda
- Identificador de la adquirencia (Acquirer ID)
Resultado
- Después del proceso de lectura, se obtendrá un objeto con todos los datos de la tarjeta requeridos para procesar operaciones de pago, anulaciones o devoluciones.
Paso a paso
- Instanciar el objeto
CardProcessData
. - Invocar el método
findCardProcess
y pasarle como parámetro:- El objeto
OperationFlow
- Instancia del objeto
CardData()
- El contexto
- El modo de lectura a procesar
- El objeto
- Configurar los observers para recibir el resultado de la lectura.
Instanciar objeto OperationFlow
- Amount: Objeto que contiene información del monto de la transacción en formato ISO. Es decir, los 2 últimos dígitos representan los decimales y no lleva punto decimal. Ejemplo: $10.00 = 1000
- Capture: Objeto que contiene información para la captura de los datos de la tarjeta. Se requiere instanciar los objetos:
- Capture(): Instanciar el objeto así:
operationFlow.capture = Capture()
- Card(): Instanciar el objeto. Así:
operationFlow.capture!!.card = Card()
- Holder(): Instanciar el objeto. Así:
operationFlow.capture!!.card.holder = Holder()
- Identification(): Instanciar el objeto. Así:
operationFlow.capture!!.card.holder.identification = Identification()
- Terminal(): Instanciar el objeto. Así:
operationFlow.terminal = Terminal()
- Capture(): Instanciar el objeto así:
- TransactionType: Tipo de transacción. Este objeto es un enum con los siguientes valores:
enum class OperationType {
PAYMENT,
REFUND,
ANNULMENT,
REVERSE
}
Instanciar objeto CardData
- countryCode: Código ISO de país. Ver Tabla de código de país. Ejemplo:
032
- acquirerId: Código del adquirente. Ver Tabla de adquirencias. Ejemplo:
GPS
- tagList: Lista de
String List<String>
que contiene el listado de tags EMV que se van a recuperar durante la lectura. Este listado depende de cada adquirencia.
Instanciar objeto Amount
-
Breakdown: Listado de desglose de montos. Está compuesta por monto y descripción. Listado de valores:
- OPERATION: si la transacción tiene propina, aquí va el valor base. Si la transacción no tiene propina, aquí va el valor total.
- TIP: (aplica cuando la transacción tiene propina, aquí solo va el valor de la propina).
-
Currency: Código de moneda. Posibles valores:
- ARS = Pesos Argentinos
- MX = Pesos Mexicanos
-
Total: Monto total de la transacción en formato ISO. Ejemplo: $25.50 = 2550
Ejemplo de implementación
val cardProcessData = CardProcessData()
cardProcessData.findCardProcess(
operationFlow = doOperationFlow(amount),
cardData = doCardData(),
context = this,
inputModeType = InputMode.ALL
)
cardProcessData.selectApp.observe(this, selectAppObserver)
cardProcessData.navigate.observe(this, navigateObserver)
private fun doOperationFlow(inputAmount: String): OperationFlow {
operationFlow.amount = Amount()
val breakdownList = Breakdown()
breakdownList.description = OPERATION
breakdownList.amount =
StringUtils.notFormatAmount(inputAmount)
operationFlow.capture = Capture()
operationFlow.capture!!.card = Card()
operationFlow.apply {
amount?.let {
it.total =
StringUtils.notFormatAmount(inputAmount)
it.currency = Currency.ARS.name
it.breakdown = listOf(breakdownList)
}
}
operationFlow.transactionType = OperationType.PAYMENT
//inicializar otros objetos
operationFlow.capture!!.card.holder = Holder()
operationFlow.capture!!.card.holder.identification = Identification()
operationFlow.terminal = Terminal()
OperationFlowHolder.operationFlow = operationFlow
return operationFlow
}
private fun doCardData(): CardData {
return CardData(
countryCode = Country.ARG.code,
acquirerId = Acquirer.GPS.name,
tagList = doTagListTest()
)
}
private val navigateObserver: (Any) -> Unit = {
when (it) {
is Bundle -> {
val status = it.get("status")
val statusResult: StatusResult = status as StatusResult
val intent = Intent(this, CardErrorActivity::class.java)
intent.putExtra("status", statusResult)
startActivity(intent)
}
is String -> {
//Validar BIN
val bundle = Bundle().apply {
putString("bin", it)
}
val intent = Intent(this, CardRulesValidationActivity::class.java).apply {
putExtras(bundle)
}
startActivity(intent)
}
}
}
Listado de TAGs EMV por adquirencia
🇦🇷 Global Processing
- 9F26
- 82
- 9F36
- 9F10
- 9F33
- 95
- 9F37
- 9A
- 9C
- 9F02
- 9F03
- 9F27
- 9F34
- 5F2A
- 9F1A
- 5F25
- 84
- 9F1E
- 9F6E
🇲🇽 Banorte
- 4F
- 50
- 57
- 5A
- 82
- 84
- 8A
- 95
- 9A
- 9B
- 9C
- 5F20
- 5F24
- 5F25
- 5F28
- 5F2A
- 5F30
- 5F34
- 9F02
- 9F03
- 9F07
- 9F09
- 9F0D
- 9F0E
- 9F0F
- 9F10
- 9F12
- 9F15
- 9F1A
- 9F1C
- 9F1E
- 9F21
- 9F26
- 9F27
- 9F33
- 9F34
- 9F35
- 9F36
- 9F37
- 9F39
- 9F41
- 9F53
- 9F6E
Códigos de respuesta
El resultado se recibe mediante el observer navigateObserver
. En la siguiente tabla se muestran los posibles objetos que se pueden recibir como respuesta:
Objeto | Descripción |
---|---|
ReaderStatus | Este objeto se devuelve en caso de fallo durante el proceso de lectura. |
String | Este objeto se devuelve cuando el proceso de lectura es exitoso, retorna el BIN de la tarjeta, los primeros 8 dígitos del número de la tarjeta. |
Objeto ReaderStatus
- type: Campo de tipo MessageType, posibles valores:
- ERROR → El proceso de lectura terminó con errores.
- INFO → Se recomienda mostrar el mensaje informativo en la pantalla de la terminal.
- SUCCESS → El proceso de lectura terminó correctamente.
- code: Campo de tipo ReaderCode, posibles valores:
- SUCCESS → Indica que el proceso interno del kernel se ejecutó sin errores.
- FALLBACK → Indica que la lectura fue fallback.
- ERROR → Indica que el proceso interno del kernel se ejecutó con errores.
- description: Campo de tipo String, contiene una descripción del código de error.
Lista de posibles códigos de error
Código | Descripción |
---|---|
MULT_CARD | Se detectaron varias tarjetas contactless en el lector. |
USE_ICC_CARD | No se detectó el chip de la tarjeta, se permite deslizar la banda. |
NO_EMV_APPS | No se encontró configuración EMV para esta tarjeta, se permite deslizar la banda. |
TIMEOUT_ERROR | Se excedió el tiempo máximo de lectura. |
BAD_SWIPE_ERROR | La banda de la tarjeta está dañada. |