# PIX Cash-Out Copia y Pega

Realiza una transferencia PIX utilizando el codigo EMV (copia y pega) extraido de un QR Code PIX.

## Endpoint

```
POST /api/external/pix/cash-out
```

## Headers

| Header | Tipo | Obligatorio | Descripcion |
|--------|------|-------------|-------------|
| `Authorization` | String | Si | `ApiKey {client_id}:{client_secret}` |
| `Content-Type` | String | Si | `application/json` |
| `hmac` | String | Si | Firma HMAC-SHA512 del body (hex) |
| `Idempotency-Key` | String | No | Clave unica para evitar procesamiento duplicado (max 256 chars). Comportamiento identico al documentado en [PIX Cash-Out por Clave](/es/pix-cashout-key#headers) |

::: danger Permiso obligatorio
La API Key **debe** tener el permiso `transfer:write` para enviar PIX. Sin el, la solicitud retorna `403 Forbidden`. Vea [como configurar permisos](/es/auth-token#permisos-permissions).
:::

## Request Body

| Campo | Tipo | Obligatorio | Descripcion |
|-------|------|-------------|-------------|
| `amount` | Integer | Si | Valor en **centavos**. R$ 30,00 = `3000`. **En QR dinamico, este valor es sobrescrito por la consulta a la URL del QR** - vea abajo |
| `emv` | String | Si | Codigo EMV copia y pega del QR Code PIX. El alias `codigo_copia_cola` tambien es aceptado pero `emv` es canonico - prefieralo |
| `description` | String | No | Descripcion de la transferencia (max 140 caracteres) |
| `external_id` | String | No | Identificador de su sistema para rastreo. Max 128 chars despues de `trim`. Solo caracteres `a-zA-Z0-9._:-`. Retornado en respuestas y webhooks. **Valores invalidos son silenciosamente descartados** (transaccion prosigue con `external_id: null`). Vea [PIX Cash-Out por Clave](/es/pix-cashout-key#request-body) para detalles. |
| `end_to_end_id` | String | No | End-to-End ID en formato BACEN. **Recomendado omitir** - el backend genera determinista. Solo envie en escenario de reprocesamiento coordinado |
| `recipient_document` | String | No* | CPF (11 digitos) o CNPJ (14 digitos) del destinatario; entrada formateada es aceptada y normalizada a digitos. **Opcional por default**; se vuelve **condicionalmente obligatorio** cuando el control **opt-in** "bloquear PIX-OUT a CNPJ" esta activado en la cuenta pagadora y la clave extraida del EMV no es un CPF/CNPJ. Mismo comportamiento y errores (`cnpj_out_document_required`, `cnpj_out_blocked`) que [PIX Cash-Out por Clave](/es/pix-cashout-key#control-opt-in-bloquear-pix-out-a-cnpj). |

::: tip Codigo Copia y Pega
El campo `emv` acepta el codigo EMV completo copiado de un QR Code PIX. La API extrae automaticamente la clave PIX, los datos del receptor y el valor original del cobro a partir del payload EMV. El backend valida el CRC-16/CCITT-FFFF y la estructura TLV antes de proseguir.
:::

::: info Control opt-in - ningun impacto por default
`recipient_document` solo es relevante cuando el control **opcional, por cuenta, desactivado por default** "bloquear PIX-OUT a CNPJ" esta activado en la cuenta pagadora. Mientras este desactivado (default), el campo es ignorado y ninguna integracion existente es afectada. Comportamiento y codigos de error completos en [PIX Cash-Out por Clave](/es/pix-cashout-key#control-opt-in-bloquear-pix-out-a-cnpj) y [Controles de Cuenta](/es/account-controls).
:::

### QR Estatico vs QR Dinamico

La API trata los dos tipos de forma distinta:

**QR Estatico** (PoIM=11, sin URL):
- La clave PIX y los metadatos vienen del propio payload EMV
- El `amount` enviado en la solicitud es **usado directamente** como valor de la transferencia
- No hay consulta externa - liquidacion inmediata despues de validacion DICT

**QR Dinamico** (PoIM=12, con URL en el tag 26/25):
- El backend hace `Provider.consult_qrcode` en la URL embebida en el payload EMV y recibe un JWS (BACEN Manual 2.9.0)
- El valor autoritativo viene de la respuesta JWS (`valor.original`) y **sobrescribe** el `amount` enviado por el cliente
- Si la consulta a la URL falla (timeout, JWS invalido, QR expirado en el emisor), retorna HTTP 422 con `detail: "QR Code dinamico nao pode ser resolvido"`
- Use el valor sobrescrito como fuente de la verdad - `net_amount` en la respuesta refleja el valor real cobrado

::: warning No confie en el valor enviado en QR dinamico
En QR dinamico, siempre consulte la respuesta del POST para obtener el `amount` efectivo. El backend ignora cualquier divergencia entre el valor enviado y el valor retornado por el emisor del QR - eso es exigencia BACEN.
:::

::: danger Valores monetarios
Los valores de **entrada** son en centavos (R$ 1,00 = `100`). Los valores de **respuesta** son en unidades base (R$ 1,00 = `10000`). Para convertir la respuesta a reales, divida por 10.000. **Nunca use punto flotante.**
:::

## Ejemplo

```bash
curl -X POST https://api.monetarie.com/api/external/pix/cash-out \
  -H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -H "hmac: $HMAC" \
  -d '{
    "amount": 3000,
    "emv": "00020126580014br.gov.bcb.pix0136a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d5204000053039865802BR5913NOME RECEBEDOR6008BRASILIA62070503***6304ABCD",
    "description": "Pagamento via QR Code",
    "external_id": "invoice-4521"
  }'
```

## Respuesta de Exito -- 200 / 202

```json
{
  "worked": true,
  "final": false,
  "transaction_id": "PIXOUT20260309a1b2c3d4e5f6",
  "end_to_end_id": "E46026562202603091530abcdef01",
  "external_id": "invoice-4521",
  "amount": 300000,
  "fee_amount": 350,
  "net_amount": 300350,
  "status": "accepted",
  "detail": "PIX enviado para processamento"
}
```

::: tip HTTP 200 vs 202
- **HTTP 200**: Transaccion ya liquidada (`final: true`, `status: "settled"`).
- **HTTP 202**: Transaccion aceptada para procesamiento (`final: false`). `status` puede ser `"accepted"` (flujo normal), `"queued"` (limite DICT, con reprocesamiento automatico) o `"pending_approval"` (aguardando aprobacion). Acompane el status via polling o webhook.
:::

| Campo | Tipo | Descripcion |
|-------|------|-------------|
| `worked` | Boolean | `true` indica que la solicitud fue aceptada |
| `final` | Boolean | `true` cuando la transaccion alcanzo estado terminal (liquidada o rechazada). `false` cuando aun en procesamiento |
| `transaction_id` | String | Identificador unico de la transaccion |
| `end_to_end_id` | String | Identificador End-to-End en el SPI/BACEN |
| `external_id` | String | Su identificador, retornado tal como fue enviado. `null` si no informado |
| `amount` | Integer | Valor de la transferencia en **unidades base** (÷ 10.000 para reales). `300000` = R$ 30,00. **En QR dinamico, refleja el valor autoritativo retornado por la consulta JWS - puede divergir del `amount` enviado en el request** |
| `fee_amount` | Integer | Tarifa cobrada en unidades base (÷ 10.000 para reales) |
| `net_amount` | Integer | Valor **bruto debitado** en la cuenta pagadora (`amount + fee_amount`) - no es el valor que el destinatario recibe. Vea la nota en [PIX Cash-Out por Clave](/es/pix-cashout-key#respuesta-de-exito-200-202) sobre la asimetria de semantica entre cash-out y cash-in |
| `status` | String | Uno de: `accepted`, `settled`, `queued`, `pending_approval`. Vea detalles en [PIX Cash-Out por Clave](/es/pix-cashout-key#respuesta-de-exito-200-202) |
| `detail` | String | Mensaje descriptivo |

## Codigos de Rechazo

Los rechazos del cash-out por EMV siguen exactamente el mismo patron del [PIX Cash-Out por Clave](/es/pix-cashout-key#codigos-de-rechazo) - dos formatos de body (Formato A `{status: "failed", errors: [...]}` y Formato B `{errors: {bad_request: "..."}}`), tres clases de error (validacion / integracion / rate-limit encolado), y los mismos vocabularios UPPERCASE × lowercase. Los items abajo destacan solo los codigos **especificos del camino EMV**.

### Errores de validacion especificos del EMV (HTTP 400 / 422)

| HTTP | Formato | Campo con codigo | Significado |
|---|---|---|---|
| 400 | B | `errors.bad_request: "invalid emv payload"` | Payload EMV malformado (CRC-16 invalido, TLV incompleto, tag obligatoria ausente) - detectado por el parser antes del Orchestrator |
| 400 | B | `errors.bad_request: "invalid or missing amount"` | `amount` ausente, cero, negativo o no-entero (QR estatico) |
| **422** | **A** | `errors[0].code: "same_institution_transfer"` | QR generado por cuenta Monetarie - PIX intra-institucional no soportado (use TEF). **Nota**: HTTP 422 (no 400), con shape `{status: "failed", errors: [{code: "same_institution_transfer", params: []}]}` |
| 422 | - | `detail: "QR Code dinamico nao pode ser resolvido"` | Falla en la consulta a la URL del QR dinamico (timeout, JWS invalido, QR expirado en el emisor) - este camino es tratado por el controller antes del Orchestrator, retorna shape legacy `{errors: {unprocessable_entity: "..."}}` |
| 422 | A | `errors[0].code: "insufficient_balance"` | Saldo disponible menor que `amount + fee_amount` |

### Otros errores

Para los codigos `dict_key_not_found`, `dict_key_blocked`, `dict_rate_limited` (sincronico), `dict_bucket_exhausted` (sincronico), `dict_lookup_failed`, `provider_rejected`, `provider_schema_error`, `provider_unknown_error` - **todos retornan HTTP 400 en el Formato A** (no 429 ni 503). Detalles en [PIX Cash-Out por Clave - Errores de integracion](/es/pix-cashout-key#errores-de-integracion-con-el-proveedor-dict-http-400).

### Rate-limit con retry automatico (HTTP 202 `queued`)

Cuando Monetarie detecta un limite DICT antes de llegar al proveedor, el cash-out permanece en procesamiento, entra en retry automatico y retorna HTTP 202 con `status: "queued"`. Detalles completos en [PIX Cash-Out por Clave - Rate-limit con retry automatico](/es/pix-cashout-key#rate-limit-con-retry-automatico-http-202-queued).

### Rechazos BACEN asincronicos

Despues de aceptacion inicial (HTTP 202), el SPI/BACEN puede rechazar via PACS.002 RJCT. Ese rechazo:

- **No altera la respuesta HTTP original** (ya fue enviada como 202)
- Aparece via `GET /transactions/:id` con `status: "failed"` + `reason_code` (AC03, AB03, ED05 etc.) + `reason_description` en ingles
- Dispara webhook `pix.payout.rejected` con los mismos campos estructurados

Vea la lista completa de codigos BACEN en [Consultar Cash-Out por ID](/es/pix-cashout-status).

## Proximos Pasos

Despues de crear la transferencia, acompane el status via:

- [Consultar por ID](/es/pix-cashout-status)
- [Consultar por E2E ID](/es/pix-cashout-e2e)
- [Consultar por Tag](/es/pix-cashout-tag)
- [Consultar por External ID](/es/pix-query-external-id) -- `GET /api/external/transactions/ref/{external_id}`

O reciba la confirmacion automaticamente via [Webhook](/es/webhooks).
