# Conceitos

Conceitos fundamentais para integrar com a API da Monetarie.

## Arquitetura de Segurança

A API utiliza **três camadas de proteção independentes**. Todas são obrigatórias.

### Camada 1 -- API Key + Secret

Cada integrador recebe um par de credenciais (`client_id` e `client_secret`). O secret nunca é armazenado em texto puro -- guardamos apenas o hash. Quando uma requisição chega, o secret enviado é comparado com o hash armazenado. Se não corresponder, a requisição é rejeitada imediatamente, antes de chegar à lógica de negócio.

### Camada 2 -- Assinatura HMAC-SHA512 por Requisição

Além da API Key, cada requisição transacional (POST) precisa enviar uma assinatura HMAC-SHA512 no header `hmac`.

O processo funciona assim:

1. O integrador serializa o body da requisição como JSON
2. Gera o hash HMAC-SHA512 usando o `client_secret` como chave
3. Envia o hash em hexadecimal no header `hmac`

Do nosso lado, recalculamos o hash com o mesmo método e comparamos com o valor recebido. Se qualquer byte do conteúdo for alterado no caminho (por exemplo, em um ataque man-in-the-middle), a assinatura não vai bater e a requisição é rejeitada com erro 401. Essa comparação é feita em **tempo constante** (constant-time comparison), o que evita ataques de timing que tentam descobrir a assinatura byte a byte.

### Camada 3 -- Whitelist de IP Obrigatória

Cada API Key só pode ser usada a partir de IPs previamente autorizados. Mesmo que alguém tenha acesso às credenciais, não conseguirá usar a API a partir de outro IP. Requisições de IPs não autorizados recebem `403 Forbidden`.

### Proteções Adicionais

| Proteção | Descrição |
|----------|-----------|
| **Rate Limiting** | 90.000 requisições/minuto por IP (autenticado). Endpoints de autenticação: 5 req/min |
| **AWS WAF** | Firewall de aplicação protegendo a API |
| **HTTPS obrigatório** | TLS 1.2 ou superior em todas as conexões |
| **HSTS** | HTTP Strict Transport Security habilitado |

Detalhes completos: [Autenticação](/auth-token) | [HMAC-SHA512](/hmac)

### Por que HMAC e não mTLS?

O mTLS (mutual TLS) adiciona autenticação via certificado X.509 no nível da conexão. É uma camada válida, mas no nosso cenário o HMAC por requisição oferece proteção equivalente ou mais adequada:

| Aspecto | mTLS | HMAC-SHA512 |
|---------|------|-------------|
| **O que valida** | A conexão (canal TLS) | Cada requisição individualmente |
| **Integridade do payload** | Não -- se a conexão é confiável, requisições passam | Sim -- qualquer alteração no body rejeita a requisição |
| **Gestão operacional** | Complexa: emissão, rotação, revogação, CRL/OCSP | Simples: gera novo par, atualiza, invalida anterior |
| **Incidentes comuns** | Certificados expirados ou mal gerenciados | Raros -- chave é string, sem ciclo de vida complexo |

O TLS já garante criptografia do transporte. O HMAC entra como camada adicional, garantindo integridade e autenticidade do payload -- algo que o mTLS por si só não cobre.

## Valores Monetários

A API Monetarie usa duas unidades diferentes dependendo da direção:

| Direção | Unidade | Escala | Exemplo R$ 30,00 |
|---------|---------|--------|-------------------|
| **Requisição enviada** (request body) | centavos | BRL x 100 | `3000` |
| **Resposta recebida** (response body) | unidades base | BRL x 10.000 | `300000` |

### Conversão rápida

- **Para enviar**: multiplique o valor em reais por 100. R$ 30,00 = `3000`
- **Para ler respostas**: divida por 10.000. `300000` / 10.000 = R$ 30,00
- **Nunca use ponto flutuante** -- sempre inteiros

### Tabela de referência

| Valor BRL | Request (centavos) | Response (unidades base) |
|-----------|--------------------|--------------------------|
| R$ 1,00 | `100` | `10000` |
| R$ 30,00 | `3000` | `300000` |
| R$ 150,50 | `15050` | `1505000` |
| R$ 1.000,00 | `100000` | `10000000` |

::: danger Atenção
O valor `3000` na requisição (R$ 30,00) vira `300000` na resposta. São o mesmo valor em BRL, representado em unidades diferentes. Se você dividir a resposta por 100 em vez de 10.000, obterá R$ 3.000,00 em vez de R$ 30,00.
:::

## External ID

O campo `external_id` é um identificador opcional que você define no seu sistema para rastrear transações. Ele é aceito nos endpoints de cash-in e cash-out e devolvido em todas as respostas e webhooks associados.

| Atributo | Valor |
|----------|-------|
| Obrigatório | Não |
| Tamanho máximo | 128 caracteres |
| Caracteres permitidos | Alfanuméricos, `.`, `_`, `:`, `-` |
| Regex | `^[a-zA-Z0-9._:\-]+$` |
| Exemplo | `"order-9876"`, `"invoice-4521"`, `"ref:2026-03-07:001"` |

