# Documentação Completa da API Pix (LURI v2)

A API v2 da LURI disponibiliza a rota `/v2/charge/pix` para a geração, consulta e gerenciamento de cobranças **Pix**. O serviço contempla o QR Code **Estático (`static`)**, Pix **Dinâmico (`cob` - Cobrança Imediata)** e Pix **Cobrança com Vencimento (`cobv`)**.

---

## 1. Visão Geral e Recursos

- **Endpoint Único e Auto-Detecção**: O endpoint `POST /v2/charge/pix` analisa os atributos informados no payload para identificar automaticamente se a solicitação trata-se de um Pix **Estático**, **Dinâmico (COB)** ou **Cobrança com Vencimento (COBV)**.
- **Convenção Unificada de Valores ("Centavos")**: Todos os valores monetários e percentuais da API (como `amount`, `late_fee_amount`, `late_fee_percentage`, `interest_amount`, `interest_percentage`, `abatement_amount` e `discount[].amount`) devem ser enviados como **inteiros representando duas casas decimais** (sem ponto ou vírgula). Exemplo: `15000` = R$ 150,00; `200` = R$ 2,00 ou 2,00%; `100` = R$ 1,00 ou 1,00%.
- **Provisionamento e Cache Automático de Chaves Pix**: O sistema verifica se o estabelecimento vendedor (`seller`) possui uma chave Pix cadastrada. Se não houver, a chave é obtida ou gerada automaticamente e salva em cache para garantir performance máxima.
- **Suporte a Idempotência**: Requisições de mutação aceitam o cabeçalho `IdempotencyKey` (UUID) para evitar duplicidade de cobranças em cenários de re-tentativa por instabilidade de rede.
- **Integração a Webhooks**: Quando o pagamento do Pix é confirmado pela rede bancária, um evento de webhook é automaticamente enviado para a URL cadastrada no seu marketplace.

> **Nota de Compatibilidade (Legado):** Formatos anteriores de parâmetros (como `discount_percentage` e `discount_limit_date` diretamente em `billing_instructions`) permanecem 100% funcionais por retrocompatibilidade. Para novas integrações, utilize a estrutura padronizada documentada abaixo.

---

## 2. Autenticação e Rotas

Todas as requisições para a API Pix exigem autenticação via **JWT (Bearer Token)** assinado com algoritmo RS256 ou **Basic Auth** com o Token no campo `username`.

| Método | Endpoint | Autenticação | Descrição |
| :--- | :--- | :--- | :--- |
| `POST` | `/v2/charge/pix` | Basic Auth / JWT | Criação de cobrança Pix (`static`, `cob` ou `cobv`) |
| `GET` | `/v2/charge/pix/{id}` | Basic Auth / JWT | Consulta de uma cobrança Pix por ID (`id_pix`) ou `txid` |
| `GET` | `/v2/charge/pix/{id}/payments` | Basic Auth / JWT | Consulta de detalhes de pagamentos e devoluções do QR Code no liquidante com conciliação ativa |
| `GET` | `/v2/charge/pix/{id}/history` | Basic Auth / JWT | Histórico de eventos da cobrança Pix |
| `GET` | `/v2/charge/pix` | Basic Auth / JWT | Listagem paginada de cobranças Pix com filtros |
| `GET` | `/v2/charge/pix/all` | Basic Auth / JWT | Consulta consolidada de cobranças Pix diretamente no liquidante |

---

## 3. Regras de Auto-Detecção da Modalidade Pix

```
                               POST /v2/charge/pix
                                        │
                    ┌───────────────────┴───────────────────┐
                    ▼                                       ▼
        `payment_type` == "static"?             Possui `customer` E
                    │                    `payment_method.expiration_date`?
             SIM ───┴─── NÃO                                │
              │           │                          SIM ───┴─── NÃO
              ▼           │                           │           │
         [ESTÁTICO]       └───────────────────────────►           ▼
        (QR Code Fixo)                                ▼         [COB]
                                                   [COBV]     (Dinâmico
                                                (Vencimento)   Imediato)
```

