CashInReversal
Visão Geral
O evento CashInReversal é enviado quando um PIX recebido anteriormente é estornado, devolvendo o valor ao pagador original. Normalmente ocorre quando você chama a API de Refund-In (POST /api/pix/refund-in/:id), mas também pode ocorrer quando a devolução é iniciada pelo PSP, como na devolução de um MED.
O movementType para CashInReversal é DEBIT, pois você está devolvendo dinheiro que havia entrado na sua conta.
| Campo | Valor |
|---|---|
event | CashInReversal |
movementType | DEBIT |
| Significado | Você devolveu dinheiro que havia recebido |
Payload Completo
{
"event": "CashInReversal",
"status": "CONFIRMED",
"transactionType": "PIX",
"movementType": "DEBIT",
"transactionId": "11111",
"externalId": "refund-678689ca-3e16-4f5e-a08f-09a984a97781",
"endToEndId": "D07136847202512112011O5222ZRBI5A",
"pixKey": null,
"feeAmount": 0.01,
"originalAmount": 0.3,
"finalAmount": 0.31,
"mismatchAmount": null,
"processingDate": "2025-12-11T20:11:13.289Z",
"errorCode": null,
"errorMessage": null,
"providerId": "r1e2f3u4n5",
"metadata": {},
"parentTransaction": {
"transactionId": "12345",
"externalId": "PIX-5482123298-EJUYFSMU1UU",
"endToEndId": "E00416968202512111942rjzxxzSSTD9",
"processingDate": "2025-12-11T19:42:04.080Z",
"wasTotalRefunded": false,
"remainingAmountForRefund": 0.2,
"providerId": "a1b2c3d4e5",
"metadata": {},
"counterpart": {
"name": "Carlos Oliveira",
"document": "*.345.678-**",
"bank": {
"bankISPB": null,
"bankName": null,
"bankCode": null,
"accountBranch": null,
"accountNumber": null
}
}
}
}Campos Específicos do CashInReversal
O CashInReversal inclui o objeto parentTransaction com dados da transação original que está sendo estornada.
parentTransaction
parentTransactionobjectobrigatorioDados da transação PIX In original que está sendo estornada.
parentTransaction.transactionIdstringID numérico da transação PIX In original (retornado como string).
parentTransaction.externalIdstring | nullID externo da transação original.
parentTransaction.endToEndIdstring | nullID End-to-End da transação original.
parentTransaction.processingDatestringData de criação da transação original (ISO 8601 UTC).
parentTransaction.wasTotalRefundedbooleanIndica se o valor total da transação original foi estornado.
true: Estorno total (não pode estornar mais)false: Estorno parcial (ainda pode estornar o restante)
parentTransaction.remainingAmountForRefundnumberValor restante que ainda pode ser estornado (em reais).
Exemplo: 0.2 (ainda pode estornar R$ 0,20)
parentTransaction.providerIdstring | nullIdentificador da transação original no PSP. null se ausente.
parentTransaction.metadataobjectmetadata da transação original.
parentTransaction.counterpartobjectDados do pagador original que receberá o estorno (mesma estrutura do counterpart do CashIn).
Estorno Total vs Parcial
Estorno Total
Quando você devolve 100% do valor recebido:
{
"parentTransaction": {
"wasTotalRefunded": true,
"remainingAmountForRefund": 0
}
}Estorno Parcial
Quando você devolve apenas parte do valor:
{
"parentTransaction": {
"wasTotalRefunded": false,
"remainingAmountForRefund": 0.2
}
}Você pode fazer múltiplos estornos parciais até que wasTotalRefunded seja true.
Casos de Uso
1. Devolução de Pagamento Duplicado
async function handleCashInReversal(payload) {
const refundId = payload.transactionId;
const originalOrderId = payload.parentTransaction.externalId;
await refundService.markAsCompleted({
refundId,
originalOrderId,
amount: payload.originalAmount,
completedAt: payload.processingDate
});
// Notificar cliente sobre a devolução
await notificationService.sendRefundConfirmation({
orderId: originalOrderId,
amount: payload.originalAmount
});
}2. Controle de Estornos Parciais
async function handleCashInReversal(payload) {
const { parentTransaction } = payload;
await refundService.updateStatus({
originalTransactionId: parentTransaction.transactionId,
totalRefunded: parentTransaction.wasTotalRefunded,
remainingAmount: parentTransaction.remainingAmountForRefund
});
if (parentTransaction.wasTotalRefunded) {
console.log('Transação totalmente estornada');
} else {
console.log(`Ainda disponível para estorno: R$ ${parentTransaction.remainingAmountForRefund}`);
}
}Fluxo Típico
sequenceDiagram
participant SeuSistema
participant FyPay
participant PagadorOriginal
Note over SeuSistema,PagadorOriginal: Transação original (CashIn)
PagadorOriginal->>FyPay: PIX recebido anteriormente
FyPay->>SeuSistema: Webhook CashIn
Note over SeuSistema,PagadorOriginal: Estorno (CashInReversal)
SeuSistema->>FyPay: POST /api/pix/refund-in/:id
FyPay->>PagadorOriginal: Devolve PIX
FyPay->>SeuSistema: Webhook CashInReversal
SeuSistema-->>FyPay: HTTP 2xx