CashInReversal
Descripción General
El evento CashInReversal se envía cuando un PIX recibido anteriormente es reversado, devolviendo el monto al pagador original. Normalmente ocurre cuando usted llama a la API de Refund-In (POST /api/pix/refund-in/:id), pero también puede ocurrir cuando la devolución es iniciada por el PSP, como en la devolución de un MED.
El movementType de CashInReversal es DEBIT, ya que usted está devolviendo dinero que había entrado en su cuenta.
| Campo | Valor |
|---|---|
event | CashInReversal |
movementType | DEBIT |
| Significado | Usted devolvió dinero que había recibido |
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 de CashInReversal
CashInReversal incluye el objeto parentTransaction con los datos de la transacción original que se está reversando.
parentTransaction
parentTransactionobjectobrigatorioDatos de la transacción PIX In original que se está reversando.
parentTransaction.transactionIdstringID numérico de la transacción PIX In original (devuelto como string).
parentTransaction.externalIdstring | nullID externo de la transacción original.
parentTransaction.endToEndIdstring | nullID End-to-End de la transacción original.
parentTransaction.processingDatestringFecha de creación de la transacción original (ISO 8601 UTC).
parentTransaction.wasTotalRefundedbooleanIndica si el monto total de la transacción original fue reversado.
true: Reversión total (no se puede reversar más)false: Reversión parcial (todavía se puede reversar el restante)
parentTransaction.remainingAmountForRefundnumberMonto restante que todavía puede reversarse (en reales).
Ejemplo: 0.2 (todavía puede reversar R$ 0,20)
parentTransaction.providerIdstring | nullIdentificador de la transacción original en el PSP. null si no existe.
parentTransaction.metadataobjectmetadata de la transacción original.
parentTransaction.counterpartobjectDatos del pagador original que recibirá la reversión (misma estructura que el counterpart de CashIn).
Reversión Total vs Parcial
Reversión Total
Cuando usted devuelve el 100% del monto recibido:
{
"parentTransaction": {
"wasTotalRefunded": true,
"remainingAmountForRefund": 0
}
}Reversión Parcial
Cuando usted devuelve solo parte del monto:
{
"parentTransaction": {
"wasTotalRefunded": false,
"remainingAmountForRefund": 0.2
}
}Puede realizar múltiples reversiones parciales hasta que wasTotalRefunded sea true.
Casos de Uso
1. Devolución de Pago 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 al cliente sobre la devolución
await notificationService.sendRefundConfirmation({
orderId: originalOrderId,
amount: payload.originalAmount
});
}2. Control de Reversiones Parciales
async function handleCashInReversal(payload) {
const { parentTransaction } = payload;
await refundService.updateStatus({
originalTransactionId: parentTransaction.transactionId,
totalRefunded: parentTransaction.wasTotalRefunded,
remainingAmount: parentTransaction.remainingAmountForRefund
});
if (parentTransaction.wasTotalRefunded) {
console.log('Transacción totalmente reversada');
} else {
console.log(`Todavía disponible para reversión: R$ ${parentTransaction.remainingAmountForRefund}`);
}
}Flujo Típico
sequenceDiagram
participant SuSistema
participant FyPay
participant PagadorOriginal
Note over SuSistema,PagadorOriginal: Transacción original (CashIn)
PagadorOriginal->>FyPay: PIX recibido anteriormente
FyPay->>SuSistema: Webhook CashIn
Note over SuSistema,PagadorOriginal: Reversión (CashInReversal)
SuSistema->>FyPay: POST /api/pix/refund-in/:id
FyPay->>PagadorOriginal: Devuelve PIX
FyPay->>SuSistema: Webhook CashInReversal
SuSistema-->>FyPay: HTTP 2xx