1. **Cobrança com Vencimento (`cobv`)**:
   - **Critério**: O campo `payment_method.expiration_date` está preenchido (`>= hoje`) **E** os dados do pagador (`customer` com `taxpayer_id` e `name`) foram informados (ou `payment_type: "cobv"`).
   - **Data Limite (`payment_limit_date`)**: Opcional. Caso omitida, assume automaticamente `expiration_date + 90 dias`.
   - **Instruções Financeiras (`billing_instructions`)**: Aceita multa (`late_fee_amount` ou `late_fee_percentage`), juros (`interest_amount` ou `interest_percentage`), descontos (`discount`) e abatimento (`abatement_amount`), todos representados como inteiros em "centavos" (2 casas decimais).

2. **Cobrança Dinâmica / Imediata (`cob`)**:
   - **Critério**: Padrão quando `expiration_date` não é informado (ou `payment_type: "cob"`).
   - **Opções em `payment_method`**:
     - `expiration_seconds` (int, opcional): Tempo de expiração em segundos (`1` a `86400`, padrão `86400` = 24h).
     - `allow_amount_change` (bool, opcional): Permite que o pagador altere o valor na leitura (padrão `false`).
     - `payer_request` / `description` (string, opcional): Texto exibido ao pagador no momento da leitura do QR Code.
     - `additional_info` (objeto `{ "name": "...", "value": "..." }`, opcional): Campo adicional exibido no comprovante.

3. **QR Code Estático (`static`)**:
   - **Critério**: Quando `payment_type` é definido como `"static"`.

---

## 4. Referência de Campos (`POST /v2/charge/pix`)

| Campo | Tipo | Obrigatório | Descrição |
| :--- | :--- | :--- | :--- |
| `seller` | `string` | Sim | Identificador (`seller_id`) do estabelecimento recebedor. |
| `amount` | `integer` | Sim | Valor nominal da cobrança em centavos (mínimo `100` = R$ 1,00). |
| `reference_id` | `string` | Não | Identificador externo de conciliação do parceiro. |
| `installment` | `object` | Não | Objeto de identificação da parcela da venda (`{ "number": 1, "total": 12 }`). |
| `installment.number` | `integer` | Condicional | Número da parcela atual (`>= 1` e `<= installment.total`; obrigatório se `installment` for enviado). |
| `installment.total` | `integer` | Condicional | Quantidade total de parcelas da venda (`>= 1`; obrigatório se `installment` for enviado). |
| `payment_type` | `string` | Não | Força a modalidade: `"cobv"`, `"cob"` ou `"static"`. |
| `tags` | `array` | Não | Lista de strings para categorização da cobrança. |
| `customer` | `object` | Condicional | Obrigatório para `cobv`, opcional para `cob`. Contém `taxpayer_id` (CPF/CNPJ) e `name` (além de endereço/contato opcionais). |
| `payment_method.expiration_date` | `string` | Condicional | Data de vencimento (`YYYY-MM-DD`). Obrigatório para `cobv`. |
| `payment_method.payment_limit_date` | `string` | Não | Data limite para pagamento após vencimento (`YYYY-MM-DD`). Padrão: `+90 dias` após `expiration_date`. |
| `payment_method.expiration_seconds` | `integer` | Não | Expiração em segundos para `cob` (`1` a `86400`, padrão `86400`). |
| `payment_method.allow_amount_change` | `boolean` | Não | Permite alteração do valor pelo pagador no `cob` (padrão `false`). |
| `payment_method.billing_instructions.late_fee_amount` | `integer` | Não | Multa fixa em centavos (ex: `200` = R$ 2,00). Mutuamente exclusivo com `late_fee_percentage`. |
| `payment_method.billing_instructions.late_fee_percentage` | `integer` | Não | Multa percentual em base centesimal (ex: `200` = 2,00%). Máx: `10000` (100,00%). |
| `payment_method.billing_instructions.late_fee_date` | `string` | Não | Data de início da multa (`YYYY-MM-DD`, `> expiration_date`). Padrão: `expiration_date + 1 dia`. |
| `payment_method.billing_instructions.interest_amount` | `integer` | Não | Juros em valor fixo por dia em centavos (ex: `100` = R$ 1,00/dia). Mutuamente exclusivo com `interest_percentage`. |
| `payment_method.billing_instructions.interest_percentage` | `integer` | Não | Juros percentual em base centesimal (ex: `100` = 1,00%). |
| `payment_method.billing_instructions.interest_mode` | `string` | Não | Modalidade de apuração dos juros no `cobv`: `"amount_calendar_days"` (Valor por dia corrido — padrão para `interest_amount`, BMP tipo `1`), `"amount_business_days"` (Valor por dia útil, BMP tipo `6`), `"percentage_daily"` (Percentual ao dia corrido, BMP tipo `2`), `"percentage_monthly"` (Percentual ao mês em dias corridos — padrão para `interest_percentage`, BMP tipo `3`), `"percentage_monthly_business"` (Percentual ao mês em dias úteis, BMP tipo `8`) ou `"exempt"` (Isento, BMP tipo `5`). |
| `payment_method.billing_instructions.interest_date` | `string` | Não | Data de início dos juros (`YYYY-MM-DD`, `> expiration_date`). Padrão: `expiration_date + 1 dia`. |
| `payment_method.billing_instructions.abatement_amount` | `integer` | Não | Valor de abatimento em centavos (ex: `500` = R$ 5,00). |
| `payment_method.billing_instructions.discount` | `array` | Não | Array de descontos (`[{ "limit_date": "YYYY-MM-DD", "mode": "...", "amount": 500 }]`). Modos suportados em `mode`: `"fixed"` (Valor fixo até a data — BMP tipo `1`), `"percentage"` (Percentual até a data — BMP tipo `2`), `"anticipation_fixed_calendar"` (Valor por dia corrido de antecipação — BMP tipo `3`), `"anticipation_fixed_business"` (Valor por dia útil de antecipação — BMP tipo `4`), `"anticipation_percentage_calendar"` (Percentual por dia corrido de antecipação — BMP tipo `5`), `"anticipation_percentage_business"` (Percentual por dia útil de antecipação — BMP tipo `6`) e `"exempt"` (Isento — BMP tipo `0`). O campo `amount` segue a convenção em centavos (`500` = R$ 5,00 ou 5,00%). |

