# Acompanhar reembolsos e chargebacks

URL: https://staging.pagpolar.com/docs/guias/jornadas/acompanhar-reembolsos-e-chargebacks

> Receba o pedido de reembolso, consulte os pedidos na API e reaja ao estorno e ao chargeback de uma venda.

Use este guia depois que a venda foi paga. Ele mostra como saber quando o cliente pede o dinheiro de volta, quando o estorno acontece e quando o banco do cliente contesta a compra.

A API **consulta** os pedidos de reembolso e **reembolsa** uma venda sua. Aceitar, recusar ou cancelar um pedido aberto pelo cliente é feito no painel da PagPolar.

Se a venda é de uma assinatura, o reembolso, o estorno e o chargeback também cancelam a assinatura. Veja [em quais casos](/docs/guias/jornadas/cancelar-assinatura#reembolso-e-chargeback).

## Visão geral

O diagrama mostra o caminho mais comum: o cliente pede o reembolso, você aceita no painel e o gateway devolve o dinheiro.

```mermaid
sequenceDiagram
  autonumber
  participant C as Cliente
  participant V as Você no painel
  participant A as API PagPolar
  participant G as Gateway
  participant S as Seu servidor
  C->>A: pede reembolso da venda inteira ou de parte dos itens
  A-)S: TRANSACTION_ASK_REFUNDING
  S->>A: GET /refunds?sale_identifier=CODIGO_DA_VENDA
  A-->>S: 200 com o pedido em PENDING
  V->>A: aceita o pedido
  A->>G: pede o estorno
  alt gateway confirma o estorno
    G-)A: estorno concluído
    A-)S: TRANSACTION_REFUNDED
  else gateway recusa o estorno
    A-->>V: pedido fica FAILED
  end
```

## Antes de começar

* Um token de acesso. Veja [Autenticação](/docs/guias/fundamentos/autenticacao#obter-o-token).
* Uma credencial com webhook. Veja [Configurar o webhook](/docs/webhooks/configurar).
* Os eventos `TRANSACTION_ASK_REFUNDING`, `TRANSACTION_REFUNDED`, `TRANSACTION_CANCELED` e `TRANSACTION_CHARGEBACK_APPROVED` escolhidos no webhook da credencial.
* Um servidor de webhook que [autentica as requisições](/docs/webhooks/autenticar-requisicoes) e [descarta eventos repetidos](/docs/webhooks/processar-sem-duplicar).

## O que fica na API e o que fica no painel

| O que acontece                                             | Onde                                                             |
| ---------------------------------------------------------- | ---------------------------------------------------------------- |
| O cliente pede reembolso.                                  | Na PagPolar. Você recebe `TRANSACTION_ASK_REFUNDING`.            |
| Aceitar, recusar ou cancelar o pedido do cliente.          | Tela **Reembolsos** do painel. Não existe rota na API para isso. |
| Reembolsar uma venda por sua conta, sem pedido do cliente. | [`POST /refunds`](/docs/referencia/reembolsos/create-refund)     |
| Ver os pedidos e a situação de cada um.                    | [`GET /refunds`](/docs/referencia/reembolsos/list-refunds)       |
| Saber que o dinheiro voltou para o cliente.                | `TRANSACTION_REFUNDED`                                           |
| Saber que o banco do cliente contestou a compra.           | `TRANSACTION_CHARGEBACK_APPROVED`                                |

## Passo a passo

1. **Receba o pedido de reembolso**

   Quando o cliente pede reembolso, a PagPolar envia `TRANSACTION_ASK_REFUNDING` para o seu webhook. O dinheiro **ainda não** voltou para o cliente.

       Exemplo resumido do que chega. O payload completo está em [`TRANSACTION_ASK_REFUNDING`](/docs/webhooks/eventos/transaction-ask-refunding).

       ```json
       {
         "event": "TRANSACTION_ASK_REFUNDING",
         "data": {
           "transaction": {
             "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
             "identifier": "PPO9876543210",
             "status": "ASK_REFUND",
             "payment_method": "PIX",
             "total_amount": "197.0000",
             "refund_reason": "Produto não atendeu às expectativas",
             "refund_at": null
           }
         }
       }
       ```

       O `status` da venda diz o tipo de pedido:

       | `data.transaction.status` | Tipo de pedido                         |
       | ------------------------- | -------------------------------------- |
       | `ASK_REFUND`              | Reembolso da venda inteira.            |
       | `ASK_PARTIAL_REFUND`      | Reembolso de parte dos itens da venda. |

       Faça assim:

       1. Grave o pedido junto da venda, usando o `data.transaction.id`.
       2. Guarde o `data.transaction.identifier`. É o código da venda, com o prefixo, como `PPO9876543210`: o mesmo valor da API. Use esse valor no filtro `sale_identifier` do próximo passo.
       3. Não revogue o acesso ainda. Espere `TRANSACTION_REFUNDED`.

   > **Pedido aberto pelo vendedor não envia este evento**
   >
   > Quando o pedido é aberto pelo próprio vendedor, pela PagPolar ou por [`POST /refunds`](#reembolsar-pela-api), ele já nasce aceito e `TRANSACTION_ASK_REFUNDING` não é enviado. Para ver esses pedidos, consulte `GET /refunds`. Os abertos no painel aparecem com `requested_by: "SELLER"`.

2. **Consulte o pedido na API**

   Chame [`GET /refunds`](/docs/referencia/reembolsos/list-refunds) com o código da venda no filtro `sale_identifier`.

   #### cURL

   ```bash
           curl "https://api.pagpolar.com/v1/refunds?sale_identifier=PPO9876543210" \
             -H "Authorization: Bearer <SEU_TOKEN_DE_ACESSO>"
           ```

   #### Node.js

   ```js
           const apiUrl = 'https://api.pagpolar.com/v1';
           const accessToken = '<SEU_TOKEN_DE_ACESSO>';
           const saleIdentifier = 'PPO9876543210';

           const query = new URLSearchParams({ sale_identifier: saleIdentifier });

           const response = await fetch(`${apiUrl}/refunds?${query}`, {
             headers: { Authorization: `Bearer ${accessToken}` },
           });

           if (!response.ok) {
             throw new Error(`Erro ${response.status}: ${await response.text()}`);
           }

           const body = await response.json();

           for (const refund of body.data) {
             console.log(refund.id, refund.status, refund.is_partial, refund.refund_amount);
           }
           ```

       Resposta resumida. Todos os campos estão na [referência de `GET /refunds`](/docs/referencia/reembolsos/list-refunds).

       ```json
       {
         "data": [
           {
             "id": "3c9f1e2a-7b4d-4e8a-9f10-2b3c4d5e6f70",
             "status": "PENDING",
             "requested_by": "CLIENT",
             "is_partial": false,
             "refund_amount": null,
             "reason": "Não atendeu às expectativas",
             "refused_reason": null,
             "canceled_reason": null,
             "return_tracking": null,
             "sale": {
               "identifier": "PPO9876543210",
               "status": "ASK_REFUND",
               "payment_method": "PIX",
               "total_amount": 197
             },
             "created_at": "2026-09-15T13:00:00.000Z",
             "updated_at": "2026-09-15T13:00:00.000Z"
           }
         ],
         "meta": {
           "page": 1,
           "per_page": 25,
           "total": 1,
           "total_pages": 1
         }
       }
       ```

       | Campo             | O que significa                                                                                                 |
       | ----------------- | --------------------------------------------------------------------------------------------------------------- |
       | `id`              | Id do pedido de reembolso.                                                                                      |
       | `status`          | Situação do pedido. Veja [Situações do pedido de reembolso](#situacoes-do-pedido).                              |
       | `requested_by`    | Quem abriu o pedido: `CLIENT` (o cliente) ou `SELLER` (o vendedor ou a PagPolar).                               |
       | `is_partial`      | `true` quando o pedido é de parte dos itens.                                                                    |
       | `refund_amount`   | Valor do reembolso parcial, **em reais**, como número: `49.9` = R$ 49,90. `null` no reembolso da venda inteira. |
       | `reason`          | Motivo informado no pedido.                                                                                     |
       | `refused_reason`  | Motivo da recusa. `null` se não foi recusado.                                                                   |
       | `canceled_reason` | Motivo do cancelamento. `null` se não foi cancelado.                                                            |
       | `return_tracking` | Rastreio da devolução de produto físico. `null` quando não há rastreio.                                         |
       | `sale`            | Resumo da venda: `identifier`, `status`, `payment_method` e `total_amount`.                                     |
       | `customer`        | O cliente, com documento e telefone mascarados.                                                                 |

       Filtros aceitos:

       | Parâmetro                     | O que faz                                                                           |
       | ----------------------------- | ----------------------------------------------------------------------------------- |
       | `sale_identifier`             | Traz só os pedidos da venda com esse código.                                        |
       | `status`                      | Traz só os pedidos nessa situação.                                                  |
       | `created_from` e `created_to` | Traz os pedidos criados nesse intervalo. Data e hora em ISO 8601 com fuso.          |
       | `page` e `per_page`           | Paginação. Veja [Paginação e filtros](/docs/guias/fundamentos/paginacao-e-filtros). |

   > **Use o código da venda, não o id**
   >
   > `sale_identifier` procura pelo código da venda (`identifier`). Ele aceita o código como chega no webhook e na API, com o prefixo, como `PPO9876543210`, o código só com os 10 dígitos, como `9876543210`, e um link que termina no código. Um `id` (uuid) nesse filtro não encontra nada.

       O bloco `sale` não traz o `id` da venda. Para ver a venda completa, chame [`GET /sales/{identifier}`](/docs/referencia/vendas/get-sale) com o `sale.identifier`.

       Uma venda só tem **um** pedido em andamento por vez. Depois que um pedido termina (reembolsado, recusado, cancelado ou com falha), um novo pedido pode ser aberto. Por isso, o filtro pode trazer mais de um pedido para a mesma venda.

3. **Acompanhe a decisão no painel**

   O vendedor responde ao pedido no painel. Nenhuma decisão envia evento de webhook, nem quando a venda volta para `PAID`. Consulte `GET /refunds` para saber o que aconteceu. Veja [Ciclo de vida da venda](/docs/guias/conceitos/ciclo-de-vida-da-venda).

       No painel, os pedidos ficam em **Vendas → Reembolsos**, com os indicadores por situação e a lista de pedidos:

       Ao abrir um pedido, a tela **Detalhes do reembolso** mostra a situação, a compra, o motivo informado pelo cliente e, quando houver, a data e o motivo da recusa. É nessa tela que o vendedor aceita ou recusa um pedido pendente:

       | Decisão                     | Situação do pedido                      | Status da venda                                                                                  | Evento |
       | --------------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------ | ------ |
       | Aceito pelo vendedor        | `ACCEPTED`, depois `REFUNDING`          | Venda inteira: `REFUNDING`. Parte dos itens: não muda.                                           | Nenhum |
       | Aceito pela PagPolar        | `ACCEPTED_BY_ADMIN`, depois `REFUNDING` | Igual ao aceito pelo vendedor.                                                                   | Nenhum |
       | Recusado                    | `REFUSED` ou `REFUSED_BY_ADMIN`         | Se estava em `ASK_REFUND` ou `ASK_PARTIAL_REFUND`, volta para `PAID`. Em outro status, não muda. | Nenhum |
       | Cancelado                   | `CANCELED`                              | Volta para `PAID`.                                                                               | Nenhum |
       | O gateway recusou o estorno | `FAILED`                                | Venda inteira: volta para `ASK_REFUND`.                                                          | Nenhum |

       Na recusa do pedido da venda inteira, o repasse e a taxa ligados à venda também voltam para `PAID`. Para saber se o pedido foi recusado ou cancelado, use o `status` do pedido em `GET /refunds`, e não o status da venda.

       A API não mostra o motivo da falha do estorno. O pedido aparece só como `FAILED`.

4. **Reaja ao estorno**

   Quando o gateway confirma o estorno, a venda muda de status e a PagPolar envia um evento. O que chega depende do caso:

       | Situação                                             | Evento                                                                | Status da venda   |
       | ---------------------------------------------------- | --------------------------------------------------------------------- | ----------------- |
       | Estorno da venda inteira                             | [`TRANSACTION_REFUNDED`](/docs/webhooks/eventos/transaction-refunded) | `REFUNDED`        |
       | Estorno de um item, e ainda restam itens na venda    | Nenhum                                                                | Volta para `PAID` |
       | Estorno do último item da venda                      | [`TRANSACTION_REFUNDED`](/docs/webhooks/eventos/transaction-refunded) | `REFUNDED`        |
       | Estorno de uma venda que ainda não contava como paga | [`TRANSACTION_CANCELED`](/docs/webhooks/eventos/transaction-canceled) | `CANCELED`        |

       "Contava como paga" quer dizer: a venda estava em `PAID`, `REFUNDING`, `ASK_REFUND`, `ASK_PARTIAL_REFUND` ou `CHARGEBACK_APPROVED`.

       Exemplo resumido de `TRANSACTION_REFUNDED`:

       ```json
       {
         "event": "TRANSACTION_REFUNDED",
         "data": {
           "transaction": {
             "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
             "identifier": "PPO9876543210",
             "status": "REFUNDED",
             "payment_method": "PIX",
             "total_amount": "197.0000",
             "refund_reason": "Produto não atendeu às expectativas"
           }
         }
       }
       ```

       Ao receber `TRANSACTION_REFUNDED`:

       1. Confira o `data.transaction.status`. Se já for `REFUNDED` no seu sistema, ignore.
       2. Revogue o acesso ao que foi vendido.
       3. Marque o pedido como reembolsado.

       Ao receber `TRANSACTION_CANCELED` depois de um pedido de reembolso, cancele o pedido no seu sistema.

       Para saber o valor devolvido no estorno de um item sem evento, consulte `GET /refunds?status=REFUNDED` e leia `is_partial` e `refund_amount`.

   > **O estorno pode chegar sem pedido antes**
   >
   > `TRANSACTION_REFUNDED` também chega quando o estorno acontece sem pedido de reembolso aberto. Trate o evento mesmo sem ter recebido `TRANSACTION_ASK_REFUNDING` antes.

## Reembolsar uma venda pela API

Use [`POST /refunds`](/docs/referencia/reembolsos/create-refund) quando **você** decide devolver o dinheiro — por acordo com o cliente, por engano na cobrança ou por uma regra do seu sistema.

> **O estorno é imediato e não tem volta**
>
> O pedido criado por esta rota já nasce aceito: o estorno vai para o gateway na hora e os acessos do cliente são revogados. Não existe rota para desfazer.

O reembolso é sempre **da venda inteira**. Reembolsar só alguns itens continua no painel.

#### cURL

```bash
    curl -X POST "https://api.pagpolar.com/v1/refunds" \
      -H "Authorization: Bearer <SEU_TOKEN_DE_ACESSO>" \
      -H "Idempotency-Key: 2f1c4d2e-8f4a-4c1e-9f7b-6a2d1e3c5b90" \
      -H "Content-Type: application/json" \
      -d '{
        "sale_identifier": "PPO9876543210",
        "requested_by": "CLIENT",
        "reason": "Cliente desistiu da compra"
      }'
    ```

#### Node.js

```js
    const apiUrl = 'https://api.pagpolar.com/v1';
    const accessToken = '<SEU_TOKEN_DE_ACESSO>';

    const response = await fetch(`${apiUrl}/refunds`, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${accessToken}`,
        'Idempotency-Key': crypto.randomUUID(),
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        sale_identifier: 'PPO9876543210',
        requested_by: 'CLIENT',
        reason: 'Cliente desistiu da compra',
      }),
    });

    if (!response.ok) {
      throw new Error(`Erro ${response.status}: ${await response.text()}`);
    }

    const { data } = await response.json();

    console.log(data.id, data.status);
    ```

| Campo                  | Obrigatório | O que é                                                                                                                                                                                                                                                                                                                                      |
| ---------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sale_identifier`      | Sim         | Código público da venda — o `identifier` que vem em [`GET /sales`](/docs/referencia/vendas/list-sales), na resposta da cobrança e no payload dos webhooks. Vem com o prefixo, como `PPO9876543210`. O código sem o prefixo ou a URL do checkout com o código também servem. **Não** é o `id` (uuid) da venda: com o uuid a resposta é `404`. |
| `requested_by`         | Não         | Quem pediu o reembolso: `SELLER` (padrão) quando a decisão foi sua, `CLIENT` quando o comprador pediu por fora, por e-mail ou atendimento. Só muda o registro, que volta em `requested_by` na consulta — o estorno é imediato nos dois casos.                                                                                                |
| `reason`               | Não         | Motivo, em texto livre, que fica gravado no pedido.                                                                                                                                                                                                                                                                                          |
| `customer_observation` | Não         | Observação do comprador, quando houver.                                                                                                                                                                                                                                                                                                      |

