# Consultar Cash-In por ID

Consulta o status e detalhes de uma transação PIX pelo ID da transação.

## Endpoint

```
GET /api/external/transactions/:id
```

## Headers

| Header | Tipo | Obrigatório | Descrição |
|--------|------|-------------|-----------|
| `Authorization` | String | Sim | `ApiKey {client_id}:{client_secret}` |
| `X-Key-Case` | String | Não | Defina como `camelCase` para receber os campos da resposta em camelCase (padrão é snake_case) |

## Path Parameters

| Parâmetro | Tipo | Obrigatório | Descrição |
|-----------|------|-------------|-----------|
| `id` | String | Sim | ID da transação (`transaction_id`) |

## Exemplo

```bash
curl -X GET https://api.monetarie.com/api/external/transactions/7popu57v6us7p6pcicgq12345 \
  -H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET"
```

## Resposta de Sucesso (200)

```json
{
  "worked": true,
  "data": {
    "id": "a1b2c3d4e5f64a7b8c9d0e1f2a3b4c5d",
    "transaction_id": "7popu57v6us7p6pcicgq12345",
    "end_to_end_id": "E46026562202603071530000001",
    "external_id": "order-9876",
    "type": "pix",
    "status": "settled",
    "amount": 300000,
    "fee_amount": 0,
    "net_amount": 300000,
    "description": "Pedido #1234",
    "direction": "inbound",
    "counterparty_name": "Maria Santos",
    "payer_document": "12345678901",
    "recipient_document": "46026562000165",
    "recipient_key": "contato@empresa.com.br",
    "payer_ispb": "60701190",
    "payer_bank_name": "ITAU UNIBANCO S.A.",
    "created_at": "2026-03-07T15:30:00Z",
    "completed_at": "2026-03-07T15:30:02Z"
  }
}
```

| Campo | Tipo | Descrição |
|-------|------|-----------|
| `worked` | Boolean | `true` indica sucesso na operação |
| `data.id` | String | ID interno da transação. Para transações **liquidadas** (shape padrão acima), o formato é **hex lowercase de 32 caracteres sem hifens** (ex: `a1b2c3d4e5f64a7b8c9d0e1f2a3b4c5d`). Em outros shapes (QR ainda não linkado, falhas), o campo pode não estar presente ou pode ter outro formato (UUID com hifens quando derivado diretamente do `qrcodes.id`) |
| `data.transaction_id` | String | Identificador público da transação. Para PIX IN via este pipeline, assume o formato `PIXIN` + E2E (ex: `PIXINE46026562202603071530000001`) -- **o prefixo é sempre `PIXIN` seguido do próprio E2E** (que começa com `E`). Use como identificador opaco; **não** tente extrair o E2E via string-split sem cuidado, pois a concatenação não tem separador |
| `data.end_to_end_id` | String | ID ponta-a-ponta do BACEN (E2E, formato `^E\d{8}[a-zA-Z0-9]{22,26}$`) |
| `data.external_id` | String \| null | Identificador do seu sistema. `null` se não informado na criação |
| `data.type` | String | `pix` para transações liquidadas via pipeline normal. `pix_qrcode` quando o `id` consultado resolve apenas em `qrcodes` (QR ainda `pending`/`expired`/`cancelled`, OU QR já pago mas ainda não vinculado à linha final em `transactions` -- janela curta pós-settlement). `pix_return` em devoluções recebidas (ver [Devoluções PIX](/pix-refund)) |
| `data.status` | String | Status atual (veja tabela abaixo) |
| `data.amount` | Integer | Valor em **unidades base** (÷ 10.000 para reais). `300000` = R$ 30,00 |
| `data.fee_amount` | Integer | Valor da tarifa em unidades base |
| `data.net_amount` | Integer | Valor líquido em unidades base (para PIX IN, normalmente `amount - fee_amount`) |
| `data.description` | String \| null | Descrição da transação |
| `data.direction` | String | `inbound` para recebimentos, `outbound` para envios |
| `data.counterparty_name` | String \| null | Para `inbound`, nome do **pagador**; para `outbound`, nome do **recebedor** |
| `data.payer_document` | String \| null | CPF/CNPJ do pagador. Presente em recebimentos quando o banco emissor enviar |
| `data.recipient_document` | String \| null | CPF/CNPJ do recebedor |
| `data.recipient_key` | String \| null | Chave PIX usada no recebimento (evp/email/phone/cpf/cnpj) |
| `data.payer_ispb` | String \| null | ISPB de 8 dígitos do banco pagador |
| `data.payer_bank_name` | String \| null | Nome do banco pagador (resolvido a partir do ISPB) |
| `data.created_at` | String | Data de criação (ISO 8601 em UTC) |
| `data.completed_at` | String \| null | Data de conclusão (ISO 8601 em UTC), `null` se ainda pendente |

