Refund a Payment
The Get Mini framework provides two ways to return funds to customers: standard refunds (linked to a previous transaction) and stand-alone refunds (without the original transaction reference).
Requirements
Before you begin, ensure you have verified permissions and data availability. The merchant must have permission for refunds (100201) and, for stand-alone refunds, the specific permiteDevolSinOrigin flag enabled. For standard refunds, you must possess the original OperacionDTO or the identificadorRTS. Critically, stand-alone refunds require the customer to be physically present with their card to complete the transaction on the PIN pad.
Option 1: Standard Refund
Standard refunds are linked to a previous transaction in your history. You use the RedsysTransactionManager to process these via Web Service.
Step 1: Obtain the Original Operation
To initiate a linked refund, you must first retrieve the OperacionDTO object corresponding to the original transaction. You can do this by querying the transaction history.
// 1. Configure the search query
let userInfo = RedsysUserInfoManager.getInfo(user)
let dateFrom = Date().addingTimeInterval(-86400 * 30) // e.g., last 30 days
let dateTo = Date()
// 'termTPVPC' is of type TerminalDataDTO (Type 2 for PC Terminal)
let consulta = ConsultaFechasDTO(
terminal: termTPVPC,
dateInitial: dateFrom,
dateEnd: dateTo,
andPage: 0,
andUserInfo: userInfo
)
// 2. (Optional) Apply filters to find specific transaction
let filtros = ConsultaFechasDTOFiltros()
filtros.setResultado("AUTORIZADAS")
filtros.setTipoOperacion("PAGO")
filtros.setFactura("INV-001") // Filter by your Invoice ID
// 3. Execute query
RedsysTransactionManager.peticionConsultaFechaPagina(
consulta,
conValores: filtros.dictValores()
) { (result, error) in
if let result = result, let operations = result.operaciones as? [OperacionDTO] {
// Find the specific operation object needed for the refund
if let originalOp = operations.first {
print("Found operation: \(originalOp.numAutorizacion)")
// Proceed to Step 2 with 'originalOp'
}
}
}Step 2: Initiate the Refund
Use peticionDevolucion with an EnvioDevolucionDTO object.
// 1. Setup User Info
let userInfo = RedsysUserInfoManager.getInfo(user)
// 2. Setup the Refund Object (using an existing OperacionDTO)
// Assuming 'termTPVPC' is your TerminalDataDTO and 'operacionOriginal' is OperacionDTO
let devolucion = EnvioDevolucionDTO(
terminal: termTPVPC,
andOperacion: operacionOriginal,
andUserInfo: userInfo
)
// 3. Set the amount (e.g., "10.00")
devolucion.importedevol = "10.00"
// 4. Execute
RedsysTransactionManager.peticionDevolucion(devolucion) { (result, error) in
if let result = result {
print("Refund successful: \(result)")
} else if let error = error {
print("Refund error: \(error.localizedDescription)")
}
}For refunds between different merchants in the same group, use the extended constructor including ComercioOriginal, FechaOperacion, and NumAutorizacion.
Option 2: Refund Without Original (Stand-alone)
If you do not have the original transaction details or are processing a manual return, use the Bluetooth Refund method. This requires the customer to present their card to the PIN pad.
Step 1: Execute the Refund
Create an EnvioDevolucionSinOriginalDTO with the amount in cents and execute it using the PIN pad Manager.
// Amount in cents (e.g., 10.00€ = 1000)
// 'termTPVPC' is your TerminalDataDTO
let devolucionSinOriginal = EnvioDevolucionSinOriginalDTO(
terminal: termTPVPC,
andImporteDevolucion: "1000",
forFactura: "INV-001"
)
// Execute using the Pinpad Manager
// Assuming 'pinpadElegido', 'merchanElegido', and 'pinpadConfig' are initialized
pinpadManager.devolucionBluetooth(
pinpadElegido,
merchan: merchanElegido,
config: pinpadConfig,
andDevolucionDTO: devolucionSinOriginal,
withDelegate: self
)Step 2: Handle PIN pad Callbacks
You must implement onPaymentFinished (or specific refund delegate method if applicable for your delegate version) to receive the result, which will be returned as a DevolucionResponseDTO.
Refund Constraints and Errors
| Constraint | Description |
|---|---|
| Amount Limit | A standard refund cannot exceed the original transaction amount (Error Code 200: TPV-PC0009). |
| Permission | Stand-alone refunds must be enabled in the merchant profile (permiteDevolSinOrigin). |
| Transaction State | You can only perform a refund on operations with an Estado of “F” (Finalized). |
Troubleshooting
Error Code 200 (TPV-PC0009) The refund amount exceeds the original transaction amount. Verify the remaining balance of the original order if partial refunds were previously issued.
Error Code 262 (TPV-PC0100) The specific operation type does not allow a refund (e.g., attempting to refund a transaction that hasn’t settled yet or is already annulled).
Merchant Permissions
If a stand-alone refund fails immediately, check PerfilComercioManager to see if permiteDevolSinOrigin is YES.
Next Steps
- Create a Single-Step Payment - Standard sale transactions
- Create a Payment with Installments - Handle currency and financing options
- Initialize the SDK - Set up SDK configuration