# MED (Special Refund Mechanism) (/en/docs/pix-processamento/med)

<QuickLinks>
  <QuickLink href="/docs/pix-processamento/endpoints/infractions/get_infractions" title="MED Endpoints" />

  <QuickLink href="/docs/pix-processamento/tutoriais/infractions" title="Defense tutorial" />

  <QuickLink href="/docs/pix-processamento/webhooks" title="Webhooks" />

  <QuickLink href="/docs/pix-processamento/trueholder" title="TrueHolder" />
</QuickLinks>

The &#x2A;*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 &#x2A;*"safety net"** of the arrangement: when suspicious
activity is identified, the payer's institution opens a formal
process requesting the refund.

<Callout type="info">
  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.
</Callout>

## Conceptual MED flow [#conceptual-med-flow]

<Mermaid
  chart="`
flowchart TD
  A[&#x22;Payer opens dispute&#x22;]
  A --> B{&#x22;Do you respond?&#x22;}
  B -->|Submits defense| C[&#x22;Bacen analyzes&#x22;]
  B -->|Just waits| C
  C --> D{&#x22;Result&#x22;}
  D -->|Accepts payer| E[&#x22;Refunds the amount&#x22;]
  D -->|Rejects payer| F[&#x22;Keeps payment&#x22;]

  click A &#x22;/en/docs/pix-processamento/endpoints/infractions/get_infractions&#x22; &#x22;GET /user/infractions&#x22;
  click B &#x22;/en/docs/pix-processamento/endpoints/infractions/post_infractions_defense&#x22; &#x22;POST defense&#x22;
  click C &#x22;/en/docs/pix-processamento/glossary&#x22; &#x22;Bacen may request info (ANSWERED) or documents (WAITING_ADJUSTMENTS)&#x22;
  click D &#x22;/en/docs/pix-processamento/glossary&#x22; &#x22;Result: CLOSED + AGREED (accepted) or DISAGREED (rejected)&#x22;
  click E &#x22;#quando-a-infração-é-agreed&#x22; &#x22;Original transaction becomes REFUNDED&#x22;
  click F &#x22;#quando-a-infração-é-disagreed&#x22; &#x22;Transaction remains COMPLETED&#x22;

  style A fill:#f59e0b,stroke:#d97706,color:#ffffff
  style E fill:#ef4444,stroke:#dc2626,color:#ffffff
  style F fill:#14ce71,stroke:#0eb464,color:#ffffff
`"
/>

The high-level flow:

1. **Pix transaction completed** successfully.
2. **Problem identified** (fraud, error, unauthorized charge).
3. **Payer's institution opens the MED** in the arrangement, webhook arrives with
   `status: "OPEN"`.
4. **Receiving bank is notified** and may block the amount during analysis.
5. **Dispute analysis** by the institutions + Bacen rules.
6. **Result**: accepted (`AGREED`, amount refunded) or rejected
   (`DISAGREED`, transaction remains valid).

## Example of webhook with infraction [#example-of-webhook-with-infraction]

Real example of the payload received when a Pix transaction is subject to
an infraction:

```json
{
  "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 [#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](/docs/pix-processamento/glossary).

## How to react when you receive an infraction [#how-to-react-when-you-receive-an-infraction]

<Steps>
  <Step>
    ### Detect the callback [#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.

    ```ts
    if (callback.infraction?.status === 'OPEN') {
      await alertOperations({
        transactionId: callback.id,
        infractionId: callback.infraction.id,
        expiresAt: callback.infraction.expiresAt,
        reportDetails: callback.infraction.reportDetails,
      });
    }
    ```
  </Step>

  <Step>
    ### Investigate [#investigate]

    Use [`GET /user/infractions/{id}`](/docs/pix-processamento/endpoints/infractions/get_infractions_by_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`
  </Step>

  <Step>
    ### Decide: defend or accept [#decide-defend-or-accept]

    | Scenario                                                         | Recommended decision                                                                                                            |
    | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
    | Legitimate charge, you have evidence of product/service delivery | **Defend** via [`POST /user/infractions/{id}/defenses`](/docs/pix-processamento/endpoints/infractions/post_infractions_defense) |
    | 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.                                                 |
  </Step>

  <Step>
    ### Track until `CLOSED` [#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"`.
  </Step>
</Steps>

## Complete lifecycle [#complete-lifecycle]

<Mermaid
  chart="`
flowchart TD
  A[&#x22;Infraction opened&#x22;]
  A --> B[&#x22;You just wait&#x22;]
  A --> C[&#x22;You submit defense&#x22;]
  B --> D[&#x22;Bacen analyzes&#x22;]
  C --> D
  D --> E[&#x22;Automatic refund&#x22;]
  D --> F[&#x22;No impact&#x22;]

  click A &#x22;/en/docs/pix-processamento/glossary&#x22; &#x22;Status: OPEN&#x22;
  click B &#x22;/en/docs/pix-processamento/glossary&#x22; &#x22;Status: ACKNOWLEDGED (default)&#x22;
  click C &#x22;/en/docs/pix-processamento/glossary&#x22; &#x22;Status: DEFENDED&#x22;
  click D &#x22;/en/docs/pix-processamento/glossary&#x22; &#x22;Bacen may request info (ANSWERED) or documents (WAITING_ADJUSTMENTS)&#x22;
  click E &#x22;#quando-a-infração-é-agreed&#x22; &#x22;CLOSED + result AGREED. Transaction becomes REFUNDED&#x22;
  click F &#x22;#quando-a-infração-é-disagreed&#x22; &#x22;CLOSED + result DISAGREED. No financial impact&#x22;

  style A fill:#f59e0b,stroke:#d97706,color:#ffffff
  style E fill:#ef4444,stroke:#dc2626,color:#ffffff
  style F fill:#14ce71,stroke:#0eb464,color:#ffffff
`"
/>

## Financial impact [#financial-impact]

### When the infraction is AGREED [#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 [#when-the-infraction-is-disagreed]

There is no refund: the balance stays intact and the transaction remains `COMPLETED`.

## Next steps [#next-steps]

<QuickLinks>
  <QuickLink href="/docs/pix-processamento/tutoriais/infractions" title="Defense tutorial" />

  <QuickLink href="/docs/pix-processamento/glossary" title="Glossary" />
</QuickLinks>