Além de ser retornado nas respostas, você pode consultar uma transação pelo `external_id`:

```
GET /api/external/transactions/ref/{external_id}
```

::: tip Rastreamento
Use o `external_id` para correlacionar transações da Monetarie com pedidos, faturas ou registros do seu sistema. Valores duplicados não são rejeitados, mas recomendamos unicidade para facilitar a conciliação.
:::

## Idempotência

Requisições de escrita (POST) aceitam o header `Idempotency-Key` para evitar processamento duplicado. Se a mesma chave for enviada em uma segunda requisição idêntica dentro de 24 horas, a API retorna a resposta original cacheada em vez de processar novamente.

```
Idempotency-Key: unique-request-id-123
```

| Atributo | Valor |
|----------|-------|
| Header | `Idempotency-Key` |
| Tamanho máximo | 256 caracteres |
| TTL do cache | 24 horas |
| Aplica-se a | Apenas POST (cash-in, cash-out, refund, webhooks, CPF) |
| Resposta replay | Header `X-Idempotent-Replay: true` |

::: warning Importante
A chave de idempotência considera método + path + chave. Duas requisições para endpoints diferentes com a mesma chave são tratadas como operações distintas.
:::

## Status de Transação

Monetarie usa um **vocabulário único** entre POST responses, GET responses e webhook bodies - o mesmo valor aparece em todas as superfícies. Veja [PIX Lifecycle](/pix-lifecycle) para o mapa completo.

### Cash In (Recebimentos)

| Status | Onde aparece | Descrição |
|--------|--------------|-----------|
| `active` | POST `/pix/cash-in` response | QR Code recém-gerado |
| `created` | Webhook `pix.charge.created` body | QR Code criado |
| `paid` | Webhook `pix.charge.paid` body | **Terminal.** PIX recebido e creditado |
| `settled` | GET `/transactions/:id` response | **Terminal.** Mesmo que `paid` - transação já em `transactions` |
| `pending` | GET quando QR ainda não foi pago | QR ativo, aguardando pagamento |
| `expired` | GET quando QR expirou | QR não foi pago dentro do TTL |
| `cancelled` | GET quando QR foi cancelado | Cobrança cancelada pelo merchant |

### Cash Out (Envios)

| Status | Onde aparece | Descrição |
|--------|--------------|-----------|
| `accepted` | POST `/pix/cash-out` response (HTTP 202) | Intermediário - aceito para processamento assíncrono |
| `processing` | Webhook `pix.payout.processing` + GET enquanto em voo | Intermediário - enviado ao SPI, aguardando BACEN |
| `settled` | Webhook `pix.payout.confirmed` + GET quando liquidado + POST response (HTTP 200 fast-track) | **Terminal de sucesso.** Débito confirmado pelo SPI/BACEN |
| `rejected` | Webhook `pix.payout.failed` body | **Terminal de falha.** Rejeitado pelo SPI, hold liberado |
| `failed` | GET `/transactions/:id` quando falhou | **Terminal de falha.** Mesmo que `rejected`, mas aparece no GET |
| `returned` | Webhook `pix.payout.returned` body | PIX enviado devolvido após liquidação (total ou parcial) |

::: tip Regra de ouro para conciliação
Só trate como final quando receber `pix.payout.confirmed` (status `settled`) ou `pix.payout.failed` (status `rejected`). `accepted` e `processing` são intermediários.
:::

## End-to-End ID (E2E ID)

Identificador único de uma transação PIX no ecossistema do Banco Central. Formato padrão:

```
E{ISPB}{YYYYMMDDHHMM}{sequencial}
```

**Exemplo:** `E46026562202603071530000001`

| Componente | Valor | Descrição |
|------------|-------|-----------|
| `E` | Prefixo fixo | Identifica como E2E ID |
| `46026562` | ISPB da Monetarie | 8 dígitos |
| `202603071530` | Data e hora UTC | AAAAMMDDHHMM (12 dígitos) |
| `000001` | Sequencial | 6 dígitos |

O E2E ID é gerado automaticamente pela Monetarie e retornado na resposta de cada operação PIX. Use-o para rastrear transações entre instituições.

## Tipos de Chave PIX

| Tipo | Formato | Exemplo | Limite PF | Limite PJ |
|------|---------|---------|-----------|-----------|
| `cpf` | 11 dígitos | `12345678901` | 1 | -- |
| `cnpj` | 14 dígitos | `12345678000190` | -- | 1 |
| `email` | E-mail válido | `contato@empresa.com.br` | 5 | 20 |
| `phone` | DDD + número (11 dígitos) | `11999998888` | 5 | 20 |
| `evp` | UUID v4 (chave aleatória) | `a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d` | 5 | 20 |

## Padrão de Resposta

Todas as respostas da API seguem o padrão:

### Sucesso

```json
{
  "worked": true,
  ...
}
```

### Erro

```json
{
  "worked": false,
  "detail": "Descrição do erro"
}
```

O campo `worked` indica se a operação foi bem-sucedida (`true`) ou falhou (`false`). Em caso de erro, o campo `detail` descreve o motivo.