A resposta é `201` com o pedido já criado:

```json
{
  "data": {
    "id": "3f1c4d2e-8f4a-4c1e-9f7b-6a2d1e3c5b90",
    "status": "REFUNDING",
    "requested_by": "CLIENT",
    "is_partial": false,
    "refund_amount": null,
    "reason": "Cliente desistiu da compra",
    "sale": {
      "identifier": "PPO9876543210",
      "status": "REFUNDING",
      "payment_method": "PIX",
      "total_amount": 197
    }
  }
}
```

| Situação na resposta | O que aconteceu                                                                | O que fazer                                                                                         |
| -------------------- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- |
| `REFUNDING`          | O gateway aceitou o pedido de estorno e ainda não confirmou.                   | Espere [`TRANSACTION_REFUNDED`](/docs/webhooks/eventos/transaction-refunded) para revogar o acesso. |
| `FAILED`             | O gateway recusou o estorno, por exemplo por falta de saldo de um co-produtor. | Consulte `GET /refunds` e peça o reprocessamento pelo painel.                                       |

### Quando a venda não pode ser reembolsada

| Situação                                                                                       | Resposta              | Como resolver                                                                                                    |
| ---------------------------------------------------------------------------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Código de uma venda de outra conta, ou código inexistente.                                     | `404 not_found`       | Confira o `identifier` da venda em `GET /sales`.                                                                 |
| Venda que não está paga nem com pedido aberto (por exemplo, `OPEN`, `REFUNDED` ou `CANCELED`). | `409 conflict`        | Só venda paga pode ser reembolsada. Veja [Ciclo de vida da venda](/docs/guias/conceitos/ciclo-de-vida-da-venda). |
| A venda já tem um pedido de reembolso em andamento.                                            | `400 invalid_request` | Consulte `GET /refunds?sale_identifier=CODIGO_DA_VENDA` e acompanhe o pedido existente.                          |

