# PIX

Envio de PIX, chaves DICT, consulta, cobrança imediata e com vencimento, leitura de BR Code, portabilidade de chave, MED (recuperação de fundos) e infrações DICT. Valores de entrada em **centavos**. As operações que tocam uma conta usam `account_id`, que precisa pertencer ao parceiro do token.

## Enviar PIX

```http
POST /api/partner/v1/pix/payments
Authorization: Bearer {{access_token}}
Content-Type: application/json
Idempotency-Key: {{uuid}}

{
  "account_id": 1042,
  "amount": 5000,
  "pixKey": "destino@exemplo.com.br",
  "recipientIspb": "12345678",
  "description": "Pagamento pedido 4210"
}
```

- **Escopo:** `pix:write` · **Obrigatórios:** `account_id`, `amount`, `pixKey`, `recipientIspb`.

Resposta `202`:

```json
{ "status": "accepted", "transactionId": "PIXOUT20260711e5c2d176f788c964967f", "endToEndId": "E4602656220260711...", "amount": 5000, "message": "PIX enviado para processamento" }
```

O `status: "accepted"` é o reconhecimento da API, não o desfecho. Acompanhe pela consulta de status e pelos webhooks `pix.payout.confirmed` e `pix.payout.failed`. Uma conta bloqueada responde `422` com `code: "account_blocked"`; saldo insuficiente responde `422`.

## Consultar status

```http
GET /api/partner/v1/pix/payments/{id}
Authorization: Bearer {{access_token}}
```

- **Escopo:** `pix:read`

```json
{
  "data": {
    "transactionId": "PIXOUT20260711...",
    "type": "pix",
    "status": "settled",
    "amount": 5000,
    "fee": 4,
    "recipientKey": "destino@exemplo.com.br",
    "endToEndId": "E4602656220260711...",
    "errorReason": null,
    "createdAt": "2026-07-11T10:12:00Z",
    "completedAt": "2026-07-11T10:12:01Z"
  }
}
```

O campo `fee` traz a tarifa cobrada por esta transação, em **centavos** (`0` quando não há tarifa).

### Estados de uma transação

| Status | Significado | Final |
|---|---|---|
| `processing` | Em andamento, aguardando a liquidação | Não |
| `accepted` | Aceite intermediário recebido | Não |
| `settled` / `confirmed` / `completed` | Liquidada com sucesso | Sim |
| `rejected` | Rejeitada | Sim |
| `timeout` | Sem resposta no prazo, valor devolvido ao pagador | Sim |
| `cancelled` | Cancelada | Sim |
| `refunded` | Devolvida após liquidação | Sim |

Um id desconhecido responde `404`; uma transação de outro parceiro responde `403`.

## Devolver PIX

Devolve um PIX **recebido** pela conta do parceiro. A devolução é emitida pela Monetarie dentro da janela regulamentar de **90 dias** contados da liquidação original. A devolução de um PIX que você **enviou** é feita pelo recebedor e chega a você pelo webhook `pix.payout.returned`, não por este endpoint.

```http
POST /api/partner/v1/pix/payments/{id}/refund
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "account_id": 1042, "amount": 5000, "reason": "MD06", "description": "Devolução solicitada pelo pagador" }
```

- **Escopo:** `pix:write` · O `id` no caminho é a transação original recebida. **Obrigatórios:** `account_id`, `amount` (centavos).
- `reason` é opcional (padrão `MD06`) e restrito à lista `MD06`, `SL02`, `BE08`, `FR01`, `AC03`, `AC06`, `AC07`, `AC14`, `AG03`, `AG13`, `AM09`, `AM18`, `RR04`.
- Devolução **parcial** é permitida, até o restante devolvível da transação; devoluções pendentes contam contra o restante.

Resposta `202` (aceite, não o desfecho):

```json
{
  "data": {
    "refundId": "PIXRET20260718b1c2d3e4f5a6",
    "originalTransactionId": "PIXIN20260718abc123",
    "endToEndId": "E4602656220260718091500aa11bb22c",
    "amount": 5000,
    "remainingRefundable": 5000,
    "status": "processing",
    "message": "Devolução PIX enviada para processamento"
  }
}
```

