Getnet DocsGetnet Docs

Process a Refund or Cancellation

This guide explains how to initiate a refund or cancel an existing payment transaction using the Tap on Phone application. Both operations require the original transaction ID and use a similar Intent structure to standard purchases.

Understanding Refunds vs. Cancellations

While both operations return funds to the customer, they have different use cases and restrictions:

  • Cancellation: Reverses a transaction. The transaction must be valid, approved, and not already refunded or cancelled. The user logged into the app must have administrator access.
  • Refund: Returns funds to the customer after the transaction is fully processed. The transaction must be valid, approved, and not already refunded or cancelled. The user logged into your application must have administrator access to perform a refund.

Prerequisites

Before you process a refund or cancellation, ensure you have:

  • An initialized Tap on Phone application.
  • The userId, userToken, and merchantId associated with the current session.
  • The transactionId (from the Tap on Phone system) of the original approved payment.
  • Configured your backend to handle Single Sign-On (SSO) refund authorization requests (see Backend Integration: Handling SSO Requests).

Step 1: Register the Activity Result Launcher

Register an Activity Result callback to handle the outcome of the refund or cancellation process.

val modificationResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    val data = result.data

    if (result.resultCode == Activity.RESULT_OK && data != null) {
        val status = data.getStringExtra("status") ?: "None"

        if (status == "APPROVED") {
            println("Transaction successfully modified (Refunded/Canceled).")
            // Extract receipt data for the refund/cancellation
        } else {
            val declineCause = data.getStringExtra("declineCause") ?: "Unknown"
            println("Modification declined: $declineCause")
        }
    } else if (result.resultCode == Activity.RESULT_CANCELED) {
        val errorCode = data?.getStringExtra("errorCode") ?: "None"
        val errorMessage = data?.getStringExtra("errorMessage") ?: "User Canceled"
        println("Operation failed or was canceled: $errorMessage ($errorCode)")
    }
}

Step 2: Prepare the SSO Metadata

Because refunds are sensitive operations, the Tap on Phone backend validates them against your backend using SSO. You must pass your Client ID in the operationMetadata field so the platform can route the authorization request properly.

// Format your Client ID as a JSON string
val operationMetadata = "{\"ClientID\\":\"your-client-id-here\"}"

Step 3: Construct and Launch the Intent

Create an explicit intent targeting the POSActivity in the Tap on Phone application.

You must specify the transactionType (either REFUND or CANCEL) and provide the identifier of the transaction you wish to modify in the originalTransaction field.

private fun performRefundOrCancel(originalTransactionId: Int, isRefund: Boolean) {
    val intent = Intent().apply {
        setClassName(
            "com.dejamobile.cbp.sps.app",
            "com.dejamobile.cbp.sps.app.POSActivity"
        )

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

        // Specify the type: "REFUND" or "CANCEL"
        val type = if (isRefund) "REFUND" else "CANCEL"
        putExtra("transactionType", type)

        // Pass the ID of the transaction to modify
        putExtra("originalTransaction", originalTransactionId)

        // Required for SSO authorization
        putExtra("operationMetadata", operationMetadata)
    }

    // Launch the intent
    modificationResultLauncher.launch(intent)
}

Step 4: Handle the Result

Once you launch the intent, the Tap on Phone application takes over. For a refund, the merchant may be prompted to present the original payment card.

When the operation concludes, your modificationResultLauncher callback executes. Inspect the status field to verify the refund or cancellation was approved, and update your internal order records accordingly.

Next Steps