# Criando um QRCode com vencimento

## Criando um QRCode com vencimento

A criação de um QRCode com vencimento na API do Pagou permite gerar um código Pix dinâmico com data de vencimento, ideal para pagamentos que requerem multas, juros ou descontos, similar a um boleto.

### Visão Geral Técnica

O endpoint <mark style="color:green;">`POST`</mark>` ``/v1/pix/due` cria um QRCode Pix com data de vencimento, com base nas informações fornecidas no payload JSON. O QRCode é identificado por um UUID único, retornado na resposta, e inclui um payload Pix e uma imagem em base64 para exibição. A operação é síncrona, retornando `201 Created` com os detalhes do QRCode, incluindo o código Pix (`payload.data`) e a imagem (`payload.image`). O pagamento pode ser monitorado via webhook (ex.: evento <mark style="color:orange;">`QRCodeCompleted`</mark> e <mark style="color:orange;">`QRCodeRefunded`</mark>).

**Especificações**:

* **Método**: `POST`
* **URL**:
  * Produção: `https://api.pagou.com.br/v1/pix/due`
  * Sandbox: `https://sandbox.api.pagou.com.br/v1/pix/due`
* **Autenticação**: Cabeçalho `X-API-KEY` com chave do painel.
* **Content-Type**: `application/json`
* **Resposta**: Status `201 Created` com corpo JSON contendo os detalhes do QRCode.
* **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.                             |
| `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`). |

### Corpo da Requisição

O payload deve conter informações do pagamento Pix, incluindo valor, descrição, data de vencimento, pagador, multas, juros, descontos e configurações de notificação.

```json
{
  "amount": 100.00,
  "description": "Payment with due date",
  "expiration": 30,
  "due_date": "2024-12-31",
  "metadata": [
    {
      "key": "order_id",
      "value": "ORD-2024-001"
    },
    {
      "key": "invoice_number",
      "value": "INV-12345"
    }
  ],
  "payer": {
    "name": "João Silva",
    "document": "12345678901"
  },
  "discount": {
    "type": "fixed",
    "amount": 10.00,
    "limit_date": "2024-12-25"
  },
  "fine": {
    "type": "percentage",
    "amount": 2.5
  },
  "interest": {
    "type": "percentage_calendar_days",
    "amount": 1.0
  },
  "notification_url": "https://your-webhook.com/notifications"
}
```

**Campos do Payload**:

| Campo                 | Tipo   | Obrigatório    | Descrição                                                                   |
| --------------------- | ------ | -------------- | --------------------------------------------------------------------------- |
| `amount`              | number | Sim            | Valor do pagamento em reais (ex.: 100.00 para R$ 100,00).                   |
| `description`         | string | Sim            | Descrição do pagamento (máx. 255 caracteres).                               |
| `expiration`          | number | Sim            | Tempo de expiração do QRCode em dias (mínimo 1).                            |
| `due_date`            | string | Sim            | Data de vencimento (formato `YYYY-MM-DD`).                                  |
| `metadata`            | array  | Não            | Pares chave-valor para dados adicionais (ex.: ID do pedido).                |
| `metadata[].key`      | string | Sim (se usado) | Chave do metadado (ex.: `order_id`).                                        |
| `metadata[].value`    | string | Sim (se usado) | Valor do metadado (ex.: `ORD-2024-001`).                                    |
| `payer`               | object | Sim            | Dados do pagador.                                                           |
| `payer.name`          | string | Sim            | Nome completo do pagador (máx. 100 caracteres).                             |
| `payer.document`      | string | Sim            | CPF (11 dígitos) ou CNPJ (14 dígitos).                                      |
| `discount`            | object | Não            | Desconto para pagamento antecipado.                                         |
| `discount.type`       | string | Sim (se usado) | Tipo de desconto (`fixed`, `percentage`, `fixed_calendar_days`, etc.).      |
| `discount.amount`     | number | Sim (se usado) | Valor do desconto (em reais para `fixed`, ou percentual para `percentage`). |
| `discount.limit_date` | string | Sim (se usado) | Data limite para o desconto (formato `YYYY-MM-DD`).                         |
| `fine`                | object | Não            | Multa por atraso.                                                           |
| `fine.type`           | string | Sim (se usado) | Tipo de multa (`percentage`, `fixed`, etc.).                                |
| `fine.amount`         | number | Sim (se usado) | Valor da multa (em percentual ou reais).                                    |
| `interest`            | object | Não            | Juros por atraso.                                                           |
| `interest.type`       | string | Sim (se usado) | Tipo de juros (`percentage_calendar_days`, `fixed`, etc.).                  |
| `interest.amount`     | number | Sim (se usado) | Valor dos juros (em percentual ou reais).                                   |
| `notification_url`    | string | Não            | URL HTTPS para webhooks (ex.: `https://your-webhook.com/notifications`).    |

