# 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**](/en/get-smart/get-smart-sdk/integration-guides/payment-operations/initialize-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**:

```kotlin
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**:

```kotlin
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**:

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

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

* [**Create a Pre-Authorized Payment**](/en/get-smart/get-smart-sdk/integration-guides/payment-operations/create-a-pre-authorized-payment): Learn about reserving funds on a card.