# 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. Comprueba `declineCause` y `declineError` para 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
}
```

<Callout type="info">

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`).

</Callout>

## 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 Code
```

### La 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](/es/get-tap-on-phone/reference/response-parameters).  
* Aprende a consultar el estado de una transacción pasada utilizando su UUID en [Consulta de Transacciones Pasadas](/es/get-tap-on-phone/transaction-guides/querying-past-transactions).