**Validações**:

* `amount`: Valor mínimo de 5 (R$ 5,00).
* `description`: Máximo de 255 caracteres.
* `expiration`: Valor inteiro maior ou igual a 60 (em segundos).
* `due_date`: Deve ser uma data futura (mín. 1 dia após a criação, formato `YYYY-MM-DD`).
* `payer.document`: Deve ser um CPF (11 dígitos) ou CNPJ (14 dígitos) válido.
* `discount.limit_date`: Deve ser anterior a `due_date`.
* `discount.amount`: Deve ser menor que `amount`.
* `fine.amount` e `interest.amount`: Devem ser menores que `amount`.
* `notification_url`: Deve ser uma URL HTTPS válida.

**Notas Técnicas**:

* O status inicial após a criação (`201 Created`) é tipicamente <mark style="color:orange;">`StatusEmpty`</mark>, transitando rapidamente para <mark style="color:orange;">`StatusActive`</mark> após validação.
* Use o endpoint <mark style="color:purple;">`GET`</mark>` ``/v1/pix/{id}` para consultar o status atual.
* Configure o `notification_url` no payload para receber o evento `QRCodeCompleted` quando o status mudar para <mark style="color:orange;">`StatusCompleted`</mark> ou <mark style="color:orange;">`QRCodeRefunded`</mark> quando o status mudar para <mark style="color:orange;">`StatusRefunded`</mark>
* O campo `expiration` define o período em dias após o qual o QRCode expira automaticamente, transitando para `StatusCanceled` se não pago até `due_date`.

### Resposta

* **Status**: `201 Created`
* **Corpo**: JSON com os detalhes do QRCode, incluindo o UUID, payload Pix e imagem em base64.