---

## 5. Exemplos de Integração

### 5.1. Criar Cobrança Pix (`POST /v2/charge/pix`)

#### Exemplo A: Pix Cobrança com Vencimento (`cobv`)

**Requisição (`POST /v2/charge/pix`):**
```json
{
  "seller": "9519f68914bb40359a045ec8a142b75f",
  "amount": 15000,
  "reference_id": "PEDIDO-2026-001",
  "installment": {
    "number": 1,
    "total": 12
  },
  "tags": [
    "Venda Online",
    "Plano Anual"
  ],
  "customer": {
    "taxpayer_id": "36160560042",
    "name": "Maria Oliveira",
    "email": "maria@exemplo.com",
    "phone_number": "11999887766",
    "street_line": "Av. Paulista, 1000",
    "street_line2": "Conjunto 42",
    "neighborhood": "Bela Vista",
    "city": "São Paulo",
    "state": "SP",
    "postal_code": "01310100"
  },
  "payment_method": {
    "expiration_date": "2026-12-31",
    "payment_limit_date": "2027-03-31",
    "billing_instructions": {
      "late_fee_percentage": 200,
      "interest_percentage": 100,
      "abatement_amount": 500,
      "discount": [
        {
          "limit_date": "2026-12-20",
          "mode": "percentage",
          "amount": 500
        }
      ]
    }
  }
}
```