::: info Endpoint também responde a envios
Apesar do foco deste documento em recebimentos, `GET /api/external/transactions/:id` é **o mesmo endpoint para PIX IN e PIX OUT**. Quando o `id` resolver para um envio em processamento ou uma falha, a resposta tem o formato descrito em [Consultar Cash-Out por ID](/pix-cashout-status) (`status: processing` / `status: failed` com `reason_code`/`reason_description`).
:::

## Status Possíveis

Valores possíveis retornados no campo `status`:

| Status | Origem | Descrição |
|--------|--------|-----------|
| `settled` | `transactions` | **Estado final de sucesso.** Pagamento recebido e creditado na conta. Mesmo valor do webhook `pix.charge.paid` com `status: "paid"`. |
| `settled` | `qrcodes` (fallback) | Emitido também quando o QR tem `paid_at` mas a linha final em `transactions` ainda não foi persistida -- janela curta entre Phase 2 ACCC do BACEN e a persistência local. Nesse caso `type: "pix_qrcode"` e alguns campos (`end_to_end_id`, `counterparty_name`, `payer_*`) podem vir populados apenas parcialmente |
| `pending` | `qrcodes` | QR Code gerado, aguardando pagamento |
| `expired` | `qrcodes` | QR Code expirado (TTL configurável por conta, padrão 1h). Também aplicado automaticamente em QRs cuja `expires_at` já passou mas ainda não foram processados pelo worker |
| `cancelled` | `qrcodes` | QR Code cancelado manualmente pelo merchant (via portal) ou em operações administrativas (ex: migração em massa estático→dinâmico de abril/2026) |
| `failed` | `failed_transactions` | Tentativa de crédito **rejeitada** (ex: limite excedido, conta bloqueada, duplicidade, rejeição BACEN). O campo `reason_code` indica o motivo estruturado. |

::: info Controles opt-in de recebimento - nenhum impacto por padrão
Se a conta recebedora tiver ativado um controle **opt-in** de recebimento ("verificação de pagador esperado" ou "bloquear recebimento de CNPJ"), um PIX recebido que não atenda ao critério é **rejeitado e devolvido ao pagador** (devolução BACEN) em vez de creditado - visível pelo status da transação e pelos webhooks. Esses controles vêm **desativados por padrão**; sem ativação, todos os recebimentos são processados normalmente. Veja [Controles de Conta](/account-controls).
:::

::: info Quando `failed` é emitido
Embora menos frequente do que em cash-out, recebimentos **podem** falhar em cenários específicos: rejeição do BACEN pós-ACSP (ex: `AC03`, `AM02`, `DUPL`), limite operacional excedido, conta destinatária bloqueada ou inexistente. Nesses casos, o registro aparece em `failed_transactions` com `direction = "inbound"` e o endpoint retorna o seguinte formato adicional (campos exclusivos do caminho `failed`):

```json
{
  "worked": true,
  "data": {
    "status": "failed",
    "transaction_id": "PIXINE46026562202603071530000001",
    "end_to_end_id": "E46026562202603071530000001",
    "amount": 300000,
    "fee_amount": 0,
    "external_id": "order-9876",
    "type": "pix",
    "direction": "inbound",
    "payment_status": "failed",
    "failure_reason": "rejected: AC03",
    "reason_code": "AC03",
    "reason_description": "Invalid creditor account number",
    "started_at": "2026-03-07T15:30:00Z",
    "failed_at": "2026-03-07T15:30:02Z",
    "recipient": {
      "name": "Empresa Exemplo LTDA",
      "key": "contato@empresa.com.br"
    }
  }
}
```

Quando você consulta pelo `tx_id` do QR e o QR ainda não foi pago, o endpoint retorna `pending`/`expired`/`cancelled` (derivado de `qrcodes`, sem linha em `transactions`). Nesse caso o payload é reduzido: `id`, `transaction_id` (= `tx_id`), `amount`, `status`, `description`, `recipient_key` (chave PIX do QR), `type: "pix_qrcode"`, `direction: "credit"`, `created_at` (quando o QR foi gerado) e `completed_at` (quando pago, ou `null`). O campo `counterparty_name` é `null` neste shape (só é preenchido quando há linha real em `transactions`).

**Nota sobre cancelamento em massa**: durante a migração de QRs estáticos para dinâmicos em abril/2026, um lote de QRs estáticos com valor fixo ativos foi cancelado administrativamente (status `cancelled`). Consultas retornam esse status normalmente; não é necessário tratamento especial.
:::

## Resposta de Erro (404)

```json
{
  "worked": false,
  "detail": "Transação não encontrada"
}
```

## Resposta de Erro (401)

```json
{
  "error": {
    "status": 401,
    "message": "Missing API key credentials. Use Authorization: ApiKey <client_id>:<client_secret>"
  }
}
```

::: tip Polling vs Webhook
Para acompanhar o status de uma cobrança, prefira utilizar [Webhooks](/webhooks) em vez de polling. Caso precise consultar, use intervalos de no mínimo 5 segundos.
:::