**Exemplo de Resposta**:

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "amount": 100.00,
  "description": "Payment with due date",
  "expiration": 30,
  "due_date": "2024-12-31",
  "metadata": [
    {
      "key": "order_id",
      "value": "ORD-2024-001"
    },
    {
      "key": "invoice_number",
      "value": "INV-12345"
    }
  ],
  "payer": {
    "name": "João Silva",
    "document": "12345678901"
  },
  "discount": {
    "type": "fixed",
    "amount": 10.00,
    "limit_date": "2024-12-25"
  },
  "fine": {
    "type": "percentage",
    "amount": 2.5
  },
  "interest": {
    "type": "percentage_calendar_days",
    "amount": 1.0
  },
  "notification_url": "https://your-webhook.com/notifications",
  "payload": {
    "payload_id": 12345,
    "data": "00020126580014br.gov.bcb.pix0136123e4567-e12b-12d1-a456-426614174000520400005303986540100.005802BR5913JOAO SILVA6008SAO PAULO62070503***63041234",
    "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVHic7doxAQAAAMKg9U9tCj+gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4GvAAAEAAQ=="
  }
}
```

**Campos da Resposta**:

| Campo                 | Tipo   | Descrição                                                                     |
| --------------------- | ------ | ----------------------------------------------------------------------------- |
| `id`                  | string | UUID único do QRCode (ex.: `550e8400-e29b-41d4-a716-446655440000`).           |
| `amount`              | number | Valor do pagamento em reais (ex.: 100.00).                                    |
| `description`         | string | Descrição do pagamento (máx. 255 caracteres).                                 |
| `expiration`          | number | Tempo de expiração do QRCode em dias (ex.: 30).                               |
| `due_date`            | string | Data de vencimento (formato `YYYY-MM-DD`).                                    |
| `metadata`            | array  | Pares chave-valor para dados adicionais.                                      |
| `metadata[].key`      | string | Chave do metadado (ex.: `order_id`).                                          |
| `metadata[].value`    | string | Valor do metadado (ex.: `ORD-2024-001`).                                      |
| `payer`               | object | Dados do pagador.                                                             |
| `payer.name`          | string | Nome completo do pagador (máx. 100 caracteres).                               |
| `payer.document`      | string | CPF (11 dígitos) ou CNPJ (14 dígitos).                                        |
| `discount`            | object | Desconto para pagamento antecipado.                                           |
| `discount.type`       | string | Tipo de desconto (`fixed`, `percentage`, `fixed_calendar_days`).              |
| `discount.amount`     | number | Valor do desconto (em reais ou percentual).                                   |
| `discount.limit_date` | string | Data limite para o desconto (formato `YYYY-MM-DD`).                           |
| `fine`                | object | Multa por atraso.                                                             |
| `fine.type`           | string | Tipo de multa (`percentage ou` `fixed`.).                                     |
| `fine.amount`         | number | Valor da multa (em percentual ou reais).                                      |
| `interest`            | object | Juros por atraso.                                                             |
| `interest.type`       | string | Tipo de juros (`percentage_calendar_days`, `fixed`, `fixed` ou `percentage`). |
| `interest.amount`     | number | Valor dos juros (em percentual ou reais).                                     |
| `notification_url`    | string | URL HTTPS para webhooks.                                                      |
| `payload`             | object | Dados do QRCode Pix.                                                          |
| `payload.payload_id`  | number | ID interno do payload Pix.                                                    |
| `payload.data`        | string | Código Pix para pagamento (copia-e-cola).                                     |
| `payload.image`       | string | Imagem do QRCode em base64 (formato `data:image/png;base64,...`).             |

### Exemplos de Código

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

```ruby
curl -X POST https://sandbox.api.pagou.com.br/v1/pix/due \
  -H "X-API-KEY: sua_chave_api" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MinhaLoja/1.0" \
  -d '{
    "amount": 100.00,
    "description": "Payment with due date",
    "expiration": 30,
    "due_date": "2024-12-31",
    "metadata": [
      {
        "key": "order_id",
        "value": "ORD-2024-001"
      },
      {
        "key": "invoice_number",
        "value": "INV-12345"
      }
    ],
    "payer": {
      "name": "João Silva",
      "document": "12345678901"
    },
    "discount": {
      "type": "fixed",
      "amount": 10.00,
      "limit_date": "2024-12-25"
    },
    "fine": {
      "type": "percentage",
      "amount": 2.5
    },
    "interest": {
      "type": "percentage_calendar_days",
      "amount": 1.0
    },
    "notification_url": "https://your-webhook.com/notifications"
  }'