**Resposta (`200 OK`):**
```json
{
  "id_pix": "f8a9e1d2-3c4b-5a6f-7e8d-9c0b1a2f3e4d",
  "txid": "7c9e1b2a3f4d5e6f7a8b9c0d1e2f3a4b",
  "modality": "cobv",
  "status": "registered",
  "amount": 15000,
  "reference_id": "PEDIDO-2026-001",
  "installment": {
    "number": 1,
    "total": 12
  },
  "emv": "00020101021226870014br.gov.bcb.pix2565pix.moneyp.com.br/qr/v2/cobv/7c9e1b2a3f4d5e6f7a8b9c0d1e2f3a4b5204000053039865405150.005802BR5915ESTABELECIMENTO6009SAO PAULO62070503***6304A1B2",
  "qrcode": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAA...",
  "seller": {
    "seller_id": "9519f68914bb40359a045ec8a142b75f",
    "taxpayer_id": "12345678000195",
    "name": "Loja Exemplo LTDA",
    "chave_pix": "02a9b3c4-5d6e-7f8a-9b0c-1d2e3f4a5b6c"
  },
  "customer": {
    "taxpayer_id": "36160560042",
    "name": "Maria Oliveira",
    "email": "maria@exemplo.com",
    "phone_number": "11999887766",
    "street_line": "Av. Paulista, 1000",
    "street_line2": "Conjunto 42",
    "neighborhood": "Bela Vista",
    "city": "São Paulo",
    "state": "SP",
    "postal_code": "01310100"
  },
  "payment_method": {
    "expiration_date": "2026-12-31",
    "payment_limit_date": "2027-03-31",
    "billing_instructions": {
      "late_fee_percentage": 200,
      "interest_percentage": 100,
      "abatement_amount": 500,
      "discount": [
        {
          "limit_date": "2026-12-20",
          "mode": "percentage",
          "amount": 500
        }
      ]
    }
  },
  "created_at": "2026-08-14T08:30:00-03:00"
}
```

---

#### Exemplo B: Pix Dinâmico COB (Cobrança Imediata)

**Requisição (`POST /v2/charge/pix`):**
```json
{
  "seller": "9519f68914bb40359a045ec8a142b75f",
  "amount": 5000,
  "reference_id": "PIX-IMEDIATO-123",
  "payment_method": {
    "expiration_seconds": 3600,
    "payer_request": "Pagamento do Pedido #123"
  }
}
```

**Resposta (`200 OK`):**
```json
{
  "id_pix": "a1b2c3d4-e5f6-7a8b-9c0d-1e2f3a4b5c6d",
  "txid": "9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
  "modality": "cob",
  "status": "registered",
  "amount": 5000,
  "reference_id": "PIX-IMEDIATO-123",
  "emv": "00020101021226870014br.gov.bcb.pix2565pix.moneyp.com.br/qr/v2/cob/9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d520400005303986540550.005802BR5915ESTABELECIMENTO6009SAO PAULO62070503***6304C3D4",
  "qrcode": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAA...",
  "seller": {
    "seller_id": "9519f68914bb40359a045ec8a142b75f",
    "taxpayer_id": "12345678000195",
    "name": "Loja Exemplo LTDA",
    "chave_pix": "02a9b3c4-5d6e-7f8a-9b0c-1d2e3f4a5b6c"
  },
  "payment_method": {
    "expiration_seconds": 3600,
    "payer_request": "Pagamento do Pedido #123"
  },
  "created_at": "2026-08-14T08:31:00-03:00"
}
```

---

#### Exemplo C: Pix Estático (QR Code Fixo/Estático)

**Requisição (`POST /v2/charge/pix`):**
```json
{
  "seller": "9519f68914bb40359a045ec8a142b75f",
  "amount": 2500,
  "reference_id": "BALCAO-001",
  "payment_type": "static"
}
```

**Resposta (`200 OK`):**
```json
{
  "id_pix": "b2c3d4e5-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
  "txid": "a1b2c3d4e5f60123456789ab",
  "modality": "static",
  "status": "registered",
  "amount": 2500,
  "reference_id": "BALCAO-001",
  "emv": "00020101021126580014br.gov.bcb.pix013602a9b3c4-5d6e-7f8a-9b0c-1d2e3f4a5b6c520400005303986540525.005802BR5915ESTABELECIMENTO6009SAO PAULO62070503***6304E5F6",
  "qrcode": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAA...",
  "seller": {
    "seller_id": "9519f68914bb40359a045ec8a142b75f",
    "taxpayer_id": "12345678000195",
    "name": "Loja Exemplo LTDA",
    "chave_pix": "02a9b3c4-5d6e-7f8a-9b0c-1d2e3f4a5b6c"
  },
  "created_at": "2026-08-14T08:32:00-03:00"
}
```

---

### 5.2. Buscar Cobrança Pix (`GET /v2/charge/pix/{id}`)

- `{id}`: Identificador único (`id_pix`) ou o `txid` da cobrança.

### 5.3. Listar Cobranças Pix (`GET /v2/charge/pix`)

