> For the complete documentation index, see [llms.txt](https://docs.pagou.com.br/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pagou.com.br/integracao-com-a-api/meio-de-pagamento-pix/estornando-um-qrcode.md).

# Estornando um QRCode

## Estornando um QRCode

O estorno de um QRCode na API do Pagou permite solicitar o reembolso de um QRCode Pix pago (com ou sem vencimento), transitando seu status para <mark style="color:orange;">`StatusRefunded`</mark>.

### Visão Geral Técnica

O endpoint <mark style="color:red;">`DELETE`</mark>` ``/v1/pix/{id}/refund` solicita o estorno de um QRCode identificado por seu ID único no formato UUID (ex.: 550e8400-e29b-41d4-a716-446655440000). O payload permite especificar o valor do estorno (para estornos parciais) e o motivo do reembolso. A operação é síncrona, retornando `204 No Content` para indicar que o estorno foi iniciado com sucesso, e o status do QRCode é alterado para <mark style="color:orange;">`StatusRefunded`</mark>.

**Especificações**:

* **Método**: <mark style="color:red;">`DELETE`</mark>
* **URL**:
  * Produção: `https://api.pagou.com.br/v1/pix/{id}/refund`
  * Sandbox: `https://sandbox-api.pagou.com.br/v1/pix/{id}/refund`
* **Autenticação**: Cabeçalho `X-API-KEY` com chave do painel.
* **Content-Type**: application/json
* **Resposta**: Status `204 No Content` sem corpo.
* **Erros**: `400 Bad Request`, `401 Unauthorized`, `500 Internal Server Error`.

### Cabeçalhos

| Cabeçalho      | Valor                  | Descrição                                                    |
| -------------- | ---------------------- | ------------------------------------------------------------ |
| `X-API-KEY`    | sua\_chave\_api        | Chave de autenticação (encontrada em *Configurações > API*). |
| `Content-Type` | application/json       | Formato JSON para o corpo da requisição.                     |
| `User-Agent`   | NomeDaSuaAplicacao/1.0 | Identificador da aplicação (ex.: MinhaLoja/1.0, opcional).   |

### Parâmetros da URL

| Parâmetro | Tipo   | Obrigatório | Descrição                                                                       |
| --------- | ------ | ----------- | ------------------------------------------------------------------------------- |
| `id`      | string | Sim         | ID único do QRCode no formato UUID (ex.: 550e8400-e29b-41d4-a716-446655440000). |

### Corpo da Requisição

O payload deve conter informações do estorno, como o valor a ser reembolsado (para estornos parciais) e o motivo do reembolso.

```json
{
  "amount": 50.00,
  "reason": 3,
  "description": "Customer requested refund due to product return"
}
```

**Campos do Payload**:

| Campo         | Tipo   | Obrigatório | Descrição                                                                |
| ------------- | ------ | ----------- | ------------------------------------------------------------------------ |
| `amount`      | number | Sim         | Valor do estorno em reais (ex.: 50.00 para R$ 50,00).                    |
| `reason`      | number | Sim         | Motivo do estorno. Valores válidos: `1`, `2`, `3`, `4`.                  |
| `description` | string | Sim         | Descrição do estorno (máx. 255 caracteres, ex.: "Devolução do produto"). |

**Valores de** reason:

<table data-header-hidden><thead><tr><th width="374"></th><th></th></tr></thead><tbody><tr><td>Valor</td><td>Descrição</td></tr><tr><td>1</td><td>Estorno devido a um erro bancário.</td></tr><tr><td>2</td><td>Estorno por suspeita de fraude.</td></tr><tr><td>3</td><td>Estorno solicitado pelo cliente final.</td></tr><tr><td>4</td><td>Estorno devido a erro relacionado ao Pix Saque ou Pix Troco.</td></tr></tbody></table>

**Validações**:

* id: Deve ser um UUID válido (ex.: 550e8400-e29b-41d4-a716-446655440000).
* amount: Deve ser maior que 0 e menor ou igual ao valor original do QRCode.
* reason: Máximo de 255 caracteres, se fornecido.
* O QRCode deve estar no status <mark style="color:orange;">`StatusCompleted`</mark>. QRCodes em <mark style="color:orange;">`StatusEmpty`</mark>, <mark style="color:orange;">`StatusActive`</mark>, <mark style="color:orange;">`StatusCanceled`</mark> ou <mark style="color:orange;">`StatusRefunded`</mark> não podem ser estornados.

**Notas Técnicas**:

* Use o endpoint <mark style="color:purple;">`GET`</mark>` ``/v1/pix/{id}` ([veja Consultando um QRCode](/integracao-com-a-api/meio-de-pagamento-pix/consultando-um-qrcode.md)) para verificar o status do QRCode antes e após o estorno.
* O estorno pode ser parcial ou total.
* Configure o `notification_url` ao criar o QRCode para receber eventos relacionados ao pagamento ou estorno, se aplicável (veja Webhooks para Interações com Pix).

### Resposta

* **Status**: `204 No Content`
* **Corpo**: Nenhum (a resposta não contém corpo, indicando sucesso no início do processo de estorno).

### Exemplos de Código

####

{% tabs %}
{% tab title="cURL" %}

```ruby
curl -X DELETE https://sandbox-api.pagou.com.br/v1/pix/550e8400-e29b-41d4-a716-446655440000/refund \
  -H "X-API-KEY: sua_chave_api" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MinhaLoja/1.0" \
  -d '{
    "amount": 50.00,
    "reason": "Customer requested refund due to product return"
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const fetch = require('node-fetch');
const { validate } = require('jsonschema');

// Esquema de validação do payload
const schema = {
    type: 'object',
    properties: {
        amount: { type: 'number', minimum: 0.01 },
        reason: { type: 'string', maxLength: 255 }
    }
};

// Configuração
const qrcodeId = '550e8400-e29b-41d4-a716-446655440000';
const url = `https://sandbox-api.pagou.com.br/v1/pix/${qrcodeId}/refund`;
const headers = {
    'X-API-KEY': 'sua_chave_api',
    'Content-Type': 'application/json',
    'User-Agent': 'MinhaLoja/1.0'
};
const payload = {
    amount: 50.00,
    reason: 'Customer requested refund due to product return'
};

// Validar payload
const validation = validate(payload, schema);
if (!validation.valid) {
    console.error('Erro de validação:', validation.errors);
    process.exit(1);
}

fetch(url, {
    method: 'DELETE',
    headers: headers,
    body: JSON.stringify(payload)
})
    .then(response => {
        if (!response.ok) {
            return response.json().then(err => { throw new Error(`Erro ${response.status}: ${err.error.message}`); });
        }
        console.log(`Estorno do QRCode ${qrcodeId} iniciado com sucesso`);
    })
    .catch(error => console.error('Erro na requisição:', error));
```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import re
from jsonschema import validate, ValidationError

# Esquema de validação do payload
schema = {
    "type": "object",
    "properties": {
        "amount": {"type": "number", "minimum": 0.01},
        "reason": {"type": "string", "maxLength": 255}
    }
}

# Configuração
qrcode_id = "550e8400-e29b-41d4-a716-446655440000"
url = f"https://sandbox-api.pagou.com.br/v1/pix/{qrcode_id}/refund"
headers = {
    "X-API-KEY": "sua_chave_api",
    "Content-Type": "application/json",
    "User-Agent": "MinhaLoja/1.0"
}
payload = {
    "amount": 50.00,
    "reason": "Customer requested refund due to product return"
}

# Validar payload
try:
    validate(instance=payload, schema=schema)
except ValidationError as e:
    print(f"Erro de validação: {e}")
    exit(1)

try:
    response = requests.delete(url, json=payload, headers=headers)
    response.raise_for_status()
    print(f"Estorno do QRCode {qrcode_id} iniciado com sucesso")
except requests.RequestException as e:
    print(f"Erro na requisição: {e}")
    if e.response:
        print(f"Detalhes: {e.response.json()}")
```

{% endtab %}
{% endtabs %}

### Tratamento de Erros

| Código HTTP | Descrição             | Possível Causa                                                                                                     | Solução                                                                                                                   |
| ----------- | --------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| 400         | Bad Request           | id não é um UUID válido, amount inválido (ex.: maior que o valor original), ou QRCode não está em StatusCompleted. | Verificar formato do id, validar amount e consultar status com <mark style="color:orange;">`GET`</mark>` ``/v1/pix/{id}`. |
| 401         | Unauthorized          | `X-API-KEY` inválido ou ausente.                                                                                   | Verificar chave.                                                                                                          |
| 500         | Internal Server Error | Erro interno da API.                                                                                               | Tentar novamente e contatar <contato@pagou.com.ver>                                                                       |

**Exemplo de Resposta de Erro**:

```json
{
  "error": "QRCode is not in completed status"
}
```

### Boas Práticas Técnicas

* **Verificação Prévia**: Consulte o status do QRCode com <mark style="color:purple;">`GET`</mark>` ``/v1/pix/{id}` (veja Consultando um QRCode) para confirmar que está em <mark style="color:orange;">`StatusCompleted`</mark> antes de tentar estornar.
* **Validação de Dados**: Valide o id como UUID e o amount (se fornecido) como menor ou igual ao valor original do QRCode antes de enviar a requisição.
* **Segurança**: Armazene `X-API-KEY` em variáveis de ambiente e use HTTPS para todas as requisições.
* **Monitoramento**: Registre todas as requisições e respostas (incluindo id e código de status HTTP) em logs para auditoria e depuração.
* **Confirmação de Estorno**: Após o estorno, use <mark style="color:purple;">`GET`</mark>` ``/v1/pix/{id}` para verificar se o status mudou para StatusRefunded.
* **Testes no Sandbox**: Use `https://sandbox-api.pagou.com.br/v1/pix/{id}/refund` para simular estornos sem impacto em produção.
* **Gestão de Erros**: Trate erros 400 para evitar tentativas de estorno de QRCodes não pagos (<mark style="color:orange;">`StatusActive`</mark>) ou já estornados (<mark style="color:orange;">`StatusRefunded`</mark>).