```

{% endtab %}

{% tab title="JavaScript" %}

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

// Esquema de validação do payload
const schema = {
    type: 'object',
    required: ['amount', 'description', 'expiration', 'due_date', 'payer'],
    properties: {
        amount: { type: 'number', minimum: 0.01 },
        description: { type: 'string', maxLength: 255 },
        expiration: { type: 'integer', minimum: 1 },
        due_date: { type: 'string', pattern: '^\\d{4}-\\d{2}-\\d{2}$' },
        metadata: {
            type: 'array',
            items: {
                type: 'object',
                required: ['key', 'value'],
                properties: {
                    key: { type: 'string' },
                    value: { type: 'string' }
                }
            }
        },
        payer: {
            type: 'object',
            required: ['name', 'document'],
            properties: {
                name: { type: 'string', maxLength: 100 },
                document: { type: 'string', pattern: '^\\d{11}|\\d{14}$' }
            }
        },
        discount: {
            type: 'object',
            required: ['type', 'amount', 'limit_date'],
            properties: {
                type: { type: 'string', enum: ['fixed', 'percentage', 'fixed_calendar_days'] },
                amount: { type: 'number', minimum: 0 },
                limit_date: { type: 'string', pattern: '^\\d{4}-\\d{2}-\\d{2}$' }
            }
        },
        fine: {
            type: 'object',
            required: ['type', 'amount'],
            properties: {
                type: { type: 'string', enum: ['percentage', 'fixed'] },
                amount: { type: 'number', minimum: 0 }
            }
        },
        interest: {
            type: 'object',
            required: ['type', 'amount'],
            properties: {
                type: { type: 'string', enum: ['percentage_calendar_days', 'fixed'] },
                amount: { type: 'number', minimum: 0 }
            }
        },
        notification_url: { type: 'string', format: 'uri' }
    }
};

// Payload
const payload = {
    amount: 100.00,
    description: 'Payment with due date',
    expiration: 30,
    due_date: '2024-12-31',
    metadata: [
        { key: 'order_id', value: 'ORD-2024-001' },
        { key: 'invoice_number', value: 'INV-12345' }
    ],
    payer: {
        name: 'João Silva',
        document: '12345678901'
    },
    discount: {
        type: 'fixed',
        amount: 10.00,
        limit_date: '2024-12-25'
    },
    fine: {
        type: 'percentage',
        amount: 2.5
    },
    interest: {
        type: 'percentage_calendar_days',
        amount: 1.0
    },
    notification_url: 'https://your-webhook.com/notifications'
};

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

// Validar due_date como data futura
const dueDate = new Date(payload.due_date);
if (dueDate <= new Date()) {
    console.error('Erro: due_date must be a future date');
    process.exit(1);
}
// Validar discount.limit_date <= due_date
if (payload.discount && payload.discount.limit_date) {
    const limitDate = new Date(payload.discount.limit_date);
    if (limitDate > dueDate) {
        console.error('Erro: discount.limit_date must be before or equal to due_date');
        process.exit(1);
    }
}
// Validar discount.amount, fine.amount e interest.amount < amount
if (payload.discount && payload.discount.amount >= payload.amount) {
    console.error('Erro: discount.amount must be less than amount');
    process.exit(1);
}
if (payload.fine && payload.fine.amount >= payload.amount) {
    console.error('Erro: fine.amount must be less than amount');
    process.exit(1);
}
if (payload.interest && payload.interest.amount >= payload.amount) {
    console.error('Erro: interest.amount must be less than amount');
    process.exit(1);
}

// Enviar requisição
fetch('https://sandbox.api.pagou.com.br/v1/pix/due', {
    method: 'POST',
    headers: {
        'X-API-KEY': 'sua_chave_api',
        'Content-Type': 'application/json',
        'User-Agent': 'MinhaLoja/1.0'
    },
    body: JSON.stringify(payload)
})
    .then(response => {
        if (!response.ok) {
            return response.json().then(err => { throw new Error(`Erro ${response.status}: ${err.error.message}`); });
        }
        return response.json();
    })
    .then(data => {
        console.log(`QRCode ID: ${data.id}`);
        console.log(`Status: ${data.status}`);
        console.log(`Código Pix: ${data.payload.data}`);
        console.log(`Imagem Base64: ${data.payload.image}`);
    })
    .catch(error => console.error('Erro na requisição:', error));
```

{% endtab %}

{% tab title="Python" %}

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

