# Conceptos

Conceptos fundamentales para integrar con la API de Monetarie.

## Arquitectura de Seguridad

La API utiliza **tres capas de proteccion independientes**. Todas son obligatorias.

### Capa 1 -- API Key + Secret

Cada integrador recibe un par de credenciales (`client_id` y `client_secret`). El secret nunca se almacena en texto plano -- guardamos solo el hash. Cuando llega una solicitud, el secret enviado se compara con el hash almacenado. Si no coincide, la solicitud se rechaza inmediatamente, antes de llegar a la logica de negocio.

### Capa 2 -- Firma HMAC-SHA512 por Solicitud

Ademas de la API Key, cada solicitud transaccional (POST) necesita enviar una firma HMAC-SHA512 en el header `hmac`.

El proceso funciona asi:

1. El integrador serializa el body de la solicitud como JSON
2. Genera el hash HMAC-SHA512 usando el `client_secret` como clave
3. Envia el hash en hexadecimal en el header `hmac`

De nuestro lado, recalculamos el hash con el mismo metodo y lo comparamos con el valor recibido. Si cualquier byte del contenido fue alterado en el camino (por ejemplo, en un ataque man-in-the-middle), la firma no coincidira y la solicitud se rechaza con error 401. Esta comparacion se realiza en **tiempo constante** (constant-time comparison), lo que evita ataques de timing que intentan descubrir la firma byte a byte.

### Capa 3 -- Whitelist de IP Obligatoria

Cada API Key solo puede usarse desde IPs previamente autorizados. Incluso si alguien tiene acceso a las credenciales, no podra usar la API desde otro IP. Las solicitudes desde IPs no autorizados reciben `403 Forbidden`.

### Protecciones Adicionales

| Proteccion | Descripcion |
|------------|-------------|
| **Rate Limiting** | 90.000 solicitudes/minuto por IP. Endpoints sin autenticacion: 5 req/min |
| **AWS WAF** | Firewall de aplicacion protegiendo la API |
| **HTTPS obligatorio** | TLS 1.2 o superior en todas las conexiones |
| **HSTS** | HTTP Strict Transport Security habilitado |

Detalles completos: [Autenticacion](/es/auth-token) | [HMAC-SHA512](/es/hmac)

### Por que HMAC y no mTLS?

El mTLS (mutual TLS) agrega autenticacion via certificado X.509 a nivel de conexion. Es una capa valida, pero en nuestro escenario el HMAC por solicitud ofrece proteccion equivalente o mas adecuada:

| Aspecto | mTLS | HMAC-SHA512 |
|---------|------|-------------|
| **Que valida** | La conexion (canal TLS) | Cada solicitud individualmente |
| **Integridad del payload** | No -- si la conexion es confiable, las solicitudes pasan | Si -- cualquier alteracion en el body rechaza la solicitud |
| **Gestion operacional** | Compleja: emision, rotacion, revocacion, CRL/OCSP | Simple: genera nuevo par, actualiza, invalida anterior |
| **Incidentes comunes** | Certificados expirados o mal gestionados | Raros -- la clave es un string, sin ciclo de vida complejo |

El TLS ya garantiza cifrado del transporte. El HMAC entra como capa adicional, garantizando integridad y autenticidad del payload -- algo que el mTLS por si solo no cubre.

## Valores Monetarios

La API Monetarie usa dos unidades diferentes dependiendo de la direccion:

| Direccion | Unidad | Escala | Ejemplo R$ 30,00 |
|-----------|--------|--------|-------------------|
| **Solicitud enviada** (request body) | centavos | BRL x 100 | `3000` |
| **Respuesta recibida** (response body) | unidades base | BRL x 10.000 | `300000` |

### Conversion rapida

- **Para enviar**: multiplique el valor en reales por 100. R$ 30,00 = `3000`
- **Para leer respuestas**: divida por 10.000. `300000` / 10.000 = R$ 30,00
- **Nunca use punto flotante** -- siempre enteros

### Tabla de referencia

| 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 Atencion
El valor `3000` en la solicitud (R$ 30,00) se convierte en `300000` en la respuesta. Son el mismo valor en BRL, representado en unidades diferentes. Si divide la respuesta por 100 en vez de 10.000, obtendra R$ 3.000,00 en vez de R$ 30,00.
:::

## External ID

El campo `external_id` es un identificador opcional que usted define en su sistema para rastrear transacciones. Se acepta en los endpoints de cash-in y cash-out y se devuelve en todas las respuestas y webhooks asociados.

| Atributo | Valor |
|----------|-------|
| Obligatorio | No |
| Tamano maximo | 128 caracteres |
| Caracteres permitidos | Alfanumericos, `.`, `_`, `:`, `-` |
| Regex | `^[a-zA-Z0-9._:\-]+$` |
| Ejemplo | `"order-9876"`, `"invoice-4521"`, `"ref:2026-03-07:001"` |

Ademas de devolverse en las respuestas, puede consultar una transaccion por el `external_id`:

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

