# 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>).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.pagou.com.br/integracao-com-a-api/meio-de-pagamento-pix/estornando-um-qrcode.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
