Getnet DocsGetnet Docs

Refund a Payment

This guide details how to implement refund operations using the RefundRepository. Refunds allow you to return funds to a customer’s card, either linked to a previous transaction or as a standalone operation.

Before performing any refund, ensure you have initialized the TPV.

Refund Methods

The RefundRepository supports three distinct refund workflows:

1. Standard Refund (By ID)

Use this method when you have the original transaction identifier (operationId) and want to refund a specific amount against it. This is the most common scenario.

Function: makeRefund

Parameters:

  • operationId: The unique identifier of the original sale.
  • amount: The Money object representing the amount to refund.
  • proprietaryExtraData (Optional): Third-party data.
  • language (Optional): Language for the service UI.

Example:

suspend fun refundTransaction(originalId: String, amount: Money) {
    val result = refundRepository.makeRefund(
        operationId = originalId,
        amount = amount
    )
    handleRefundResult(result)
}

2. Refund with Card Reading

Use this method when you have the original operationId but want to force the customer to present their card again (e.g., for security or compliance reasons).

Function: makeRefundReadingCard

Parameters: Same as Standard Refund.

Example:

suspend fun refundWithCardCheck(originalId: String, amount: Money) {
    val result = refundRepository.makeRefundReadingCard(
        operationId = originalId,
        amount = amount
    )
    handleRefundResult(result)
}

3. Refund Without Original

Use this method to issue a refund without linking it to a previous transaction. This functionality typically requires specific configuration (noOriginal flag) to be enabled on the TPV.

Function: makeRefundWithoutOriginal

Parameters:

  • amount: The Money object representing the amount to refund.
  • proprietaryExtraData (Optional): Third-party data.
  • language (Optional): Language for the service UI.

Example:

suspend fun adhocRefund(amount: Money) {
    val result = refundRepository.makeRefundWithoutOriginal(
        amount = amount
    )
    handleRefundResult(result)
}

Interpreting the RefundResult

When the repository call is successful (RepositoryResult.Success), it returns a RefundResult sealed interface. You must handle the following states:

1. Accepted (RefundResult.Accepted)

The refund was authorized by the host.

  • Data: Contains a Transaction object with details of the refund operation.
  • Action: Print the refund receipt and confirm success to the user.

2. Denied (RefundResult.Denied)

The refund was rejected.

  • Data: Contains a Transaction object, potentially with a rejection reason.
  • Action: Inform the user the refund was declined.

3. Exceeded Amount (RefundResult.ExceededAmount)

Specific error indicating the requested refund amount is greater than the original transaction amount (or the remaining refundable balance).

  • Action: Show an error indicating the amount is too high.

Example Handling Logic

fun handleRefundResult(result: RepositoryResult<RefundResult>) {
    when (result) {
        is RepositoryResult.Success -> {
            when (val refundOutcome = result.data) {
                is RefundResult.Accepted -> {
                    println("✅ Refund Approved: ${refundOutcome.data.operationInfo.authorizationNumber}")
                }
                is RefundResult.Denied -> {
                    println("❌ Refund Denied")
                }
                is RefundResult.ExceededAmount -> {
                    println("⚠️ Error: Refund amount exceeds original transaction")
                }
            }
        }
        is RepositoryResult.ConnectionError -> println("❌ Connection Error")
        is RepositoryResult.Cancelled -> println("⚠️ Cancelled by user")
        is RepositoryResult.ProtocolError -> println("❌ Protocol Error: ${result.type}")
    }
}

Next Steps