## Chargeback

Chargeback é a contestação da compra pelo banco do cliente. Não existe pedido nem decisão no painel: o gateway avisa a PagPolar quando o chargeback é aprovado.

O diagrama mostra o que acontece quando o aviso chega.

```mermaid
sequenceDiagram
  autonumber
  participant G as Gateway
  participant A as API PagPolar
  participant S as Seu servidor
  G-)A: chargeback aprovado
  A-)S: TRANSACTION_CHARGEBACK_APPROVED
  S->>A: GET /sales/CODIGO_DA_VENDA
  A-->>S: 200 com o status atual da venda
```

O que muda na PagPolar:

| O quê                         | Efeito                                                                                                                                                                        |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Status da venda               | Vira `CHARGEBACK_APPROVED`. Se a venda já estava `REFUNDED` ou `CANCELED`, o status não muda.                                                                                 |
| Evento                        | `TRANSACTION_CHARGEBACK_APPROVED` é enviado nos dois casos acima.                                                                                                             |
| Pedidos de reembolso da venda | Os que estavam `PENDING`, `ACCEPTED` ou `ACCEPTED_BY_ADMIN` viram `CANCELED`.                                                                                                 |
| Assinatura da venda           | A PagPolar pede o cancelamento, se a venda não estava `REFUNDED` nem `CANCELED`. Veja [Cancelar assinatura](/docs/guias/jornadas/cancelar-assinatura#reembolso-e-chargeback). |

Exemplo resumido:

```json
{
  "event": "TRANSACTION_CHARGEBACK_APPROVED",
  "data": {
    "transaction": {
      "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
      "identifier": "PPO9876543210",
      "status": "CHARGEBACK_APPROVED",
      "payment_method": "CREDIT_CARD",
      "total_amount": "197.0000",
      "chargeback_approved_at": "2026-09-15T12:00:00.000Z"
    }
  }
}
```

Ao receber `TRANSACTION_CHARGEBACK_APPROVED`:

1. Revogue o acesso ao que foi vendido.
2. Guarde `data.transaction.chargeback_approved_at`. A venda na API não traz essa data.
3. Se a venda tinha um pedido de reembolso aberto no seu sistema, marque o pedido como cancelado.

Para listar as vendas com chargeback aprovado, filtre a listagem de vendas pelo status:

#### cURL

```bash
    curl "https://api.pagpolar.com/v1/sales?status=CHARGEBACK_APPROVED&per_page=100" \
      -H "Authorization: Bearer <SEU_TOKEN_DE_ACESSO>"
    ```

#### Node.js

```js
    const apiUrl = 'https://api.pagpolar.com/v1';
    const accessToken = '<SEU_TOKEN_DE_ACESSO>';

    const query = new URLSearchParams({
      status: 'CHARGEBACK_APPROVED',
      per_page: '100',
    });

    const response = await fetch(`${apiUrl}/sales?${query}`, {
      headers: { Authorization: `Bearer ${accessToken}` },
    });

    if (!response.ok) {
      throw new Error(`Erro ${response.status}: ${await response.text()}`);
    }

    const body = await response.json();

    console.log(body.data.map((sale) => sale.identifier));
    ```

> **Não há aviso antes da aprovação**
>
> A PagPolar só envia evento quando o chargeback é **aprovado**. Não existe evento para chargeback aberto ou em análise.

## Situações do pedido de reembolso

O diagrama mostra os caminhos principais de um pedido de reembolso.

```mermaid
stateDiagram-v2
  [*] --> PENDING: pedido aberto
  PENDING --> ACCEPTED: vendedor aceita
  PENDING --> ACCEPTED_BY_ADMIN: PagPolar aceita
  PENDING --> REFUSED: vendedor recusa, venda volta para PAID
  PENDING --> REFUSED_BY_ADMIN: PagPolar recusa, venda volta para PAID
  PENDING --> CANCELED: pedido cancelado ou chargeback aprovado
  ACCEPTED --> CANCELED: chargeback aprovado
  ACCEPTED_BY_ADMIN --> CANCELED: chargeback aprovado
  ACCEPTED --> REFUNDING: estorno pedido ao gateway
  ACCEPTED_BY_ADMIN --> REFUNDING: estorno pedido ao gateway
  ACCEPTED --> FAILED: gateway recusa o estorno
  ACCEPTED_BY_ADMIN --> FAILED: gateway recusa o estorno
  REFUNDING --> REFUNDED: gateway confirma o estorno
```

| Situação                                     | Significado                                                                                                                   | O que fazer                                      |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| `PENDING`                                    | O pedido espera a resposta do vendedor.                                                                                       | Aguarde.                                         |
| `ACCEPTED`                                   | O vendedor aceitou. O estorno vai ser pedido ao gateway.                                                                      | Aguarde o estorno.                               |
| `ACCEPTED_BY_ADMIN`                          | A PagPolar aceitou, inclusive por aprovação automática de pedido sem resposta.                                                | Aguarde o estorno.                               |
| `REFUSED`                                    | O vendedor recusou. A venda volta para `PAID`, se estava em pedido de reembolso.                                              | Mantenha o acesso.                               |
| `REFUSED_BY_ADMIN`                           | A PagPolar recusou. A venda volta para `PAID`, se estava em pedido de reembolso.                                              | Mantenha o acesso.                               |
| `WAITING_SEND`, `WAITING_TRACK_CODE`, `SENT` | Etapas da devolução de um produto físico. `WAITING_TRACK_CODE` aparece quando o vendedor exige a devolução do produto físico. | Aguarde.                                         |
| `REFUNDING`                                  | O estorno foi pedido ao gateway e ainda não foi confirmado.                                                                   | Aguarde `TRANSACTION_REFUNDED`.                  |
| `REFUNDED`                                   | O estorno foi concluído.                                                                                                      | Revogue o acesso, se ainda não fez.              |
| `CANCELED`                                   | O pedido foi desfeito, ou a venda teve chargeback aprovado.                                                                   | Mantenha o acesso se a venda voltou para `PAID`. |
| `FAILED`                                     | O gateway recusou o estorno.                                                                                                  | Aguarde. O vendedor resolve pelo painel.         |

## Eventos de webhook deste fluxo

* [`TRANSACTION_ASK_REFUNDING`](/docs/webhooks/eventos/transaction-ask-refunding): veja [Receba o pedido de reembolso](#receba-o-pedido-de-reembolso).
* [`TRANSACTION_REFUNDED`](/docs/webhooks/eventos/transaction-refunded) e [`TRANSACTION_CANCELED`](/docs/webhooks/eventos/transaction-canceled): veja [Reaja ao estorno](#reaja-ao-estorno).
* [`TRANSACTION_CHARGEBACK_APPROVED`](/docs/webhooks/eventos/transaction-chargeback-approved): veja [Chargeback](#chargeback).

## Quando algo dá errado

Além dos [erros comuns a todas as rotas](/docs/guias/fundamentos/erros#erros-comuns), este fluxo pode responder:

| Passo              | Situação                                                                                   | Resposta               | Como resolver                                                                           |
| ------------------ | ------------------------------------------------------------------------------------------ | ---------------------- | --------------------------------------------------------------------------------------- |
| Consultar o pedido | `status` com um valor fora da lista de situações.                                          | `400 invalid_request`  | Use um valor da tabela [Situações do pedido de reembolso](#situacoes-do-pedido).        |
| Consultar o pedido | `created_from` ou `created_to` fora do formato ISO 8601.                                   | `400 invalid_request`  | Envie data e hora completas: `2026-09-15T23:59:59-03:00`.                               |
| Consultar o pedido | `sale_identifier` com o `id` (uuid) da venda, ou com o código de uma venda de outra conta. | `200` com `data` vazio | Envie o código da venda (`identifier`), com ou sem o prefixo.                           |
| Chargeback         | `TRANSACTION_CHARGEBACK_APPROVED` chegou com `status: "REFUNDED"` ou `"CANCELED"`.         | Status mantido         | A venda já tinha sido estornada ou cancelada. Registre o chargeback sem mudar o status. |

## Próximos passos

- [Ciclo de vida da venda](/docs/guias/conceitos/ciclo-de-vida-da-venda) — Veja todos os status da venda e o evento de cada um.
- [Processar eventos sem duplicar](/docs/webhooks/processar-sem-duplicar) — Trate cada evento de reembolso uma única vez.
- [Conciliar vendas e assinaturas](/docs/guias/jornadas/conciliar-vendas) — Confira no fim do período se nenhum estorno ficou de fora.
