# Consulta de transacciones pasadas

En algunos escenarios, es posible que tu app no reciba el resultado final de la transacción de la app Tap on Phone. Esto puede ocurrir si tu app falla (crash) o si el usuario fuerza el cierre de la app. También es posible que necesites recuperar detalles de transacciones pasadas para rellenar un historial de transacciones o una pantalla de detalles.

Para gestionar estos casos, puedes consultar el estado de una transacción específica enviando un Broadcast de Android que contenga el UUID de la transacción.

## Prerrequisitos 

Antes de poder consultar una transacción pasada, asegúrate de que tienes:

* El `userId`, `userToken` y `merchantId` asociados a la sesión.  
* El `sdkTransactionId` (UUID) de la transacción que deseas comprobar. La app Tap on Phone transmite (broadcasts) este ID al principio del proceso de pago. (Consulta [Procesar una Transacción de Compra](/es/get-tap-on-phone/transaction-guides/process-a-purchase-transaction) para aprender cómo capturar este ID).

<Callout type="warning">

Si estás intentando recuperar el estado inmediatamente después de un intento de pago, espera al menos **5 segundos** (idealmente **10 segundos**) antes de enviar la solicitud de estado. Esto da al backend de Tap on Phone tiempo suficiente para terminar de procesar la transacción.

</Callout>

## Paso 1: Registrar un Broadcast Receiver

Cuando consultas el estado de la transacción, la app Tap on Phone responde de forma asíncrona a través de un broadcast. Debes registrar un `BroadcastReceiver` para capturar esta respuesta.

Por defecto, la app Tap on Phone responde utilizando la acción `com.dejamobile.cbp.sps.TRANSACTION_STATUS_BROADCAST_RESPONSE`.

```
val statusResponseAction = "com.dejamobile.cbp.sps.TRANSACTION_STATUS_BROADCAST_RESPONSE"

val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        // Extract the receipt or failure details
        val receipt = intent?.getStringExtra("Receipt")
        val failure = intent?.getStringExtra("Failure")

        if (receipt != null) {
            println("Got transaction receipt: $receipt")
            // Parse the receipt data to determine the final status (APPROVED/DECLINED)
        } else if (failure != null) {
            println("Transaction status failure: $failure")
            // Handle the failure
        }

        // Unregister the receiver once handled
        context?.unregisterReceiver(this)
    }
}

// Register the receiver
val filter \= IntentFilter(statusResponseAction)
registerReceiver(receiver, filter)
```

<Callout type="info">

Aunque el broadcast de respuesta utiliza las cadenas `Receipt` y `Failure` para agrupar el resultado, el intent también incluye los mismos campos de datos detallados que la respuesta del intent de pago estándar (como `status`, `amount`, `pan`, etc.). Consulta [Gestión de Resultados de Transacciones](/es/get-tap-on-phone/transaction-guides/handle-transaction-results) para obtener detalles sobre cómo analizar estos campos.

</Callout>

## Paso 2: Enviar el Broadcast de solicitud de estado

Una vez que tu `BroadcastReceiver` esté escuchando, construye y envía el intent de broadcast. Debes dirigirte a la clase `TransactionStatusBroadcastReceiver` y pasar las credenciales de sesión obligatorias junto con el `TransactionId`.

```
private fun queryTransactionStatus(transactionUUID: String) {
    val intent = Intent().apply {
        action = "com.dejamobile.cbp.sps.TRANSACTION_STATUS_BROADCAST"
        component = ComponentName(
            "com.dejamobile.cbp.sps.app",
            "com.dejamobile.cbp.sps.app.broadcast.TransactionStatusBroadcastReceiver"
        )
        addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)

        // Session Identifiers
        putExtra("userId", userId)
        putExtra("merchantId", merchantId)
        putExtra("userToken", userToken)

        // The UUID of the transaction to query
        putExtra("TransactionId", transactionUUID)

        // Optional: Specify your custom response action if you don't want to use the default
        // putExtra("ResponseAction", "your.custom.action.name")
    }

    // Send the broadcast
    sendBroadcast(intent)
}
```

## Paso 3: Gestionar errores y reintentos

Si tu `BroadcastReceiver` captura una respuesta que contiene una cadena `Failure` (o si la respuesta indica que la transacción no existe), no asumas inmediatamente que la transacción falló permanentemente.

Los problemas de red o los problemas internos del dispositivo pueden hacer que la recuperación del estado falle ocasionalmente. Sigue esta lógica de reintentos:

1. **Primer Fallo**: Si el broadcast devuelve un error, espera unos segundos y vuelve a intentar el broadcast una vez más.  
2. **Segundo Fallo**: Si se sigue devolviendo un error tras el segundo intento, puedes considerar de forma segura que la transacción ha sido denegada.