Recusas: `404` quando a original não existe ou pertence a outra conta; `422` fora da janela de 90 dias, valor acima do restante devolvível, razão fora da lista ou saldo insuficiente. O desfecho chega pelos webhooks `pix.refund.completed` e `pix.refund.failed`, descritos em [Webhooks](/endpoints/webhooks).

## Trilha de devoluções

```http
GET /api/partner/v1/pix/payments/{id}/refunds?account_id=1042
Authorization: Bearer {{access_token}}
```

- **Escopo:** `pix:read`

Devolve a transação original, o restante devolvível e a lista de devoluções já solicitadas:

```json
{
  "data": {
    "original": { "transactionId": "PIXIN20260718abc123", "endToEndId": "E4602656220260718091500aa11bb22c", "amount": 10000, "status": "settled", "completedAt": "2026-07-18T09:15:01Z" },
    "remainingRefundable": 5000,
    "refunds": [
      { "refundId": "PIXRET20260718b1c2d3e4f5a6", "rtrId": "D46026562202607180920aabbccddeef", "amount": 5000, "status": "settled", "reasonCode": "MD06", "reasonDescription": "Devolução solicitada pelo pagador", "requestedAt": "2026-07-18T09:20:00Z", "completedAt": "2026-07-18T09:20:02Z" }
    ]
  }
}
```

O campo `rtrId` fica nulo enquanto a devolução processa. Valores em **centavos**. Um id inexistente ou de outra conta responde `404`.

## Chaves PIX (DICT)

### Registrar chave

```http
POST /api/partner/v1/pix/keys
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "account_id": 1042, "keyType": "EMAIL", "key": "maria@exemplo.com.br" }
```

- **Escopo:** `pix:write` · `keyType`: `CPF`, `CNPJ`, `PHONE`, `EMAIL` ou `EVP`.

Para `CPF` e `CNPJ`, a chave é o documento do titular. Para `EVP` (chave aleatória), a chave é gerada e devolvida na resposta. Para `PHONE` e `EMAIL`, informe o valor no campo `key`. Resposta `202`:

```json
{ "data": { "type": "email", "key": "maria@exemplo.com.br", "status": "pending" } }
```

O desfecho do registro chega pelo webhook `pix.key.registered`; exclusão, bloqueio e desbloqueio chegam por `pix.key.deleted`, `pix.key.blocked` e `pix.key.unblocked`, descritos em [Webhooks](/endpoints/webhooks).

### Listar e excluir chaves

```http
GET    /api/partner/v1/pix/keys?account_id=1042      # listar (pix:read)
DELETE /api/partner/v1/pix/keys/{key}?account_id=1042 # excluir (pix:write)
Authorization: Bearer {{access_token}}
```

A listagem devolve `{ "data": [ { id, type, key, status, owner_name, created_at } ] }`. A exclusão responde `202` com `{ "message": "Exclusão de chave PIX enviada para processamento" }`.

### Consultar chave externa

```http
GET /api/partner/v1/pix/dict/{key}?accountId={id}
Authorization: Bearer {{access_token}}
```

- **Escopo:** `pix:read`
- **`accountId` é obrigatório.**

Resolve uma chave no diretório e devolve os dados do titular e da instituição, para pagar.

O BACEN exige, em toda consulta lookup-to-pay, o documento de **quem vai pagar**
(o cabeçalho `PI-PayerId` da API DICT). Esse documento é sempre o **titular da
conta informada em `accountId`**, e por isso o parâmetro é obrigatório. Não
existe consulta sem conta: a chamada morre antes de chegar ao diretório.

| Parâmetro | Obrigatório | Para que serve |
|---|---|---|
| `accountId` | **sim** | conta demandante. O documento do titular dela é enviado como `PI-PayerId` |
| `payerDocument` | não | **conferência apenas**. Se enviado, tem que bater com o titular de `accountId` |

`payerDocument` **não** é fonte do pagador. Ele existe só para o integrador
confirmar que está consultando em nome de quem pensa estar. Divergiu, a
requisição é recusada.

**Respostas de erro**

| HTTP | `code` | Quando |
|---|---|---|
| `422` | `payer_account_required` | `accountId` ausente, ou a conta não tem titular com documento |
| `422` | `payer_document_mismatch` | `payerDocument` não confere com o titular de `accountId` |
| `404` | `key_not_found` | chave não registrada no DICT |
| `403` | | a conta em `accountId` não pertence à sua entidade |