#### Parâmetros da Query String (Filtros)
- `seller_id` (string): Filtrar por hash do vendedor.
- `seller_ein` (string): Filtrar por CPF/CNPJ do vendedor.
- `reference_id` (string): Filtrar por referência externa.
- `txid` (string): Filtrar pelo identificador de transação Pix.
- `status` (string): Status da cobrança (`created`, `registered`, `paid`, `canceled`).
- `created_date_gte` / `created_date_lte` (string): Período de criação (`YYYY-MM-DD`).
- `updated_date_gte` / `updated_date_lte` (string): Período de atualização (`YYYY-MM-DD`).
- `page` (int): Número da página desejada (padrão: `1`).
- `limit` (int): Quantidade de itens por página (máximo: `300`).

### 5.4. Consultar Todos os Pix no Liquidante (`GET /v2/charge/pix/all`)

Permite consultar diretamente na instituição liquidante as cobranças Pix dinâmicas emitidas para um determinado `seller_id`.

#### Parâmetros da Query String
- `seller_id` (string, **obrigatório**): Hash identificador do seller.
- `start_date` / `end_date` (string, opcionais): Filtro de período (`YYYY-MM-DD`).
- `status` (string, opcional): Filtro de status.
- `page` / `limit` (int, opcionais): Paginação.

---

### 5.5. Consultar Detalhes de Pagamento e Conciliação Ativa de QR Code (`GET /v2/charge/pix/{id}/payments`)

Consulta diretamente na instituição liquidante (BMP `GET /api/v2/QRCode/{codigoQRCode}/DetalhesPagamento`) todos os pagamentos recebidos para o QR Code da cobrança (`e2e_id` / `numeroOperacao`, `receipt_id` / `codigoRecebimento`, `movement_id` / `codigoMovimento`, `amount`, `payment_date`) e eventuais devoluções (`refunds`).

- **Conciliação Ativa Automática (Fallback)**: Caso a cobrança esteja com status diferente de `paid` na base local mas a instituição liquidante retorne pagamento confirmado para o QR Code, a API concilia automaticamente o título para `status: "paid"`, grava o histórico e enfileira o webhook `pix.paid` (caso ainda não tenha sido entregue). Para apenas consultar sem conciliar, envie `?reconcile=false`.

**Resposta (`200 OK`):**
```json
{
  "id_pix": "f8a9e1d2-3c4b-5a6f-7e8d-9c0b1a2f3e4d",
  "txid": "7c9e1b2a3f4d5e6f7a8b9c0d1e2f3a4b",
  "codigo_qrcode": "b1c2d3e4-f5a6-4789-8a9b-0c1d2e3f4a5b",
  "status": "paid",
  "reconciled": true,
  "total_payments": 1,
  "total_paid_amount": 15000,
  "total_refunded_amount": 0,
  "payments": [
    {
      "e2e_id": "E1337083520261108172030123456789",
      "receipt_id": "f1e2d3c4-b5a6-4987-8c9d-0e1f2a3b4c5d",
      "movement_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
      "txid": "7c9e1b2a3f4d5e6f7a8b9c0d1e2f3a4b",
      "amount": 15000,
      "payment_date": "2026-11-08T14:20:30",
      "refunds": []
    }
  ]
}
```

---

## 6. Eventos de Webhook do Pix

As cobranças criadas em `/v2/charge/pix` disparam automaticamente os seguintes eventos para o webhook configurado no seu marketplace (consulte `WEBHOOKS.md` para detalhes completos):

- **`pix.created`**: Disparado imediatamente após o registro da cobrança em `POST /v2/charge/pix` (`status: "registered"`), contendo `id_pix`, `txid`, `modality` (`static`, `cob`, `cobv`), `amount`, `reference_id`, `emv`, `qrcode` e `payment_method`.
- **`pix.paid`**: Disparado quando o pagamento do Pix puro é confirmado (`status: "paid"`), contendo `id_pix`, `txid`, `e2e_id` (`NumeroOperacao`), `movement_id` (`CodigoMovimento`), `transaction_id` (`CodigoTransacao`), `amount`, `total_amount`, `interest`, `discount`, `payment_date`, `credit_date` e `payer` (dados do pagador).
