MED (Special Refund Mechanism)
The Central Bank's safety net against Pix fraud and scams: when the payer's institution files a refund request, you get the alert on the same webhook as the transaction and handle the dispute without leaving your flow.
The MED (Special Refund Mechanism) is a Central Bank procedure that protects Pix users in cases of fraud, scam, or unauthorized transactions.
It works as a "safety net" of the arrangement: when suspicious activity is identified, the payer's institution opens a formal process requesting the refund.
At PayZu, the MED flow is delivered via webhook, reusing the
same callbackUrl of the transaction. The status of the original operation is
updated and the infraction object is inserted into the payload.
Conceptual MED flow
The high-level flow:
- Pix transaction completed successfully.
- Problem identified (fraud, error, unauthorized charge).
- Payer's institution opens the MED in the arrangement, webhook arrives with
status: "OPEN". - Receiving bank is notified and may block the amount during analysis.
- Dispute analysis by the institutions + Bacen rules.
- Result: accepted (
AGREED, amount refunded) or rejected (DISAGREED, transaction remains valid).
Example of webhook with infraction
Real example of the payload received when a Pix transaction is subject to an infraction:
{
"id": "PAYZU20260811K7M2X9QP4T000000",
"type": "DEPOSIT",
"status": "COMPLETED",
"serviceFeeCharged": 1,
"amount": 30,
"clientReference": "d2b2a5ed-f1a4-477e-81da-9",
"qrCodeText": "00020101021226870014br.gov.bcb.pix...",
"payerName": "João da Silva",
"payerDocument": "12345678901",
"payerInstitutionName": "PAYZU IP",
"receiverName": "PAYZU LTDA",
"receiverDocument": "123456789010110",
"endToEndId": "E18236120202608111046s1235ee7a91",
"paidAt": "2026-08-11T10:46:26.986Z",
"createdAt": "2026-08-11T10:45:18.403Z",
"updatedAt": "2026-08-11T10:46:27.346Z",
"callbackUrl": "https://seuwebhook.com",
"infraction": {
"id": "cmide759mb9i3s601bhwf6e",
"protocol": "4dd32924-9b53-4408-af4b-6d3b4d7ac",
"status": "OPEN",
"type": "REFUND_REQUEST",
"reportDetails": "Fraud report: transaction formally contested by the payer",
"reportedBy": "DEBITED_PARTICIPANT",
"analysisResult": null,
"analysisDetails": null,
"reportedAt": "2026-08-24T16:52:15.808Z",
"createdAt": "2026-08-24T17:00:00.490Z",
"updatedAt": "2026-08-24T17:00:00.490Z"
}
}Fields of the infraction object
| Field | Type | Description |
|---|---|---|
id | string | Unique infraction identifier |
protocol | string | Payment provider protocol number |
status | InfractionStatus | Current infraction status |
type | InfractionType | Infraction type |
reportDetails | string | Description of the dispute reason |
reportedBy | ReportedBy | Who reported the infraction |
analysisResult | AnalysisResult | null | Final decision (null while pending) |
analysisDetails | string | null | Decision justification |
reportedAt | string | When it was reported |
expiresAt | string | null | Deadline for resolution |
createdAt | string | Creation date |
updatedAt | string | Last update |
The full values of status, type, reportedBy and analysisResult are in the Glossary.
How to react when you receive an infraction
Detect the callback
When the infraction object arrives in the payload, trigger an internal alert immediately. The Bacen deadline is short, typically 72h, and silence is usually interpreted as acceptance.
if (callback.infraction?.status === 'OPEN') {
await alertOperations({
transactionId: callback.id,
infractionId: callback.infraction.id,
expiresAt: callback.infraction.expiresAt,
reportDetails: callback.infraction.reportDetails,
});
}Investigate
Use GET /user/infractions/{id} for full details of the dispute, original transaction, and deadline. Cross-reference with your logs:
- DICT logs before the payment (if a Pix payment)
- Who performed the operation in your system
- Customer IP, device, session
- Transaction history for that
payerDocument
Decide: defend or accept
| Scenario | Recommended decision |
|---|---|
| Legitimate charge, you have evidence of product/service delivery | Defend via POST /user/infractions/{id}/defenses |
| Real suspicion of fraud on your side (compromised customer) | Accept (do not defend). The amount is refunded and the case closes. |
| You have no evidence | Evaluate case by case. Without defense, Bacen tends to accept the contestation. |
Track until CLOSED
The infraction goes through states (OPEN → ACKNOWLEDGED/DEFENDED → ANSWERED/WAITING_ADJUSTMENTS → CLOSED). Each change generates a new callback. The final result comes in analysisResult when status: "CLOSED".
Complete lifecycle
Financial impact
When the infraction is AGREED
The original transaction (COMPLETED) moves through WAITING_FOR_REFUND, the amount is debited from the balance and the transaction ends as REFUNDED, with a finalization webhook. The amount actually refunded comes in refundAmount on the callback and may differ from the original amount.
When the infraction is DISAGREED
There is no refund: the balance stays intact and the transaction remains COMPLETED.