Chave inexistente devolve **`404` com corpo de erro estruturado**, nunca um
`200` de sucesso carregando `status: "not_found"` no corpo.

## Cobrança imediata

```http
POST /api/partner/v1/pix/charges
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "account_id": 1042, "amount": 2599, "description": "Pedido 4210" }
```

- **Escopo:** `pix:write` · **Obrigatórios:** `account_id`, `amount`.

A cobrança dinâmica é gerada pelo motor canônico da plataforma: o BR Code aponta para a `locationUrl`, que serve o payload assinado (JWS) da cobrança, e o valor vive nesse payload.

Resposta `201`:

```json
{ "data": { "account_id": 1042, "brcode": "00020101021226...", "qrcode_base64": "data:image/png;base64,...", "amount": 2599, "description": "Pedido 4210", "txId": "GGFOZZRTXJOAMJPVLWOIIWLRMALW2", "locationUrl": "https://qrcode.monetarie.com/qr/v2/<token>", "expiresAt": "2026-07-11T03:22:23Z" } }
```

## QR estático (valor em aberto ou fixo)

```http
POST /api/partner/v1/pix/qrcodes/static
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "account_id": 1042, "description": "Doacao" }
```

- **Escopo:** `pix:write` · **Obrigatório:** `account_id`. · **Opcionais:** `amount` (centavos), `pix_key`, `description`, `city`.

Sem `amount`, o QR sai com **valor em aberto**: a tag de valor não é emitida e o pagador digita o valor no app dele. Com `amount`, o valor fica fixo no código. O QR estático é reutilizável e não expira.

Resposta `201`:

```json
{ "data": { "account_id": 1042, "type": "static", "brcode": "00020101021126...", "qrcode_base64": "data:image/png;base64,...", "amount": null, "description": "Doacao", "txId": "A1B2C3D4E5", "pixKey": "12345678901" } }
```

## Cobrança com vencimento (CobV)

```http
POST /api/partner/v1/pix/cobv
Authorization: Bearer {{access_token}}
Content-Type: application/json

{
  "account_id": 1042,
  "amount": 12345,
  "due_date": "2026-09-30",
  "interest_type": "PERCENTUAL",
  "interest_value": "1.00",
  "fine_type": "FIXO",
  "fine_value": "5.00",
  "discount_type": "FIXO",
  "discount_value": "2.00",
  "debtor_name": "Cliente Exemplo",
  "debtor_document": "12345678909"
}
```

- **Escopo:** `pix:write` · **Obrigatórios:** `account_id`, `amount`, `due_date` (`AAAA-MM-DD`).
- **Opcionais:** `fine_type`/`fine_value`, `interest_type`/`interest_value`, `discount_type`/`discount_value` (cada tipo aceita `FIXO` ou `PERCENTUAL`), `rebate_value`, `debtor_name`, `debtor_document`.

Resposta `201`:

```json
{
  "data": {
    "account_id": 1042,
    "type": "cobv",
    "brcode": "00020101021226960014br.gov.bcb.pix2574...",
    "qrcode_base64": "data:image/png;base64,...",
    "amount": 12345,
    "dueDate": "2026-09-30",
    "txId": "GGFOZZRTXJOAMJPVLWOIIWLRMALW2",
    "locationUrl": "https://qrcode.monetarie.com/qr/v2/<token>",
    "expiresAt": "2026-07-11T03:23:11Z"
  }
}
```

O pagador resolve a cobrança pelo `locationUrl` no momento do pagamento, e o valor final é calculado conforme a data. Sem `due_date` a resposta é `400`.

## Consultar cobrança

```http
GET /api/partner/v1/pix/charges/{id}
Authorization: Bearer {{access_token}}
```

- **Escopo:** `pix:read` · Devolve `{ "data": { txId, account_id, type, status, amount, description, brcode, expiresAt, paidAt } }`.

## Ler um BR Code

```http
POST /api/partner/v1/pix/brcode/decode
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "brcode": "00020101021126..." }
```

- **Escopo:** `pix:write`