# Esquema de validação do payload
schema = {
    "type": "object",
    "required": ["amount", "description", "expiration", "due_date", "payer"],
    "properties": {
        "amount": {"type": "number", "minimum": 0.01},
        "description": {"type": "string", "maxLength": 255},
        "expiration": {"type": "integer", "minimum": 1},
        "due_date": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"},
        "metadata": {
            "type": "array",
            "items": {
                "type": "object",
                "required": ["key", "value"],
                "properties": {
                    "key": {"type": "string"},
                    "value": {"type": "string"}
                }
            }
        },
        "payer": {
            "type": "object",
            "required": ["name", "document"],
            "properties": {
                "name": {"type": "string", "maxLength": 100},
                "document": {"type": "string", "pattern": "^\\d{11}|\\d{14}$"}
            }
        },
        "discount": {
            "type": "object",
            "required": ["type", "amount", "limit_date"],
            "properties": {
                "type": {"type": "string", "enum": ["fixed", "percentage", "fixed_calendar_days"]},
                "amount": {"type": "number", "minimum": 0},
                "limit_date": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"}
            }
        },
        "fine": {
            "type": "object",
            "required": ["type", "amount"],
            "properties": {
                "type": {"type": "string", "enum": ["percentage", "fixed"]},
                "amount": {"type": "number", "minimum": 0}
            }
        },
        "interest": {
            "type": "object",
            "required": ["type", "amount"],
            "properties": {
                "type": {"type": "string", "enum": ["percentage_calendar_days", "fixed"]},
                "amount": {"type": "number", "minimum": 0}
            }
        },
        "notification_url": {"type": "string", "format": "uri"}
    }
}

# Payload
payload = {
    "amount": 100.00,
    "description": "Payment with due date",
    "expiration": 30,
    "due_date": "2024-12-31",
    "metadata": [
        {"key": "order_id", "value": "ORD-2024-001"},
        {"key": "invoice_number", "value": "INV-12345"}
    ],
    "payer": {
        "name": "João Silva",
        "document": "12345678901"
    },
    "discount": {
        "type": "fixed",
        "amount": 10.00,
        "limit_date": "2024-12-25"
    },
    "fine": {
        "type": "percentage",
        "amount": 2.5
    },
    "interest": {
        "type": "percentage_calendar_days",
        "amount": 1.0
    },
    "notification_url": "https://your-webhook.com/notifications"
}

# Validar payload
try:
    validate(instance=payload, schema=schema)
    # Validar due_date como data futura
    due_date = datetime.strptime(payload["due_date"], "%Y-%m-%d")
    if due_date <= datetime.now():
        raise ValueError("due_date must be a future date")
    # Validar discount.limit_date <= due_date
    if "discount" in payload and payload["discount"].get("limit_date"):
        limit_date = datetime.strptime(payload["discount"]["limit_date"], "%Y-%m-%d")
        if limit_date > due_date:
            raise ValueError("discount.limit_date must be before or equal to due_date")
    # Validar discount.amount, fine.amount e interest.amount < amount
    if "discount" in payload and payload["discount"].get("amount", 0) >= payload["amount"]:
        raise ValueError("discount.amount must be less than amount")
    if "fine" in payload and payload["fine"].get("amount", 0) >= payload["amount"]:
        raise ValueError("fine.amount must be less than amount")
    if "interest" in payload and payload["interest"].get("amount", 0) >= payload["amount"]:
        raise ValueError("interest.amount must be less than amount")
except (ValidationError, ValueError) as e:
    print(f"Erro de validação: {e}")
    exit(1)

# Enviar requisição
url = "https://sandbox.api.pagou.com.br/v1/pix/due"
headers = {
    "X-API-KEY": "sua_chave_api",
    "Content-Type": "application/json",
    "User-Agent": "MinhaLoja/1.0"
}

try:
    response = requests.post(url, json=payload, headers=headers)
    response.raise_for_status()
    data = response.json()
    print(f"QRCode ID: {data['id']}")
    print(f"Status: {data.get('status', 'StatusEmpty')}")
    print(f"Código Pix: {data['payload']['data']}")
    print(f"Imagem Base64: {data['payload']['image']}")
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           | Payload inválido (ex.: CPF inválido, `amount` < 5, `due_date` no passado, `discount.limit_date` após `due_date`, `discount.amount` ≥ `amount`). | Validar dados antes de enviar.                                                    |
| `401`       | Unauthorized          | `X-API-KEY` inválido ou ausente.                                                                                                                | Verificar chave.                                                                  |
| `500`       | Internal Server Error | Erro interno da API.                                                                                                                            | Tentar novamente e contatar [scontato@pagou.com.br](mailto:suporte@pagou.com.br). |

