Gestión de resultados de transacciones
Una vez que la app Tap on Phone finaliza el procesamiento de un pago, reembolso o cancelación, devuelve el control a tu app. Pasa el resultado de la transacción a través de la API Activity Result de Android.
Esta guía explica cómo analizar el código de resultado, determinar el estado final de la transacción y extraer los datos detallados del recibo.
Paso 1: Comprobar el Activity Result Code
Cuando se activa tu callback registrado de Activity Result, primero debes inspeccionar el resultCode. Este código te indica si la app Tap on Phone ha completado su proceso.
RESULT_OK: El proceso de transacción se completó con éxito y la app Tap on Phone generó un recibo. Nota: Esto no significa que el pago haya sido aprobado; solo significa que el proceso finalizó sin un error fatal del sistema.RESULT_CANCELED: El proceso se abortó antes de que se pudiera generar un recibo. Esto ocurre si el usuario cancela manualmente la operación (por ejemplo, pulsando el botón de retroceso) o si se produce un error antes de que la transacción se conecte online (como un fallo en la lectura de la tarjeta o un timeout de red).
val resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val data = result.data
if (result.resultCode == Activity.RESULT_OK && data != null) {
// The process finished and generated a receipt. Proceed to Step 2.
} else if (result.resultCode == Activity.RESULT_CANCELED) {
// The process was canceled or failed. Proceed to Step 4.
}
}Paso 2: Determinar el estado de la transacción
Cuando recibes RESULT_OK, debes evaluar el extra status para determinar el resultado financiero real de la transacción:
-
APPROVED: La transacción se realizó con éxito. -
DECLINED: La transacción fue rechazada. CompruebadeclineCauseydeclineErrorpara obtener más detalles.
// ... inside your RESULT_OK block
val status = data.getStringExtra("status") ?: "None"
if (status == "APPROVED") {
println("The transaction was approved.")
// Fulfill the order and save the receipt data
} else if (status == "DECLINED") {
val declineCause = data.getStringExtra("declineCause") ?: "Unknown reason"
println("The transaction was declined: $declineCause")
// Prompt the user to try a different payment method
}La app Tap on Phone también devuelve un extra booleano authorized. Este es un campo de conveniencia derivado directamente del campo status (true cuando es APPROVED, false cuando es DECLINED).
Paso 3: Extraer datos del recibo
Para cada transacción completada (RESULT_OK), los datos del intent contienen información detallada sobre el pago. Utiliza estos campos para actualizar tu backend, imprimir recibos físicos o enviar recibos digitales al cliente.
Extrae los datos utilizando los getters de intent estándar de Android:
// Basic Identifiers
val transactionId = data.getIntExtra("transactionId", -1)
val uuid = data.getStringExtra("uuid") ?: "" // Unique receipt ID
// Financial Details
val amount = data.getLongExtra("amount", 0) // Amount in cents
val currency = data.getStringExtra("currency") ?: "" // ISO 4217 code (e.g., "EUR")
val date = data.getStringExtra("date") ?: ""
// Card & EMV Details
val scheme = data.getStringExtra("scheme") ?: "" // e.g., "Visa", "Mastercard"
val pan = data.getStringExtra("pan") ?: "" // Masked PAN (e.g., "************1234")
val aid = data.getStringExtra("aid") ?: "" // Selected EMV Application ID
val applicationLabel = data.getStringExtra("applicationLabel") ?: ""
val authCode = data.getStringExtra("authCode") ?: "" // EMV Authorization CodeLa cadena de recibo formateada
Si deseas mostrar o imprimir un recibo sin formatear manualmente cada campo, la app Tap on Phone proporciona una cadena preformateada.
Extrae el extra formatedString. Esta cadena contiene un diseño de recibo completo y listo para imprimir que incluye el nombre del comercio, la ubicación, el PAN enmascarado, la fecha y los códigos de autorización.
val fullReceiptString = data.getStringExtra("formatedString") ?: "No receipt available"
println(fullReceiptString)Paso 4: Gestionar cancelaciones y errores
Cuando recibes RESULT_CANCELED, debes comprobar si se trata de una simple cancelación del usuario o de un error del sistema.
Si un error provocó la cancelación, la app Tap on Phone incluye los detalles del error en los extras del intent. Si el intent no contiene estos extras, puedes asumir que el usuario canceló manualmente el proceso.
// ... inside your RESULT_CANCELED block
if (data != null && data.hasExtra("errorCode")) {
val errorCode = data.getStringExtra("errorCode") ?: "Unknown"
val errorName = data.getStringExtra("errorName") ?: "Unknown"
val errorMessage = data.getStringExtra("errorMessage") ?: "Unknown"
println("Transaction failed with error [$errorCode]: $errorName - $errorMessage")
// Display the error message to the merchant
} else {
println("The merchant canceled the transaction.")
}Próximos pasos
- Para obtener una lista exhaustiva de todos los campos de datos disponibles devueltos en el intent, consulta la referencia de Parámetros de Respuesta.
- Aprende a consultar el estado de una transacción pasada utilizando su UUID en Consulta de Transacciones Pasadas.