Decodifica um BR Code (copia e cola ou o conteúdo do QR), valida o CRC e devolve os campos interpretados, sem pagar:

```json
{ "data": { "pixKey": "destino@exemplo.com.br", "amount": 10000, "amountStr": "100.00", "recipientName": "MONETARIE SCD", "city": "SAO PAULO", "txId": "REVALTX123", "url": null, "type": "static", "countryCode": "BR", "currency": "986" } }
```

`amount` vem em **centavos**; é nulo quando o BR Code não fixa valor. Um BR Code inválido responde `422` com `code: "invalid_brcode"`; ausência do campo responde `400` com `code: "missing_brcode"`.

## Portabilidade de chave

Traz uma chave PIX para uma conta do parceiro. O ciclo é criar, acompanhar e, conforme o caso, confirmar ou cancelar. Toda operação é escopada à conta informada (`account_id`).

```http
POST /api/partner/v1/pix/claims
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "account_id": 1042, "key": "maria@exemplo.com.br", "keyType": "EMAIL" }
```

- **Escopo:** `pix:write` · **Obrigatórios:** `account_id`, `key`, `keyType`.

```http
GET  /api/partner/v1/pix/claims?account_id=1042        # listar (pix:read)
GET  /api/partner/v1/pix/claims/{id}?account_id=1042   # consultar (pix:read)
POST /api/partner/v1/pix/claims/{id}/confirm            # confirmar (pix:write)
POST /api/partner/v1/pix/claims/{id}/complete           # completar (pix:write)
POST /api/partner/v1/pix/claims/{id}/cancel             # cancelar (pix:write)
Authorization: Bearer {{access_token}}
```

A listagem devolve `{ "data": { "claims": [...], "total": 1 } }` somente com as reivindicações que envolvem a conta informada, como reivindicadora ou doadora (`claimer_account` ou `donor_account`); aceita os filtros opcionais `status`, `limit` (padrão 50) e `offset`. O confirmar é a ação da conta doadora; o completar é a ação da reivindicadora ao fim da portabilidade ou reivindicação de posse.

Cada resposta traz `{ "data": { ... } }` com o estado da reivindicação. Uma reivindicação que não envolve a conta informada responde `403`; um id desconhecido responde `404`.

Cada etapa da reivindicação também é notificada pelos webhooks `pix.claim.created`, `pix.claim.acknowledged`, `pix.claim.confirmed`, `pix.claim.cancelled` e `pix.claim.completed`, descritos em [Webhooks](/endpoints/webhooks).

## MED (recuperação de fundos)

O MED é o mecanismo de recuperação de fundos do PIX. Quando um cliente relata fraude ou golpe em um PIX enviado, você abre uma intervenção para tentar recuperar o valor junto à instituição recebedora.

### Abrir intervenção

```http
POST /api/partner/v1/pix/med
Authorization: Bearer {{access_token}}
Content-Type: application/json

{
  "account_id": 10024270,
  "end_to_end_id": "E4602656220260714210000aabbccdd0",
  "fraud_category": "SCAM",
  "details": "Cliente relata golpe na negociação"
}
```

- **Escopo:** `pix:write` · Corpo: `account_id`, `end_to_end_id`, `fraud_category` e `details` (descrição do caso).
- `fraud_category` aceita `FRAUDULENT_ACCESS`, `SCAM`, `ACCOUNT_TAKEOVER` ou `OTHER`.
- A transação do `end_to_end_id` precisa pertencer à conta informada; caso contrário a resposta é `422`.

Resposta `202`:

```json
{
  "data": {
    "medId": "REC-...",
    "status": "CREATED",
    "rootTransactionId": "E4602656220260714210000aabbccdd0",
    "fraudCategory": "SCAM",
    "createdAt": "2026-07-14T21:05:00Z"
  }
}
```

### Consultar e listar intervenções

```http
GET /api/partner/v1/pix/med/{id}?account_id=10024270   # consultar (pix:read)
GET /api/partner/v1/pix/med?account_id=10024270        # listar (pix:read)
Authorization: Bearer {{access_token}}
```

A consulta responde `404` quando a intervenção não pertence à conta informada. A listagem aceita `limit` (padrão 50) e devolve `{ "data": { "recoveries": [ { medId, status, rootTransactionId, fraudCategory, createdAt } ], "total": 1 } }`, somente com as intervenções cuja transação raiz envolve a conta.

