# Criando um Boleto

A criação de boletos na API do Pagou permite gerar boletos para pagamento, com detalhes do cliente, cedente, e URLs para visualização em PDF ou HTML. Esta seção detalha o endpoint <mark style="color:green;">`POST`</mark>` ``/v1/charges`, o payload, a geração de URLs para visualização, autenticação, validação, exemplos de código, tratamento de erros, e boas práticas para criar boletos de forma robusta e segura.

### Visão Geral Técnica

O endpoint <mark style="color:green;">`POST`</mark>` ``/v1/charges` cria um boleto, retornando um ID único e informações básicas na resposta síncrona. Detalhes como código de barras, linha digitável, e informações bancárias são enviados posteriormente pelo webhook <mark style="color:orange;">`charge.created`</mark> (veja [Webhooks para Interações com Boletos](/integracao-com-a-api/meio-de-pagamento-pix/webhooks.md)) após o registro do boleto. Após a criação, o boleto pode ser visualizado em PDF (`https://fatura.pagou.com.br/boleto/pdf/{id}`) ou HTML (`https://fatura.pagou.com.br/boleto/{id}`), mas essas URLs podem não estar disponíveis imediatamente até o registro ser concluído.

**Especificações**:

* **Método**: `POST`
* **URL**:
  * Produção: `https://api.pagou.com.br/v1/charges`
  * Sandbox: `https://sandbox.api.pagou.com.br/v1/charges`
* **Autenticação**: Cabeçalho `X-API-KEY` com chave do painel.
* **Content-Type**: `application/json`
* **Resposta**: `Status 201` Created com corpo JSON contendo o ID do boleto e detalhes.
* **Erros**: `400 Bad Request`, `401 Unauthorized`, `500 Internal Server Error`.

**Headers**

| Cabeçalho    | Valor                    | Descrição                                |
| ------------ | ------------------------ | ---------------------------------------- |
| Content-Type | `application/json`       | Formato JSON para o corpo da requisição. |
| X-API-KEY    | `<token>`                | Chave de autenticação do painel.         |
| User-Agent   | `NomeDaSuaAplicacao/1.0` | Identificador da aplicação.              |

### Corpo da Requisição

O payload deve conter informações do boleto, cliente, multas, juros, descontos e configurações de notificação.

```json
{
  "due_date": "2024-12-31",
  "grace_period": 15,
  "amount": 100.50,
  "description": "Payment for services rendered",
  "metadata": [
    {
      "key": "order_id",
      "value": "ORD-2024-001"
    },
    {
      "key": "reference",
      "value": "REF-12345"
    }
  ],
  "payer": {
    "name": "João Silva",
    "document": "12345678901",
    "zip": "01234567",
    "street": "Rua das Flores",
    "city": "São Paulo",
    "state": "SP",
    "number": "123",
    "neighborhood": "Centro"
  },
  "fine": 2.5,
  "interest": 1.0,
  "discount": {
    "type": "fixed",
    "amount": 10.00,
    "limit_date": "2024-12-25"
  },
  "notification_url": "https://your-webhook.com/notifications",
  "customer_code": "CUST-001"
}
```

**Campos do Payload**:

