Estornar um Pagamento
Este guia detalha como implementar operações de estorno (refund) utilizando o RefundRepository. O estorno permite devolver fundos para o cartão de um cliente, seja vinculado a uma transação anterior ou como uma operação independente.
Antes de realizar qualquer estorno, certifique-se de que você já inicializou o TPV.
Métodos de Estorno
O RefundRepository suporta três fluxos distintos de estorno:
1. Estorno Padrão (Por ID)
Use este método quando você tiver o identificador da transação original (operationId) e quiser estornar um valor específico contra ela. Este é o cenário mais comum.
Função: makeRefund
Parâmetros:
operationId: O identificador exclusivo da venda original.amount: O objetoMoneyrepresentando o valor a ser estornado.proprietaryExtraData(Opcional): Dados de terceiros.language(Opcional): Idioma para a interface do serviço.
Exemplo:
suspend fun refundTransaction(originalId: String, amount: Money) {
val result = refundRepository.makeRefund(
operationId = originalId,
amount = amount
)
handleRefundResult(result)
}2. Estorno com Leitura de Cartão
Use este método quando você tiver o operationId original, mas desejar forçar o cliente a apresentar o cartão novamente (ex: por motivos de segurança ou conformidade).
Função: makeRefundReadingCard
Parâmetros: Mesmos do Estorno Padrão.
Exemplo:
suspend fun refundWithCardCheck(originalId: String, amount: Money) {
val result = refundRepository.makeRefundReadingCard(
operationId = originalId,
amount = amount
)
handleRefundResult(result)
}3. Estorno Sem Original (Adhoc)
Use este método para emitir um estorno sem vinculá-lo a uma transação anterior. Esta funcionalidade geralmente requer que uma configuração específica (noOriginal) esteja habilitada no TPV.
Função: makeRefundWithoutOriginal
Parâmetros:
amount: O objetoMoneyrepresentando o valor a ser estornado.proprietaryExtraData(Opcional): Dados de terceiros.language(Opcional): Idioma para a interface do serviço.
Exemplo:
suspend fun adhocRefund(amount: Money) {
val result = refundRepository.makeRefundWithoutOriginal(
amount = amount
)
handleRefundResult(result)
}Interpretando o RefundResult
Quando a chamada do repositório é bem-sucedida (RepositoryResult.Success), ela retorna uma interface selada RefundResult. Você deve tratar os seguintes estados:
1. Aceito (RefundResult.Accepted)
O estorno foi autorizado pelo host.
- Dados: Contém um objeto
Transactioncom os detalhes da operação de estorno. - Ação: Imprima o comprovante de estorno e confirme o sucesso para o usuário.
2. Negado (RefundResult.Denied)
O estorno foi rejeitado.
- Dados: Contém um objeto
Transaction, potencialmente com o motivo da rejeição. - Ação: Informe ao usuário que o estorno foi recusado.
3. Valor Excedido (RefundResult.ExceededAmount)
Erro específico indicando que o valor de estorno solicitado é maior que o valor da transação original (ou que o saldo estornável restante).
- Ação: Exiba um erro indicando que o valor é muito alto.
Exemplo de Lógica de Tratamento
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}")
}
}Próximos Passos
- Criar um Pagamento Pré-autorizado: Saiba como reservar fundos em um cartão.
- Histórico de Transações: Consultando operações passadas.