# Handle Transaction Results

After the Tap on Phone application finishes processing a payment, refund, or cancellation, it returns control to your application. It passes the transaction outcome through the Android Activity Result API.

This guide explains how to parse the result code, determine the final status of the transaction, and extract the detailed receipt data.

## Step 1: Check the Activity Result Code

When your registered Activity Result callback triggers, you must first inspect the `resultCode`. This code tells you if the Tap on Phone application completed its process.

* `RESULT_OK`: The transaction process completed successfully, and the Tap on Phone app generated a receipt. **Note:** This does not mean the payment was approved; it only means the process finished without a fatal system error.  
* `RESULT_CANCELED`: The process aborted before a receipt could be generated. This happens if the user manually cancels the operation (for example, by pressing the back button) or if an error occurs before the transaction goes online (such as a card reading failure or network timeout).

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

## Step 2: Determine the Transaction Status

When you receive `RESULT_OK`, you must evaluate the `status` extra to determine the actual financial outcome of the transaction:

* `APPROVED`: The transaction was successful.

* `DECLINED`: The transaction was rejected. Check `declineCause` and `declineError` for details.

```
// ... 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">

The Tap on Phone app also returns an `authorized` boolean extra. This is a convenience field derived directly from the `status` field (`true` when `APPROVED`, `false` when `DECLINED`).

</Callout>

## Step 3: Extract Receipt Data

For every completed transaction (`RESULT_OK`), the intent data contains detailed information about the payment. You use these fields to update your backend, print physical receipts, or send digital receipts to the customer.

Extract the data using standard Android intent getters:

```
// 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
```

### The Formatted Receipt String

If you want to display or print a receipt without manually formatting each field, the Tap on Phone application provides a pre-formatted string.

Extract the `formatedString` extra. This string contains a complete, ready-to-print receipt layout that includes the merchant name, location, masked PAN, date, and authorization codes.

```
val fullReceiptString = data.getStringExtra("formatedString") ?: "No receipt available"
println(fullReceiptString)
```

## Step 4: Handle Cancellations and Errors

When you receive `RESULT_CANCELED`, you must check if it was a simple user cancellation or a system error.

If an error caused the cancellation, the Tap on Phone app includes error details in the intent extras. If the intent does not contain these extras, you can assume the user manually canceled the process.

```
// ... 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.")
}
```

## Next Steps

* For an exhaustive list of all available data fields returned in the intent, consult the [Response Parameters](/en/get-tap-on-phone/reference/response-parameters) reference.  
* Learn how to query the status of a past transaction using its UUID in [Querying Past Transactions](/en/get-tap-on-phone/transaction-guides/querying-past-transactions).