### Cancelar intervenção

```http
POST /api/partner/v1/pix/med/{id}/cancel
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "account_id": 10024270 }
```

- **Escopo:** `pix:write` · Responde `404` quando a intervenção não pertence à conta informada.

A resposta traz o estado atualizado em `data`. O cancelamento também é notificado pelo webhook `pix.med.cancelled`.

### Grafo de rastreamento

```http
GET /api/partner/v1/pix/med/{id}/graph?account_id=10024270
Authorization: Bearer {{access_token}}
```

- **Escopo:** `pix:read` · Responde `404` quando a intervenção não pertence à conta informada.

Devolve em `data` o grafo de rastreamento dos fundos da intervenção, no formato do arranjo PIX.

### Solicitar devolução dos fundos

```http
POST /api/partner/v1/pix/med/{id}/refund
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "account_id": 10024270, "amount": 5000 }
```

- **Escopo:** `pix:write` · `amount` (centavos) é opcional: sem ele, a devolução sai pelo valor integral da transação raiz.

Resposta `202` com `data` (`refundId`, `recoveryId`, `status`, `amount`), o aceite da solicitação, não o desfecho.

Acompanhe o andamento das intervenções pelos webhooks `pix.med.created`, `pix.med.completed` e `pix.med.cancelled`, descritos em [Webhooks](/endpoints/webhooks).

## Infrações DICT

Relatos de infração sobre transações PIX da conta (marcação de fraude no DICT), e a defesa do cliente quando uma infração aberta por outra instituição bloqueia valores cautelarmente.

### Abrir relato

```http
POST /api/partner/v1/pix/infractions
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "account_id": 10024270, "end_to_end_id": "E4602656220260714210000aabbccdd0", "details": "Cliente relata fraude na transação" }
```

- **Escopo:** `pix:write` · **Obrigatórios:** `account_id`, `end_to_end_id`. `details` descreve o caso.
- A transação do `end_to_end_id` precisa pertencer à conta informada; caso contrário a resposta é `422`.

Resposta `202` com `data` (`infractionId`, `status`, `endToEndId`, `debtorIspb`, `creditorIspb`, `analysisResult`, `analysisDetails`, `createdAt`, `updatedAt`), o aceite do relato, não o desfecho da análise.

### Listar e consultar

```http
GET /api/partner/v1/pix/infractions?account_id=10024270          # listar (pix:read)
GET /api/partner/v1/pix/infractions/{id}?account_id=10024270     # consultar (pix:read)
Authorization: Bearer {{access_token}}
```

A listagem aceita `limit` (padrão 50) e `offset`, e devolve `{ "data": { "infractions": [...], "total": 1 } }`, somente com relatos sobre transações da conta. Uma infração que não envolve a conta responde `404`.

### Cancelar relato

```http
POST /api/partner/v1/pix/infractions/{id}/cancel
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "account_id": 10024270 }
```

- **Escopo:** `pix:write` · Mesmo escopo da consulta: infração que não envolve a conta responde `404`.

### Enviar defesa

Quando uma infração aberta por outra instituição bloqueia valores da conta cautelarmente, o cliente pode apresentar defesa.

```http
POST /api/partner/v1/pix/infractions/{id}/defense
Authorization: Bearer {{access_token}}
Content-Type: application/json

{ "account_id": 10024270, "defense_text": "Prestação de serviço comprovada, nota fiscal 4210 anexada ao atendimento" }
```

- **Escopo:** `pix:write` · **Obrigatórios:** `account_id`, `defense_text`. O `id` aceita o identificador da infração ou do bloqueio.

Resposta `200`:

```json
{ "data": { "infractionId": "b17c9a02-4a2f-4d5e-9b1a-77e0a1c2d3e4", "blockId": "3f21aa8c-1b2c-4d5e-8f90-0a1b2c3d4e5f", "status": "defense_submitted" } }
```

Uma infração que não está mais em fase de defesa responde `422`. O registro da defesa também é notificado pelo webhook `pix.infraction.defense_submitted`, e o desfecho da análise por `pix.infraction.resolved`, descritos em [Webhooks](/endpoints/webhooks).