::: tip Rastreo
Use el `external_id` para correlacionar transacciones de Monetarie con pedidos, facturas o registros de su sistema. Los valores duplicados no se rechazan, pero recomendamos unicidad para facilitar la conciliacion.
:::

## Idempotencia

Las solicitudes de escritura (POST) aceptan el header `Idempotency-Key` para evitar procesamiento duplicado. Si la misma clave se envia en una segunda solicitud identica dentro de 24 horas, la API retorna la respuesta original cacheada en vez de procesar nuevamente.

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

| Atributo | Valor |
|----------|-------|
| Header | `Idempotency-Key` |
| Tamano maximo | 256 caracteres |
| TTL del cache | 24 horas |
| Se aplica a | Solo POST (cash-in, cash-out, refund, webhooks, CPF) |
| Respuesta replay | Header `X-Idempotent-Replay: true` |

::: warning Importante
La clave de idempotencia considera metodo + path + clave. Dos solicitudes para endpoints diferentes con la misma clave se tratan como operaciones distintas.
:::

## Estado de Transaccion

Monetarie usa un **vocabulario unico** entre respuestas POST, respuestas GET y cuerpos de webhook - el mismo valor aparece en todas las superficies. Vea [PIX Lifecycle](/es/pix-lifecycle) para el mapa completo.

### Cash In (Cobros)

| Estado | Donde aparece | Descripcion |
|--------|---------------|-------------|
| `active` | Respuesta POST `/pix/cash-in` | QR Code recien generado |
| `created` | Webhook `pix.charge.created` body | QR Code creado |
| `paid` | Webhook `pix.charge.paid` body | **Terminal.** PIX recibido y acreditado |
| `settled` | Respuesta GET `/transactions/:id` | **Terminal.** Igual que `paid` - transaccion ya en `transactions` |
| `pending` | GET cuando el QR aun no fue pagado | QR activo, esperando pago |
| `expired` | GET cuando el QR expiro | QR no fue pagado dentro del TTL |
| `cancelled` | GET cuando el QR fue cancelado | Cobro cancelado por el merchant |

### Cash Out (Envios)

| Estado | Donde aparece | Descripcion |
|--------|---------------|-------------|
| `accepted` | Respuesta POST `/pix/cash-out` (HTTP 202) | Intermedio - aceptado para procesamiento asincrono |
| `processing` | Webhook `pix.payout.processing` + GET durante el vuelo | Intermedio - enviado al SPI, esperando BACEN |
| `settled` | Webhook `pix.payout.confirmed` + GET cuando liquidado + respuesta POST (HTTP 200 fast-track) | **Estado terminal de exito.** Debito confirmado por el SPI/BACEN |
| `rejected` | Webhook `pix.payout.failed` body | **Estado terminal de fallo.** Rechazado por el SPI, hold liberado |
| `failed` | GET `/transactions/:id` cuando fallo | **Estado terminal de fallo.** Igual que `rejected`, pero aparece en GET |
| `returned` | Webhook `pix.payout.returned` body | PIX enviado devuelto despues de liquidacion (total o parcial) |

::: tip Regla de oro para conciliacion
Solo trate como final cuando reciba `pix.payout.confirmed` (estado `settled`) o `pix.payout.failed` (estado `rejected`). `accepted` y `processing` son intermedios.
:::

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

Identificador unico de una transaccion PIX en el ecosistema del Banco Central. Formato estandar:

```
E{ISPB}{YYYYMMDDHHMM}{secuencial}
```

**Ejemplo:** `E46026562202603071530000001`

| Componente | Valor | Descripcion |
|------------|-------|-------------|
| `E` | Prefijo fijo | Identifica como E2E ID |
| `46026562` | ISPB de Monetarie | 8 digitos |
| `202603071530` | Fecha y hora UTC | AAAAMMDDHHMI (12 digitos) |
| `000001` | Secuencial | 6 digitos |

El E2E ID se genera automaticamente por Monetarie y se devuelve en la respuesta de cada operacion PIX. Uselo para rastrear transacciones entre instituciones.

## Tipos de Clave PIX

| Tipo | Formato | Ejemplo | Limite PF | Limite PJ |
|------|---------|---------|-----------|-----------|
| `cpf` | 11 digitos | `12345678901` | 1 | -- |
| `cnpj` | 14 digitos | `12345678000190` | -- | 1 |
| `email` | E-mail valido | `contato@empresa.com.br` | 5 | 20 |
| `phone` | DDD + numero (11 digitos) | `11999998888` | 5 | 20 |
| `evp` | UUID v4 (clave aleatoria) | `a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d` | 5 | 20 |

## Patron de Respuesta

Todas las respuestas de la API siguen el patron:

### Exito

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

### Error

```json
{
  "worked": false,
  "detail": "Descripcion del error"
}
```

El campo `worked` indica si la operacion fue exitosa (`true`) o fallo (`false`). En caso de error, el campo `detail` describe el motivo.