**Exemplo de Resposta de Erro**:

```json
{
  "error": "discount.limit_date must be before or equal to due_date"
}
```

### Mapa de Status do Pix

Cada QRCode Pix com vencimento possui um status que reflete seu estado no ciclo de vida. Os status possíveis, conforme definido na API do Pagou, são:

| Status                                               | Valor Numérico | Descrição                                                                                                                    |
| ---------------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| <mark style="color:orange;">`StatusEmpty`</mark>     | 1              | Estado inicial transitório, indicando que o QRCode foi criado, mas ainda não está ativo (ex.: aguardando validação interna). |
| <mark style="color:orange;">`StatusActive`</mark>    | 2              | QRCode ativo, pronto para pagamento, com código Pix e imagem disponíveis.                                                    |
| <mark style="color:orange;">`StatusCanceled`</mark>  | 3              | QRCode cancelado, não mais válido para pagamento (ex.: por solicitação ou expiração).                                        |
| <mark style="color:orange;">`StatusCompleted`</mark> | 4              | QRCode pago pelo cliente, com liquidação confirmada.                                                                         |
| <mark style="color:orange;">`StatusRefunded`</mark>  | 5              | QRCode pago, mas reembolsado ao cliente (ex.: após devolução do produto).                                                    |

**Transições de Status**:

* <mark style="color:orange;">`StatusEmpty`</mark> → <mark style="color:orange;">`StatusActive`</mark>: Após validação interna bem-sucedida (geralmente imediata).
* <mark style="color:orange;">`StatusActive`</mark> → <mark style="color:orange;">`StatusCompleted`</mark>: Quando o pagamento é confirmado (notificado via webhook <mark style="color:orange;">`QRCodeCompleted`</mark>).
* <mark style="color:orange;">`StatusActive`</mark> → <mark style="color:orange;">`StatusCanceled`</mark>: Após solicitação de cancelamento (ex.: <mark style="color:red;">`DELETE`</mark>` ``/v1/pix/{id}`) ou expiração do QRCode (definida por `due_date` e `expiration`).
* <mark style="color:orange;">`StatusCompleted`</mark> → <mark style="color:orange;">`StatusRefunded`</mark>: Após processamento de reembolso (se aplicável).
* <mark style="color:orange;">`StatusCanceled`</mark>, <mark style="color:orange;">`StatusRefunded`</mark>: Estados finais, sem transições adicionais.

### Boas Práticas Técnicas

* **Validação de Dados**: Use esquemas JSON (como nos exemplos) para validar o payload antes de enviar, incluindo verificações específicas como `due_date` futura, `discount.limit_date` ≤ `due_date` e `discount.amount`, `fine.amount`, `interest.amount` < `amount`.
* **Segurança**: Armazene `X-API-KEY` em variáveis de ambiente e use HTTPS para todas as requisições.
* **Status do Pix**: Após a criação, verifique o status com <mark style="color:purple;">`GET`</mark>` ``/v1/pix/{id}` (a ser documentado) para confirmar a transição de <mark style="color:red;">`StatusEmpty`</mark> para <mark style="color:red;">`StatusActive`</mark>.
* **Webhooks**: Configure o `notification_url` para receber o evento <mark style="color:red;">`QRCodeCompleted`</mark> quando o status mudar para <mark style="color:red;">`StatusCompleted`</mark> ou <mark style="color:red;">`QRCodeRefunded`</mark> quando o status mudar para <mark style="color:red;">`StatusRefunded`</mark>.
* **Testes no Sandbox**: Use `https://sandbox.api.pagou.com.br/v1/pix/due` para simular criação de QRCodes sem custos reais.
* **Monitoramento**: Registre todas as requisições e respostas (incluindo `id`, `status`, `payload.data` e `payload.image`) em logs para auditoria e depuração.