| **Campo**             | **Tipo** | **Obrigatório** | **Descrição**                                                            |
| --------------------- | -------- | --------------- | ------------------------------------------------------------------------ |
| `due_date`            | string   | Sim             | Data de vencimento (formato YYYY-MM-DD).                                 |
| `grace_period`        | number   | Sim             | Dias de tolerância após o vencimento (ex.: 15 dias).                     |
| `amount`              | number   | Sim             | Valor do boleto em reais (ex.: 100.50 para R$ 100,50).                   |
| `description`         | string   | Sim             | Descrição do boleto (máx. 255 caracteres).                               |
| `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).                                   |
| `payer.zip`           | string   | Sim             | CEP (8 dígitos, sem hífen).                                              |
| `payer.street`        | string   | Sim             | Rua ou avenida (máx. 200 caracteres).                                    |
| `payer.city`          | string   | Sim             | Cidade (máx. 100 caracteres).                                            |
| `payer.state`         | string   | Sim             | UF (2 letras, ex.: SP).                                                  |
| `payer.number`        | string   | Sim             | Número do endereço (máx. 20 caracteres).                                 |
| `payer.neighborhood`  | string   | Sim             | Bairro (máx. 100 caracteres).                                            |
| `fine`                | number   | Não             | Multa por atraso em percentual (ex.: 2.5 para 2,5%).                     |
| `interest`            | number   | Não             | Juros por dia de atraso em percentual (ex.: 1.0 para 1%).                |
| `discount`            | object   | Não             | Desconto para pagamento antecipado.                                      |
| `discount.type`       | string   | Sim (se usado)  | Tipo de desconto (fixed ou percentage).                                  |
| `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).                        |
| `notification_url`    | string   | Não             | URL HTTPS para webhooks (ex.: <https://your-webhook.com/notifications>). |
| `customer_code`       | string   | Não             | Código interno do cliente (máx. 50 caracteres).                          |

**Validações**:

* `due_date`: Deve ser uma data futura (mín. 1 dia).
* `grace_period`: Deve ser maior do que 0 e menor igual a 30.
* `amount`: Valor mínimo de 5.00 (R$ 5,00).
* `payer`.document: Deve ser um CPF (11 dígitos) ou CNPJ (14 dígitos) válido.
* `payer.zip`: Deve ser um CEP válido (8 dígitos).
* `discount.limit_date`: Deve ser anterior ou igual a due\_date.
* `notification_url`: Deve ser uma URL HTTPS válida.

### Resposta

* **Status**: 201 Created
* **Header**: Location: /charges/{id}
* **Corpo**: Contendo o ID do Boleto criado mais os dados.

**Response**

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

```json
{
  "id": "d1bfda17-3a56-433b-8825-7981f7374cee",
  "due_date": "2024-12-31",
  "grace_period": 15,
  "amount": 100.50,
  "description": "Payment for services rendered",
  "metadata": [
    {
      "key": "order_id",
      "value": "ORD-2024-001"
    },
    {
      "key": "reference",
      "value": "REF-12345"
    }
  ],
  "payer": {
    "name": "João Silva",
    "document": "12345678901",
    "zip": "01234567",
    "street": "Rua das Flores",
    "city": "São Paulo",
    "state": "SP",
    "number": "123",
    "neighborhood": "Centro"
  },
  "fine": 2.5,
  "interest": 1.0,
  "discount": {
    "type": "fixed",
    "amount": 10.00,
    "limit_date": "2024-12-25"
  },
  "notification_url": "https://your-webhook.com/notifications",
  "customer_code": "CUST-001"

}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "error": "Invalid request"
}
```

{% endtab %}
{% endtabs %}

### Visualização do Boleto

Após a criação, o boleto pode ser visualizado em dois formatos:

* **PDF**: Acesse `https://fatura.pagou.com.br/boleto/pdf/{id}` (ex.: <https://fatura.pagou.com.br/boleto/pdf/1b6f2a39-2403-4217-a2ce-7d20e6376cf5>).
* **HTML**: Acesse `https://fatura.pagou.com.br/boleto/{id}` (ex.: <https://fatura.pagou.com.br/boleto/1b6f2a39-2403-4217-a2ce-7d20e6376cf5>).

**Nota**: Substitua {id} pelo UUID retornado (id). As URLs podem não estar disponíveis imediatamente, pois dependem do registro do boleto. Aguarde o webhook `charge.created` para confirmar a disponibilidade do boleto.

### Exemplos de Código

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

```bash
curl -X POST https://sandbox.api.pagou.com.br/v1/charges \
  -H "X-API-KEY: sua_chave_api" \
  -H "Content-Type: application/json" \
  -H "User-Agent: MinhaLoja/1.0" \
  -d '{
    "due_date": "2024-12-31",
    "grace_period": 15,
    "amount": 100.50,
    "description": "Payment for services rendered",
    "metadata": [
      {
        "key": "order_id",
        "value": "ORD-2024-001"
      },
      {
        "key": "reference",
        "value": "REF-12345"
      }
    ],
    "payer": {
      "name": "João Silva",
      "document": "12345678901",
      "zip": "01234567",
      "street": "Rua das Flores",
      "city": "São Paulo",
      "state": "SP",
      "number": "123",
      "neighborhood": "Centro"
    },
    "fine": 2.5,
    "interest": 1.0,
    "discount": {
      "type": "fixed",
      "amount": 10.00,
      "limit_date": "2024-12-25"
    },
    "notification_url": "https://your-webhook.com/notifications",
    "customer_code": "CUST-001"
  }'
```

{% 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: ['due_date', 'amount', 'description', 'payer'],
    properties: {
        due_date: { type: 'string', pattern: '^\\d{4}-\\d{2}-\\d{2}$' },
        grace_period: { type: 'integer', minimum: 0 },
        amount: { type: 'number', minimum: 1.00 },
        description: { type: 'string', maxLength: 255 },
        metadata: {
            type: 'array',
            items: {
                type: 'object',
                required: ['key', 'value'],
                properties: {
                    key: { type: 'string' },
                    value: { type: 'string' }
                }
            }
        },
        payer: {
            type: 'object',
            required: ['name', 'document', 'zip', 'street', 'city', 'state', 'number', 'neighborhood'],
            properties: {
                name: { type: 'string', maxLength: 100 },
                document: { type: 'string', pattern: '^\\d{11}|\\d{14}$' },
                zip: { type: 'string', pattern: '^\\d{8}$' },
                street: { type: 'string', maxLength: 200 },
                city: { type: 'string', maxLength: 100 },
                state: { type: 'string', pattern: '^[A-Z]{2}$' },
                number: { type: 'string', maxLength: 20 },
                neighborhood: { type: 'string', maxLength: 100 }
            }
        },
        fine: { type: 'number', minimum: 0, maximum: 100 },
        interest: { type: 'number', minimum: 0, maximum: 100 },
        discount: {
            type: 'object',
            required: ['type', 'amount', 'limit_date'],
            properties: {
                type: { type: 'string', enum: ['fixed', 'percentage'] },
                amount: { type: 'number', minimum: 0 },
                limit_date: { type: 'string', pattern: '^\\d{4}-\\d{2}-\\d{2}$' }
            }
        },
        notification_url: { type: 'string', format: 'uri' },
        customer_code: { type: 'string', maxLength: 50 }
    }
};

// Payload
const payload = {
    due_date: '2024-12-31',
    grace_period: 15,
    amount: 100.50,
    description: 'Payment for services rendered',
    metadata: [
        { key: 'order_id', value: 'ORD-2024-001' },
        { key: 'reference', value: 'REF-12345' }
    ],
    payer: {
        name: 'João Silva',
        document: '12345678901',
        zip: '01234567',
        street: 'Rua das Flores',
        city: 'São Paulo',
        state: 'SP',
        number: '123',
        neighborhood: 'Centro'
    },
    fine: 2.5,
    interest: 1.0,
    discount: {
        type: 'fixed',
        amount: 10.00,
        limit_date: '2024-12-25'
    },
    notification_url: 'https://your-webhook.com/notifications',
    customer_code: 'CUST-001'
};

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

// Enviar requisição
fetch('https://sandbox.api.pagou.com.br/v1/charges', {
    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) {
            throw new Error(`Erro ${response.status}: ${response.statusText}`);
        }
        console.log(`Status: ${response.status}`);
        console.log(`Location: ${response.headers.get('Location')}`);
    })
    .catch(error => console.error('Erro na requisição:', error));
```

{% endtab %}

{% tab title="Python" %}

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

# Esquema de validação do payload
schema = {
    "type": "object",
    "required": ["due_date", "amount", "description", "payer"],
    "properties": {
        "due_date": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"},
        "grace_period": {"type": "integer", "minimum": 0},
        "amount": {"type": "number", "minimum": 1.00},
        "description": {"type": "string", "maxLength": 255},
        "metadata": {
            "type": "array",
            "items": {
                "type": "object",
                "required": ["key", "value"],
                "properties": {
                    "key": {"type": "string"},
                    "value": {"type": "string"}
                }
            }
        },
        "payer": {
            "type": "object",
            "required": ["name", "document", "zip", "street", "city", "state", "number", "neighborhood"],
            "properties": {
                "name": {"type": "string", "maxLength": 100},
                "document": {"type": "string", "pattern": "^\\d{11}|\\d{14}$"},
                "zip": {"type": "string", "pattern": "^\\d{8}$"},
                "street": {"type": "string", "maxLength": 200},
                "city": {"type": "string", "maxLength": 100},
                "state": {"type": "string", "pattern": "^[A-Z]{2}$"},
                "number": {"type": "string", "maxLength": 20},
                "neighborhood": {"type": "string", "maxLength": 100}
            }
        },
        "fine": {"type": "number", "minimum": 0, "maximum": 100},
        "interest": {"type": "number", "minimum": 0, "maximum": 100},
        "discount": {
            "type": "object",
            "required": ["type", "amount", "limit_date"],
            "properties": {
                "type": {"type": "string", "enum": ["fixed", "percentage"]},
                "amount": {"type": "number", "minimum": 0},
                "limit_date": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"}
            }
        },
        "notification_url": {"type": "string", "format": "uri"},
        "customer_code": {"type": "string", "maxLength": 50}
    }
}

# Payload
payload = {
    "due_date": "2024-12-31",
    "grace_period": 15,
    "amount": 100.50,
    "description": "Payment for services rendered",
    "metadata": [
        {"key": "order_id", "value": "ORD-2024-001"},
        {"key": "reference", "value": "REF-12345"}
    ],
    "payer": {
        "name": "João Silva",
        "document": "12345678901",
        "zip": "01234567",
        "street": "Rua das Flores",
        "city": "São Paulo",
        "state": "SP",
        "number": "123",
        "neighborhood": "Centro"
    },
    "fine": 2.5,
    "interest": 1.0,
    "discount": {
        "type": "fixed",
        "amount": 10.00,
        "limit_date": "2024-12-25"
    },
    "notification_url": "https://your-webhook.com/notifications",
    "customer_code": "CUST-001"
}

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

# Enviar requisição
url = "https://sandbox.api.pagou.com.br/v1/charges"
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()
    print(f"Status: {response.status_code}")
    print(f"Location: {response.headers.get('Location')}")
except requests.RequestException as e:
    print(f"Erro na requisição: {e}")
```

{% 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 < 1.00). | Validar dados antes de enviar (use schema fornecido).  |
| 401         | Unauthorized          | X-API-KEY inválido ou ausente.                       | Verificar chave em *Configurações > API*.              |
| 429         | Too Many Requests     | Limite de requisições excedido.                      | Implementar rate limiting e retentativas exponenciais. |
| 500         | Internal Server Error | Erro interno da API.                                 | Tentar novamente e contatar <suporte@pagou.com.br>.    |

### Boas Práticas Técnicas

* **Validação de Dados**: Use esquemas JSON (como nos exemplos) para validar o payload antes de enviar, evitando erros 400.
* **Segurança**: Armazene X-API-KEY em variáveis de ambiente e use HTTPS para todas as requisições.
* **Webhooks**: Configure o `notification_url` para receber o evento <mark style="color:red;">`ChargePaid`</mark> quando o boleto for pago.
* **Testes no Sandbox**: Use <https://sandbox.api.pagou.com.br/v1/charge> para simular criação de boletos sem custos reais.
* **Monitoramento**: Registre todas as requisições e respostas (incluindo Location) em logs para auditoria e depuração.

### Mapa de Status dos Boletos

Cada boleto 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:red;">`StatusEmpty`</mark>    | 1                  | Estado inicial transitório, indicando que o boleto foi criado, mas ainda não está ativo (ex.: aguardando validação interna). |
| <mark style="color:red;">`StatusActive`</mark>   | 2                  | Boleto ativo, pronto para pagamento, com código de barras e PDF disponíveis.                                                 |
| <mark style="color:red;">`StatusCanceled`</mark> | 3                  | Boleto cancelado, não mais válido para pagamento (ex.: por solicitação ou expiração).                                        |
| <mark style="color:red;">`StatusPaid`</mark>     | 4                  | Boleto pago pelo cliente, com liquidação confirmada.                                                                         |
| <mark style="color:red;">`StatusRefunded`</mark> | 5                  | Boleto pago, mas reembolsado ao cliente (ex.: após devolução do produto).                                                    |

**Transições de Status**:

* `StatusEmpty` → `StatusActive`: Após validação interna bem-sucedida (geralmente imediata).
* `StatusActive` → `StatusPaid`: Quando o pagamento é confirmado (notificado via webhook `ChargePaid`).
* `StatusActive` → `StatusCanceled`: Após solicitação de cancelamento via solicitação ou expiração.
* `StatusPaid` → `StatusRefunded`: Após processamento de reembolso.
* `StatusEmpty`, `StatusCanceled`, `StatusRefunded`: Estados finais, sem transições adicionais.


---

# 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-boleto/criando-um-boleto.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.
