docs
Webhooks

CashInReversal

Overview

The CashInReversal event is sent when a previously received PIX is reversed, returning the amount to the original payer. It usually occurs when you call the Refund-In API (POST /api/pix/refund-in/:id), but it can also occur when the refund is initiated by the PSP, as in the refund of a MED.

The movementType for CashInReversal is DEBIT, because you are returning money that had entered your account.

FieldValue
eventCashInReversal
movementTypeDEBIT
MeaningYou returned money you had received

Full Payload

{
  "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
      }
    }
  }
}

CashInReversal-Specific Fields

CashInReversal includes the parentTransaction object with data about the original transaction being reversed.

parentTransaction

parentTransactionobjectobrigatorio

Data about the original PIX In transaction being reversed.

parentTransaction.transactionIdstring

Numeric ID of the original PIX In transaction (returned as a string).

parentTransaction.externalIdstring | null

External ID of the original transaction.

parentTransaction.endToEndIdstring | null

End-to-End ID of the original transaction.

parentTransaction.processingDatestring

Creation date of the original transaction (ISO 8601 UTC).

parentTransaction.wasTotalRefundedboolean

Indicates whether the full amount of the original transaction was reversed.

  • true: Full reversal (cannot reverse any more)
  • false: Partial reversal (the remainder can still be reversed)
parentTransaction.remainingAmountForRefundnumber

Remaining amount that can still be reversed (in reais).

Example: 0.2 (R$ 0.20 can still be reversed)

parentTransaction.providerIdstring | null

Identifier of the original transaction at the PSP. null if absent.

parentTransaction.metadataobject

metadata of the original transaction.

parentTransaction.counterpartobject

Data about the original payer who will receive the reversal (same structure as the CashIn counterpart).


Full vs Partial Reversal

Full Reversal

When you return 100% of the amount received:

{
  "parentTransaction": {
    "wasTotalRefunded": true,
    "remainingAmountForRefund": 0
  }
}

Partial Reversal

When you return only part of the amount:

{
  "parentTransaction": {
    "wasTotalRefunded": false,
    "remainingAmountForRefund": 0.2
  }
}

You can make multiple partial reversals until wasTotalRefunded is true.


Use Cases

1. Refund of a Duplicate Payment

async function handleCashInReversal(payload) {
  const refundId = payload.transactionId;
  const originalOrderId = payload.parentTransaction.externalId;

  await refundService.markAsCompleted({
    refundId,
    originalOrderId,
    amount: payload.originalAmount,
    completedAt: payload.processingDate
  });

  // Notify customer about the refund
  await notificationService.sendRefundConfirmation({
    orderId: originalOrderId,
    amount: payload.originalAmount
  });
}

2. Tracking Partial Reversals

async function handleCashInReversal(payload) {
  const { parentTransaction } = payload;

  await refundService.updateStatus({
    originalTransactionId: parentTransaction.transactionId,
    totalRefunded: parentTransaction.wasTotalRefunded,
    remainingAmount: parentTransaction.remainingAmountForRefund
  });

  if (parentTransaction.wasTotalRefunded) {
    console.log('Transaction fully reversed');
  } else {
    console.log(`Still available for reversal: R$ ${parentTransaction.remainingAmountForRefund}`);
  }
}

Typical Flow

sequenceDiagram
    participant YourSystem
    participant FyPay
    participant OriginalPayer

    Note over YourSystem,OriginalPayer: Original transaction (CashIn)
    OriginalPayer->>FyPay: PIX previously received
    FyPay->>YourSystem: CashIn Webhook

    Note over YourSystem,OriginalPayer: Reversal (CashInReversal)
    YourSystem->>FyPay: POST /api/pix/refund-in/:id
    FyPay->>OriginalPayer: Returns PIX
    FyPay->>YourSystem: CashInReversal Webhook
    YourSystem-->>FyPay: HTTP 2xx

Next Steps

On this page