# QI Tech — 薪资贷款 › SIAPE-SIGEPE

Documentação da QI Tech em texto corrido, para colar em um LLM.
Fonte: https://docs.qitech.com.br
11 página(s).

Índice:
- Assinatura em Lote (/zh-Hans/documentation/siape/assinatura-em-lote)
- Cancelamento, Desaverbação e Reversal (SIAPE) (/zh-Hans/documentation/siape/cancelamento)
- Consulta de Margem Consignável (SIAPE) (/zh-Hans/documentation/siape/consulta-margem)
- Conta Interna para Desembolso (/zh-Hans/documentation/siape/conta-interna-desembolso)
- Modelos de Formalização (SIAPE) (/zh-Hans/documentation/siape/formalizacao)
- SIAPE-SIGEPE — Introdução (/zh-Hans/documentation/siape/introducao)
- Mapa de Status (/zh-Hans/documentation/siape/mapa-de-status)
- Margem Livre (Crédito Novo) (/zh-Hans/documentation/siape/margem-livre)
- Mocks (Sandbox) (/zh-Hans/documentation/siape/mocks-sandbox)
- Portabilidade + Refinanciamento (/zh-Hans/documentation/siape/portabilidade-refin)
- Webhooks (/zh-Hans/documentation/siape/webhooks)

---

# Assinatura em Lote

URL: /zh-Hans/documentation/siape/assinatura-em-lote

Agrupa **várias operações SIAPE** em **um único envelope** de assinatura do QI Sign. Você abre o lote, cria as operações referenciando o `document_batch_key`, confere (opcionalmente limpa) e dispara o envio para assinatura.

Fluxo recomendado para [compra de dívida](./04-portabilidade-refin.md) — onde N duplas `debt_purchase` + `refinancing` + 1 refin/refin consolidador podem ser assinadas num único envelope (servidor assina uma vez só).

:::caution Regras do lote
**Mesma titularidade:** todas as operações do lote devem ser do **CPF** (ou do **mesmo representante legal**) do servidor. Incluir CPF "A" e CPF "B" no mesmo lote gera **erro síncrono** no `POST /debt`.

**Tipos permitidos:** o lote SIAPE aceita apenas `POST /debt` com `collateral_type: federal_payroll`.
:::

## 1. Abrir o lote

ENDPOINT /document/document_batch
MÉTODO POST

**Request Body**

```json
{
  "type": "federal_payroll_external_batch",
  "certifier_type": "qi_sign",
  "batch_name": "Lote SIAPE compra-divida - 5ed20003-0610-46d2-88cc-a5d0de640696",
  "request_control_key": "5ed20003-0610-46d2-88cc-a5d0de640696"
}
```

### Campos chave

| Campo | Tipo | Descrição |
|---|---|---|
| `type` | string | Fixo: **`federal_payroll_external_batch`** |
| `certifier_type` | string | Fixo: **`qi_sign`** |
| `batch_name` | string | Nome identificador do lote (**máximo 100 caracteres**) |
| `request_control_key` | string (UUIDv4) | **Idempotência** — não reutilize entre lotes |

**Response Body**

```json
{
  "document_batch_key": "17f35e19-a039-468f-aaa7-84aa8edec3dc"
}
```

Guarde o `document_batch_key` retornado — ele é referenciado em todas as próximas chamadas.

## 2. Incluir operações no lote

Ao criar cada operação SIAPE, envie **`document_batch_key` na raiz** do payload do `POST /debt` (mesmo nível dos demais campos principais).

ENDPOINT /debt
MÉTODO POST

```json
{
  "document_batch_key": "17f35e19-a039-468f-aaa7-84aa8edec3dc",
  "borrower": { "...": "demais campos do borrower" },
  "financial": { "...": "demais campos financeiros" },
  "operation_type": "refinancing",
  "collaterals": [
    {
      "collateral_type": "federal_payroll",
      "collateral_data": {
        "reservation_type": "refinancing",
        "authority_code": "17000",
        "registration_code": "1354387"
      }
    }
  ],
  "modality": { "code": "0202" },
  "refinanced_credit_operations": [
    { "...": "operation_key + contrato externo (ver Portabilidade + Refin)" }
  ]
}
```

O restante do body segue o contrato do `POST /debt`. Consulte os roteiros da [Margem Livre](./03-margem-livre.md) ou [Portabilidade + Refinanciamento](./04-portabilidade-refin.md) conforme a modalidade.

:::tip Compra de dívida cabe num lote só
Pra [compra de dívida](./04-portabilidade-refin.md) (`debt_purchase` + `refinancing` port-enrustido), todas as duplas Op A + Op B + o refin/refin consolidador podem entrar no mesmo lote.
:::

## 3. Consultar documentos do lote

Recomendado **antes de fechar o lote** para conferir os documentos agrupados.

ENDPOINT /document/document_batch/DOCUMENT_BATCH_KEY
MÉTODO GET

**Response Body**

```json
{
  "document_batch_key": "1eee4ec2-05f5-45ef-aa64-38bb3d9de02f",
  "documents": [
    {
      "document_key": "5cca1dad-28fe-4f19-8bbb-0edd6f042384",
      "document_type": "ccb_pre_price_days"
    },
    {
      "document_key": "c109d589-ae18-4f4f-ad31-2879bf714c71",
      "document_type": "ccb_pre_price_days"
    }
  ]
}
```

## 4. Limpar documentos do lote (opcional)

Remove **todos os documentos** vinculados ao lote — útil pra reagrupar do zero se identificar inconsistência antes do envio.

ENDPOINT /document/document_batch/DOCUMENT_BATCH_KEY/documents
MÉTODO DELETE

Body vazio. Response: HTTP 200.

## 5. Enviar para assinatura

Fecha o lote e dispara os documentos pro QI Sign. **Antes desse PUT, os documentos não vão pro servidor.** É o gatilho final.

ENDPOINT /document/document_batch/DOCUMENT_BATCH_KEY/send_to_signature
MÉTODO PUT

Body: `{}`. Response: HTTP 200.

## Erros comuns

| HTTP | Código | Endpoint | Quando ocorre |
|---|---|---|---|
| 404 | `DOC000007` | `GET /document/document_batch/DOCUMENT_BATCH_KEY` | `document_batch_key` inexistente |
| 409 | `DOC000103` | `POST /document/document_batch` | `request_control_key` duplicado (idempotência violada) |

**Exemplo — DOC000103 (idempotência)**

```json
{
  "code": "DOC000103",
  "title": "Bad Request",
  "description": "request_control_key already exists",
  "translation": "Chave de controle da request já existe.",
  "http_status": 409
}
```

:::info Conflito de titularidade
Validação de **mesmo CPF/representante** no lote retorna erro no `POST /debt` (não no endpoint do lote). O corpo de erro segue o catálogo do `/debt`.
:::

---

# Cancelamento, Desaverbação e Reversal (SIAPE)

URL: /zh-Hans/documentation/siape/cancelamento

Cancelar uma operação SIAPE tem dois eixos independentes:
1. **Cancelamento da CCB** — estado da operação no LaaS, e eventual estorno do dinheiro desembolsado.
2. **Desaverbação no SIGEPE** — liberação da margem em folha.

Os dois acontecem de forma assíncrona. Cancelar a operação NÃO libera a margem instantaneamente.

## 1. Pré-desembolso — Cancelamento Imediato

```http
PATCH /debt/{DEBT_KEY}/cancel
```

Operação imediatamente vai pra `canceled`. Sem reversal financeiro (dinheiro nem saiu). QI dispara em seguida a desaverbação no SIGEPE.

Webhook: `debt` com `status: canceled` + `cancel_reason_enumerator`.

## 2. Pós-desembolso — Janela de Desistência (7 dias úteis)

**Janela legal de 7 dias úteis** após desembolso. Dentro dela:

```http
PATCH /debt/{DEBT_KEY}/cancel
```

A response retorna um **PIX QR Code** pra borrower pagar de volta o dinheiro desembolsado:

| Campo na response | Significado |
|---|---|
| `cancel_qr_code.qr_code_url` / `digitable_line` | PIX copia-e-cola |
| `cancel_qr_code.amount` | Valor a devolver |
| `cancel_qr_code.expiration` | Prazo (15 dias úteis após desembolso) |

Quando o borrower paga:
1. QI confirma o pagamento.
2. Dispara o **reversal financeiro automático**.
3. Webhook `reversal`:
   ```json
   {
     "webhook_type": "reversal",
     "credit_operation_key": "<uuid>",
     "reversal": {
       "status": "pending_fund",
       "amount": 2026.93,
       "is_total": true,
       "is_operation_canceled": true,
       "reversal_key": "<uuid>"
     }
   }
   ```
4. QI dispara a desaverbação no SIGEPE.
5. Operação vai pra `canceled`.

> [!warning] Janela operacional do SIGEPE afeta desaverbação
> Como o SIAPE só processa 07:00-00:00 em dias úteis, a desaverbação pode demorar. Cancelamento de PIX QR funciona 24/7 (BaaS); só a parte do SIGEPE espera janela.

Restrições pós-desembolso:
- Status `open` (sem parcelas pagas).
- Pagamento parcial bloqueia o cancelamento.
- Sem cancelamento parcial.

## 3. Cancelamento Permanente

```http
PATCH /debt/{DEBT_KEY}/cancel/permanent
```

`canceled_permanently` — não há volta. Sem reversal automático.

## 4. Desaverbação no SIGEPE

![Fluxo de cancelamento SIAPE](/img/diagrams/siape-cancelamento.svg)

| Status | Significado |
|---|---|
| `waiting_confirmation` | SIGEPE ainda processando |
| `successfully_deleted` | Margem liberada |
| `communication_error` | SIGEPE indisponível — QI retenta |

Pra consultar:

```http
GET /debt/{DEBT_KEY}/collateral
```

## 5. Auto-cancelamento (7 dias)

Operações em `canceled` por mais de 7 dias viram automaticamente `canceled_permanently`. Aplica-se a:
- `consent_refused`
- `consent_expired`
- Pendente de assinatura além do prazo
- QR não pago dentro de 15 dias úteis

## Resumo dos Endpoints

| Endpoint | Quando usar | Reversal automático? |
|---|---|---|
| `PATCH /debt/{KEY}/cancel` (pré-desembolso) | Antes do desembolso | Não aplica |
| `PATCH /debt/{KEY}/cancel` (pós-desembolso) | Em até 7 dias úteis após desembolso | Sim — após borrower pagar o PIX QR |
| `PATCH /debt/{KEY}/cancel/permanent` | Definitivo (sem volta) | Não |

## Cancel reasons no webhook `debt` (`status: canceled`)

| Enumerador | Significado |
|---|---|
| `manual` | Cancelado via API ou portal |
| `waiting_signature` | Não assinou no prazo |
| `not_collateral_constituted` | Averbação falhou (consent_refused, consent_expired, etc.) |
| `is_portability` | Portabilidade falhou |
| `pix_max_retry` | Muitas falhas no desembolso PIX |
| `lack_of_resource` | Sem recurso pra desembolsar |
| `kyc_not_accepted` | KYC reprovado |

→ [Lista completa de enumeradores em Mapa de Status](./08-mapa-de-status.md)

---

# Consulta de Margem Consignável (SIAPE)

URL: /zh-Hans/documentation/siape/consulta-margem

Endpoint que consulta a margem disponível do servidor federal no SIGEPE/SIAPE. Sem o `balance_key` desse passo, não dá pra simular nem emitir.

## Pré-requisitos

1. **Servidor pré-autorizou QI SCD** no Portal do Servidor (válida 30 dias).
2. `authority_code` (código UPAG) — recebido na fase comercial.

> [!warning]
> Diferente do Exército, **não há upload de documento de autorização**. Tudo é digital no portal.

## Endpoint

```http
POST /federal_payroll/balance
```

| Campo | Tipo | Descrição |
|---|---|---|
| `document_number` | string | CPF do servidor (11 dígitos) |
| `authority_code` | string | Código da Unidade Pagadora (UPAG) |
| `registration_code` | string | Matrícula SIAPE |

Resposta síncrona:

```json
{
  "balance_key": "...",
  "status": "pending_search"
}
```

## Webhook de resultado

Tipo: `federal_payroll.balance`

Estrutura do payload de **sucesso**:
```json
{
  "balance_query": [
    {
      "available_balance": 3500.00,
      "authority_code": "17000",
      "registration_code": "1354387",
      "employment_relationship": "active",
      "consigned_credit": 1200.00,
      "consigned_card": 300.00
    }
  ]
}
```

- `available_balance` — margem disponível
- `consigned_credit` — quanto já está consignado em crédito
- `consigned_card` — quanto está em cartão consignado

## Enumeradores de falha (balance)

| Enumerador | Significado | Ação |
|---|---|---|
| `unauthorized_institution` | Servidor não pré-autorizou QI SCD no portal | Pedir autorização |
| `inexistent_relationship` | Sem vínculo federal | Verificar dados |
| `invalid_document_number` | CPF malformado | Verificar CPF |
| `inactive_federal_employee` | Servidor inativo | Não há ação |
| `deceased_federal_employee` | Servidor falecido | Não há ação |

## Cenários de Sandbox

### Sucesso

| `document_number` | `authority_code` | `registration_code` |
|---|---|---|
| 25256363506 | 17000 | 1354387 |

### Falha

| `document_number` | `failure_reason` |
|---|---|
| 71987878353 | `unauthorized_institution` |

> [!info] Reset diário
> Reservas não-finalizadas no sandbox são **encerradas todo dia às 23:59h** pra manter o ambiente limpo.

## Próximo passo

Após o webhook `succeeded` com `available_balance` retornado, escolha a modalidade:

- [Margem Livre](./03-margem-livre.md) — crédito novo com margem disponível
- [Portabilidade + Refinanciamento](./04-portabilidade-refin.md) — refin de operação QI ou compra de dívida externa

---

# Conta Interna para Desembolso

URL: /zh-Hans/documentation/siape/conta-interna-desembolso

Em **compra de dívida**, **portabilidade** e **refinanciamento** consignado, o desembolso da operação **não vai direto para a conta externa do tomador**: ele cai numa conta interna **em nome do tomador** (aberta pelo parceiro via `POST /account`). É a partir dessa conta que a QI executa as ações pós-desembolso — **quitação do contrato externo**, **repasse de troco**, **conciliação**.

:::tip Por que conta interna?
Concentrar o desembolso numa conta operacional dá controle do fluxo: a QI consegue orquestrar quitação externa + averbação + repasse de troco sem depender de SLA de banco terceiro no meio do processo.
:::

## Quando usar conta interna vs externa

| Cenário | `disbursement_bank_account` |
|---|---|
| [Margem Livre](./03-margem-livre.md) (crédito novo direto) | Conta **externa** do tomador |
| [Refinanciamento puro](./04-portabilidade-refin.md) (renegocia CO QI ativa) | Conta **interna** em nome do tomador |
| [Portabilidade](./04-portabilidade-refin.md) (com ou sem troco) | Conta **interna** em nome do tomador |
| [Compra de dívida](./04-portabilidade-refin.md) (`debt_purchase` + `refinancing` port-enrustido) | Conta **interna** em nome do tomador **nas duas operações da dupla** |
| Refin/refin consolidador (opcional, fecha várias port/refins) | Conta **interna** em nome do tomador |

## 1. Abrir a conta interna em nome do tomador

ENDPOINT /account
MÉTODO POST

A conta é aberta pelo **parceiro** (autenticado com seus `client_integration_key`), com o `owner_document_number` apontando para o **CPF do tomador**. Reutilize a conta existente — uma por tomador (não abrir nova a cada operação).

**Request Body**

```json
{
  "owner_document_number": "<CPF DO TOMADOR>",
  "owner_person_key": "<PERSON_KEY DO TOMADOR>",
  "requester_key": "<REQUESTER_KEY DO PARCEIRO>",
  "webhook_enabled": true
}
```

:::info Pré-requisito
O tomador precisa estar **onboarded** previamente (ter `person_key`) — o parceiro envia esse `person_key` no `owner_person_key`. Caso contrário, o `/account` falha com `ACC000xxx` por validation.
:::

**Response Body**

```json
{
  "account_key": "602de111-21e1-4c1e-8c5c-d60c032309ca",
  "account_branch": "0001",
  "account_number": "1431704",
  "account_digit": "3",
  "owner_document_number": "<CPF DO TOMADOR>",
  "owner_name": "<NOME DO TOMADOR>",
  "bank_code": "329",
  "account_status": "active",
  "webhook_enabled": true
}
```

:::tip Idempotência por tomador
Se já existe conta ativa para esse `owner_document_number` no parceiro, evite chamar `POST /account` de novo — consulte `GET /accounts?owner_document_number= ` antes e reaproveite o `account_key` retornado.
:::

## 2. Usar a conta no `/debt`

Use os dados retornados em `disbursement_bank_account` no payload do `POST /debt`. **A mesma conta vai nas DUAS operações da dupla `debt_purchase` + `refinancing`** (e no `refinancing` consolidador, se houver).

```json
{
  "disbursement_bank_account": {
    "name": "<NOME DO TOMADOR>",
    "bank_code": "329",
    "account_type": "checking_account",
    "account_branch": "0001",
    "account_number": "1431704",
    "account_digit": "3",
    "document_number": "<CPF DO TOMADOR>",
    "transfer_method": "ted"
  }
}
```

| Campo | Valor (conta interna QI Tech) |
|---|---|
| `bank_code` | `"329"` (QI Tech S.A. — SCD) |
| `account_branch` | `"0001"` |
| `account_number` / `account_digit` | retornados no `POST /account` |
| `document_number` | **CPF do tomador** (mesmo do `owner_document_number`) |
| `transfer_method` | `"ted"` (recomendado para `payment_type_id: 10`) |

Exemplo completo: ver [Portabilidade + Refinanciamento — Compra de dívida](./04-portabilidade-refin.md).

## 3. Ações pós-desembolso

A QI dispara as ações abaixo automaticamente conforme os webhooks confirmam cada etapa.

### 3.1 Conferir saldo

ENDPOINT /account/ACCOUNT_KEY/balance
MÉTODO GET

### 3.2 Quitação do contrato externo (port)

Disparada pela QI ao receber `credit_operation.collateral` (`reservation_status: deleted`) na operação antiga: saldo da conta interna é enviado ao banco origem via **PIX** ou **TED** para liquidar o contrato externo.

### 3.3 Repasse de troco pro tomador (se houver)

Se `final_disbursement_amount > 0` na simulação, o saldo residual é transferido da conta interna para a **conta externa do tomador** (informada no onboarding ou no payload da operação).

### 3.4 Conciliação

ENDPOINT /account/ACCOUNT_KEY/statement
MÉTODO GET

Query params `from_date` e `to_date` no formato `YYYY-MM-DD`.

### 3.5 Webhooks relevantes

| Webhook | Quando dispara |
|---|---|
| `account.balance_change` | Crédito recebido na conta interna (desembolso da CO) |
| `pix_transfer.status_change` | Quitação externa OU repasse de troco confirmados |
| `ted.status_change` | Quitação externa OU repasse via TED confirmados |

## Referências

- [Conta de pagamento — fluxo completo](/documentation/contas/abertura_de_conta/fluxo_de_abertura_de_conta) — referência do `POST /account` em detalhes
- [Portabilidade + Refinanciamento](./04-portabilidade-refin.md) — usa essa conta em compra de dívida (`debt_purchase` + `refinancing`)
- [Webhooks](./07-webhooks.md) — eventos assíncronos da operação

---

# Modelos de Formalização (SIAPE)

URL: /zh-Hans/documentation/siape/formalizacao

A QI suporta **5 modelos de formalização** pra operações SIAPE — mesmo conjunto do Exército. Adicionalmente, pra agrupar várias operações num único envelope (recomendado em [compra de dívida](./04-portabilidade-refin.md)), use [Assinatura em Lote](./11-assinatura-em-lote.md).

:::tip Várias operações no mesmo envelope
Em compra de dívida com N duplas `debt_purchase` + `refinancing` (+ refin/refin consolidador), use [Assinatura em Lote](./11-assinatura-em-lote.md) (`POST /document/document_batch` com `type: federal_payroll_external_batch`) — o servidor assina tudo de uma vez só.
:::

## Modelos disponíveis

| Modelo | Quando usar |
|---|---|
| **QI Sign automático** (default) | QI envia link de assinatura ao borrower; nenhuma config extra |
| **QI Sign em lote** | Várias operações num único envelope; ver [Assinatura em Lote](./11-assinatura-em-lote.md) |
| **PDF assinado externamente** | Parceiro tem signature provider próprio |
| **Data-signature: opt-in** | Borrower clica "concordo" em portal do parceiro |
| **Data-signature: zip** | Parceiro envia zip de evidências |
| **Data-signature: selfie** | Biometria via CaaS |

## QI Sign Automático

Não requer chamada adicional após `/debt`. QI envia URL pro borrower. Webhook `debt` fires com `status: signature_finished`.

## PDF assinado externamente

```http
POST /debt/{DEBT_KEY}/signed
```

```json
{
  "signed_document_key": "<uuid retornado pelo upload do PDF>"
}
```

## Data-signature: opt-in

```json
{
  "data_signature": {
    "type": "opt_in",
    "evidence": { "ip_address": "...", "user_agent": "...", "timestamp": "..." }
  }
}
```

## Data-signature: zip

```json
{
  "data_signature": {
    "type": "zip",
    "signed_document_key": "<uuid do zip>"
  }
}
```

## Data-signature: selfie

Requer integração CaaS (face match + liveness):

```json
{
  "data_signature": {
    "type": "selfie",
    "signed_document_key": "<image_key do CaaS>"
  }
}
```

## Webhook após formalização

`debt` com `status: signature_finished` — assinatura aceita pela QI. Em seguida, se `reservation_method: issuing`, a averbação é disparada agora; se `creation`, já foi disparada antes e o desembolso entra na fila quando confirmada.

## Próximo passo

Após o `signature_finished`, a operação segue automaticamente: averbação confirmada (se `issuing`) → desembolso PIX/TED → webhook `debt` (`disbursed`).

Para acompanhar via webhooks: [Webhooks](./07-webhooks.md). Para cancelar a qualquer momento: [Cancelamento](./06-cancelamento.md).

---

# SIAPE-SIGEPE — Introdução

URL: /zh-Hans/documentation/siape/introducao

API para originação de **CCB consignado** para **servidores públicos federais** (professores em universidades federais, funcionários em órgãos federais — **não inclui** militares). A reserva de margem é feita via **SIGEPE/SIAPE** e exige pré-autorização da QI SCD no **Portal do Servidor** pelo próprio servidor antes de qualquer operação.

| Item | Valor |
|---|---|
| Autoridade pagadora | Governo Federal / **SIGEPE-SIAPE** |
| Tipo de garantia (`collateral_type`) | `federal_payroll` |
| Modelo de reserva | Averbação (assíncrona, consentida no Portal do Servidor) |
| Funcionamento | **07:00–00:00, dias úteis, exceto feriados** |
| Modalidades suportadas | [Margem Livre (Crédito Novo)](./03-margem-livre.md) e [Portabilidade + Refinanciamento](./04-portabilidade-refin.md) |
| Pré-autorização do servidor | **30 dias** de validade — Portal do Servidor: *Consignações → Empréstimo Consignado → Autorizar Consignatário* |
| Instrumento | CCB (via `POST /debt`) |

:::danger Atenção!
Os webhooks da QI Tech não devem ser mapeados de forma restrita.
Campos adicionais podem ser incluídos aos payloads dos webhooks retornados em nossas APIs.
:::

:::info Reenvio de Webhooks
Você pode consultar e reenviar webhooks seguindo as instruções detalhadas na documentação: [Reenvio de Webhooks](/documentation/notificacoes/reenvio_de_notificacoes).
:::

:::caution Janela operacional
Diferente do Exército (24/7), o SIAPE só processa de **segunda a sexta, das 07:00 às 00:00**. Requisições de averbação fora dessa janela ficam em fila e são processadas no próximo dia útil. Planeje retries e SLA com isso em mente.
:::

## Fluxo End-to-End

Em **margem livre** o desembolso vai direto pra conta externa do servidor. Em **refinanciamento, portabilidade e compra de dívida** o desembolso vai pra uma **conta interna em nome do tomador** (aberta pelo parceiro via `POST /account`) — daí a QI quita o contrato externo, repassa o troco e faz a conciliação. Ver [Conta Interna para Desembolso](./10-conta-interna-desembolso.md).

![Fluxo end-to-end SIAPE](/img/diagrams/siape-introducao.svg)

## Modalidades

A operação se divide em quatro modalidades, escolhidas no `operation_type` e `collateral_data`:

| Modalidade | `operation_type` / `reservation_type` | Quando usar | Doc |
|---|---|---|---|
| **Margem Livre** (Crédito Novo) | `operation_type: structured_operation` / `reservation_type: new_credit` | Servidor com margem disponível; sem dívida externa nem refin de operação ativa | [→ Margem Livre](./03-margem-livre.md) |
| **Refinanciamento** | `operation_type: refinancing` / `reservation_type: refinancing` + `operation_key` | Renegociar operação QI ativa (prazo/taxa), eventualmente liberando troco | [→ Port + Refin](./04-portabilidade-refin.md) |
| **Portabilidade** (com ou sem troco) | `operation_type: refinancing` / `reservation_type: refinancing` + `original_contract_number` | Trazer dívida de outro banco; pode incluir troco | [→ Port + Refin](./04-portabilidade-refin.md) |
| **Compra de dívida** (port enrustida) | `operation_type: debt_purchase` + `operation_type: refinancing` (dupla) | Trazer N dívidas externas; QI emite uma dupla `debt_purchase` + `refinancing` por contrato externo, com desembolso em [conta interna em nome do tomador](./10-conta-interna-desembolso.md) | [→ Port + Refin](./04-portabilidade-refin.md) |

## Pré-requisitos

1. **Servidor pré-autorizou QI SCD no Portal do Servidor** — autorização válida 30 dias. Sem isso, `federal_payroll.balance` falha com `unauthorized_institution`. O parceiro deve orientar o servidor a entrar em `Consignações → Empréstimo Consignado → Autorizar Consignatário` antes de qualquer chamada.
2. **Não há upload de termo de autorização** — diferente do Exército, a autorização SIAPE é digital no portal (não há `authorization_document_key` no payload de balance).

## Referência por área

- [Consulta de Margem](./02-consulta-margem.md) — endpoint `/federal_payroll/balance` + UPAG
- [Margem Livre](./03-margem-livre.md) — Simulação + Emissão para `new_credit`
- [Portabilidade + Refinanciamento](./04-portabilidade-refin.md) — Simulação + Emissão para `refinancing` + payloads de compra de dívida (`debt_purchase` + `refinancing` port-enrustido)
- [Formalização](./05-formalizacao.md) — 5 modelos: QI Sign, PDF, opt-in, zip, selfie
- [Conta Interna para Desembolso](./10-conta-interna-desembolso.md) — POST `/account` em nome do tomador + uso em compra de dívida + ações pós-desembolso
- [Assinatura em Lote](./11-assinatura-em-lote.md) — agrupar várias operações num único envelope QI Sign (`POST /document/document_batch`)
- [Cancelamento, Desaverbação e Reversal](./06-cancelamento.md) — pré + pós-desembolso + reversal automático
- [Webhooks](./07-webhooks.md) — todos os eventos assíncronos + payloads
- [Mapa de Status](./08-mapa-de-status.md) — enumeradores consolidados
- [Mocks (Sandbox)](./09-mocks-sandbox.md) — dados de teste e cenários end-to-end

---

# Mapa de Status

URL: /zh-Hans/documentation/siape/mapa-de-status

Referência consolidada de todos os enumeradores que podem aparecer nas respostas síncronas e webhooks do produto consignado SIAPE.

## Consulta de Margem (`federal_payroll.balance`)

| Status | Significado |
|---|---|
| `pending_search` | Resposta síncrona — consulta enfileirada |
| `succeeded` | Webhook — margem retornada |
| `failure` | Webhook — falha |

### Failure reasons

| Enumerador | Significado |
|---|---|
| `unauthorized_institution` | Servidor não pré-autorizou QI SCD no Portal |
| `inexistent_relationship` | Sem vínculo federal |
| `invalid_document_number` | CPF malformado |
| `inactive_federal_employee` | Servidor inativo |
| `deceased_federal_employee` | Servidor falecido |

## Averbação / Desaverbação (`credit_operation.collateral`)

| Status | Significado |
|---|---|
| `pending_consent` | SIGEPE aceitou; aguardando servidor confirmar no Portal |
| `success` | Averbação confirmada (`collateral_constituted: true`) |
| `failure` | Falha (ver enumerator) |

### Enumeradores de failure

| Enumerador | Ação |
|---|---|
| `consent_refused` | Servidor recusou no Portal — cancela operação |
| `consent_expired` | Janela de consentimento expirou — cancela |
| `invalid_balance` | Margem insuficiente — cancela |
| `unauthorized_institution` | Autorização QI SCD expirou no Portal — **retenta por até 7 dias** |
| `origin_contract_not_found` | Contrato origem (port/refin) não existe — cancela |
| `waiting_for_origin_contract_closure` | Aguardando quitação externa — permanece em retry |
| `expired_portability` | Janela de port no SIGEPE fechou |
| `successfully_deleted` | Margem desaverbada com sucesso |

## Operação (`debt`)

| Status | Significado |
|---|---|
| `waiting_signature` | Aguardando assinatura |
| `signature_finished` | Assinatura concluída |
| `waiting_disbursement` | Aguardando desembolso |
| `disbursed` | Desembolsado |
| `canceled` | Cancelada (não-permanente) |
| `canceled_permanently` | Cancelada definitivamente |
| `settled` | Liquidada |

### Cancel reasons

| Enumerador | Significado |
|---|---|
| `manual` | Cancelado via API ou portal |
| `waiting_signature` | Não assinou no prazo |
| `not_collateral_constituted` | Averbação falhou |
| `is_portability` | Portabilidade falhou |
| `pix_max_retry` | Muitas falhas no desembolso PIX |
| `lack_of_resource` | Sem recurso pra desembolsar |
| `kyc_not_accepted` | KYC reprovado |
| `agencia_conta_invalida` | Erro em dados bancários |
| `invalid_account` | Conta inválida |
| `rejected_payment` | Pagamento recusado pelo banco destino |

## Reversal (cancelamento pós-desembolso)

| Status | Significado |
|---|---|
| `pending_fund` | Reversal iniciado, aguardando devolução pro fundo |
| `completed` | Reversal completo |
| `failed` | Reversal falhou (raro — investigação manual) |

## Parcelas (`installment.status_change`)

| Status | Significado |
|---|---|
| `opened` | Aberta, ainda não venceu |
| `waiting_payment` | Aberta, na data de vencimento |
| `paid` | Paga em dia |
| `paid_early` | Paga antes do vencimento |
| `paid_partial` | Paga parcialmente |
| `paid_overdue` | Paga após o vencimento |
| `paid_partial_overdue` | Paga parcialmente após vencimento |
| `overdue` | Em atraso |
| `canceled` | Cancelada |

## Recuperar último estado

```http
GET /debt/{DEBT_KEY}/collateral
```

Retorna `last_response` + `reservation_status` + timestamp.

---

# Margem Livre (Crédito Novo)

URL: /zh-Hans/documentation/siape/margem-livre

Esteira de **originação direta** quando o servidor federal tem margem consignável disponível no SIAPE/SIGEPE. Cobre simulação e emissão para `reservation_type: new_credit`.

Para refinanciar uma operação QI ativa ou trazer dívida de outro banco, ver [Portabilidade + Refinanciamento](./04-portabilidade-refin.md).

## Pré-requisitos

- Servidor **pré-autorizou QI SCD no Portal do Servidor** (válida 30 dias).
- `balance_key` recebido na [Consulta de Margem](./02-consulta-margem.md), com webhook `federal_payroll.balance` em `status: succeeded`.
- `available_balance` retornado > parcela desejada × prazo.

## 1. Simulação

ENDPOINT /debt_simulation
MÉTODO POST

**Request Body**

```json
{
  "borrower": {
    "person_type": "natural",
    "individual_document_number": "25256363506"
  },
  "financial": {
    "first_due_date": "2026-07-01",
    "installment_face_value": 500.00,
    "disbursement_date": "2026-06-02",
    "number_of_installments": 72,
    "monthly_interest_rate": 0.0185,
    "interest_type": "pre_price_days",
    "credit_operation_type": "ccb",
    "interest_grace_period": 0,
    "principal_grace_period": 0,
    "fine_configuration": {
      "monthly_rate": 0.01,
      "interest_base": "calendar_days",
      "contract_fine_rate": 0.02
    }
  },
  "collaterals": [
    {
      "collateral_type": "federal_payroll",
      "percentage": 1,
      "collateral_data": {
        "reservation_type": "new_credit",
        "authority_code": "17000",
        "registration_code": "1354387"
      }
    }
  ]
}
```

### Campos chave

| Campo | Descrição |
|---|---|
| `collaterals[].collateral_type` | **`federal_payroll`** (obrigatório) |
| `collaterals[].collateral_data.reservation_type` | **`new_credit`** — sempre pra margem livre |
| `collaterals[].collateral_data.authority_code` | Código da Unidade Pagadora (UPAG) |
| `collaterals[].collateral_data.registration_code` | Matrícula SIAPE |
| `financial.installment_face_value` | Parcela — ≤ `available_balance` |
| `financial.number_of_installments` | Prazo (geralmente até 96 meses pra SIAPE) |

`modality.code` **NÃO** é obrigatório em margem livre.

### Janela operacional

Pra `disbursement_date`, lembre que o SIAPE só processa em **dias úteis das 07:00 às 00:00**. Datas em fim de semana ou feriados são empurradas pro próximo dia útil.

## 2. Emissão

ENDPOINT /debt
MÉTODO POST

**Request Body**

```json
{
  "borrower": {
    "name": "MARIA DOS SANTOS",
    "email": "maria@email.com",
    "phone": { "number": "900000000", "area_code": "11", "country_code": "+55" },
    "address": {
      "city": "Brasília", "state": "DF", "number": "100",
      "street": "Esplanada", "complement": "",
      "postal_code": "70000000", "neighborhood": "Centro"
    },
    "role_type": "issuer",
    "birth_date": "1978-09-22",
    "mother_name": "JOSEFINA DOS SANTOS",
    "person_type": "natural",
    "individual_document_number": "25256363506",
    "gender": "female",
    "nationality": "brasileiro",
    "is_pep": false,
    "marital_status": "married"
  },
  "financial": ,
  "simplified": true,
  "collaterals": [
    {
      "collateral_type": "federal_payroll",
      "percentage": 1,
      "collateral_data": {
        "reservation_type": "new_credit",
        "reservation_method": "creation",
        "authority_code": "17000",
        "registration_code": "1354387"
      }
    }
  ],
  "disbursement_bank_account": {
    "name": "MARIA DOS SANTOS",
    "bank_code": "001",
    "account_type": "checking_account",
    "account_digit": "8",
    "branch_number": "1234",
    "account_number": "00098765",
    "document_number": "25256363506",
    "transfer_method": "ted"
  },
  "purchaser_document_number": "32402502000135"
}
```

### `reservation_method`

**creation (averbação imediata)**

Averbação no SIGEPE dispara junto com a criação do `/debt`.

**issuing (averbação após formalização)**

Averbação só dispara após a formalização (`POST /debt/{KEY}/signed`).

### Etapa-chave: confirmação do servidor no Portal

![Fluxo de margem livre SIAPE](/img/diagrams/siape-margem-livre.svg)

:::warning Servidor precisa confirmar
Após o `/debt`, o webhook chega com `status: pending_consent`. **O servidor precisa entrar no Portal do Servidor e confirmar a operação** dentro da janela do SIGEPE. Se não confirmar, expira com `consent_expired` e cancela. Comunique o servidor imediatamente após o `/debt`.
:::

### Webhooks pós `/debt`

| Webhook | Status | Quando |
|---|---|---|
| `debt` | `waiting_signature` | Operação criada |
| `credit_operation.collateral` | `pending_consent` | Aguardando servidor confirmar no Portal |
| `credit_operation.collateral` | `success` (`collateral_constituted: true`) | Servidor confirmou; averbação ativa |
| `debt` | `disbursed` | Desembolso PIX/TED enviado |

→ Próximo passo: [Formalização](./05-formalizacao.md)

## Falhas comuns

| Webhook / Erro | Enumerador | Significado | Ação |
|---|---|---|---|
| `federal_payroll.balance` | `unauthorized_institution` | Servidor não pré-autorizou QI SCD | Solicitar autorização |
| `federal_payroll.balance` | `inexistent_relationship` | Sem vínculo federal | Verificar dados |
| `credit_operation.collateral` | `invalid_balance` | Margem insuficiente | Reduzir parcela |
| `credit_operation.collateral` | `consent_refused` | Servidor recusou no Portal | Conversar com servidor |
| `credit_operation.collateral` | `consent_expired` | Janela do SIGEPE fechou | Re-emitir |

→ [Lista completa de enumeradores](./08-mapa-de-status.md)

## Sandbox

### Sucesso

| `document_number` | `authority_code` | `registration_code` |
|---|---|---|
| 25256363506 | 17000 | 1354387 |

### Falha

| `document_number` | `failure_reason` |
|---|---|
| 71987878353 | `unauthorized_institution` |

→ [Mocks completos](./09-mocks-sandbox.md)

---

# Mocks (Sandbox)

URL: /zh-Hans/documentation/siape/mocks-sandbox

O `federal-payroll-api` da QI Tech intercepta as chamadas ao SIAPE/SIGEPE em sandbox e retorna respostas mockadas via [`siape_mocker.py`](https://gitlab.qitech.com.br/qilaas/federal-payroll-api/-/blob/master/src/connectors/siape_mocker.py). Apenas os CPFs listados abaixo são reconhecidos — qualquer outro retorna `cdRetCode 9999` ("O número do documento informado não é um mock válido no ambiente de teste").

## Sucesso completo (consulta + emissão + portabilidade)

CPFs que passam por **todos** os endpoints (`consultarAutorizacoesMargemConsignavelV2`, `incluirContratoV2`, `incluirContratoPortabilidade`, `renovarContratoV2`, etc.) com retorno OK:

| `document_number` (CPF) | `authority_code` | `registration_code` |
|---|---|---|
| 25256363506 | 17000 | 1354387 |
| 03137300088 | 17000 | 1354387 |
| 20472510010 | 17000 | 1354387 |
| 67050758051 | 17000 | 1354387 |
| 59669701066 | 17000 | 1354387 |

Resposta esperada no webhook `federal_payroll.balance` (`status: succeeded`):

```xml
nome: KAUAN RIBEIRO PEREIRA
codOrgao: 17000 (MINISTERIO DA ECONOMIA)
cdMatricula: 1354387
autorizacaoEmprestimo: S (válida até 09/10/2024)
autorizacaoPortabilidade: S (válida até 24/10/2024)
contratoPortado:
  nrCnpj: 00000000000191
  nrContrato: 526985/WU
vlMargemDisp: 100000 (geral), 50000 (portabilidade)
```

## Cenários especiais

### CPF sem autorização (`unauthorized_institution`)

| `document_number` | Comportamento |
|---|---|
| `71987878353` | Funciona apenas em `consultarAutorizacoesMargemConsignavelV2`. Retorna servidor "HELEN LUCIA REZENDE DE MORAES" com `autorizacaoEmprestimo: N` e `autorizacaoPortabilidade: N` |

Use este CPF pra testar a UX de "peça pro servidor autorizar QI SCD no Portal".

### CPF sem margem (`consignable_margin_exceeded`)

| `document_number` | Comportamento |
|---|---|
| `33673248090` | Funciona em `consultarAutorizacoes` (retorna `vlMargemDisp: 0`) E em `incluirContratoV2/incluirContratoPortabilidade/renovarContratoV2` (retorna `cdRetCode: 8058` "Funcionário não tem margem para essa solicitação") |

Use este CPF pra testar fluxo de margem insuficiente após autorização concedida.

## CPFs fora da whitelist

Qualquer outro CPF retorna:

```xml
cdRetCode: 9999
dsRetCode: O número do documento informado não é um mock válido no ambiente de teste
```

Webhook resultante: `federal_payroll.balance` com `status: failure` + `failure_reason: mock_error`.

## Token e Portal do Servidor em Sandbox

- **Não há autorização real no Portal do Servidor em sandbox.** Os mocks já trazem `autorizacaoEmprestimo: S` (ou N) baseado no CPF da whitelist.
- O endpoint `consultarAnuenciaContratos` retorna `void` (não há body) — significa que o mock pula o passo de consulta de anuência.

## Portabilidade — dados do contrato origem mockados

Quando você usa um CPF da whitelist e simula portabilidade, os mocks já têm:

| Campo | Valor mockado |
|---|---|
| `original_financial_institution_document_number` | `00000000000191` (Banco do Brasil) |
| `original_contract_number` | `526985/WU` |
| `due_balance` mockado | varia conforme `vlMargemDisp` da resposta |

Use estes valores ao montar o payload de `/debt` em portabilidade pra que o mock reconheça o contrato origem.

## Reset diário

Reservas que não atingiram estado terminal (`reserved`, `canceled`, `deleted`) são **encerradas automaticamente às 23:59h** pra manter o ambiente limpo.

## Cenário end-to-end completo

Sequência recomendada para validar a integração em sandbox:

1. `POST /federal_payroll/balance` com `25256363506` + `authority_code: 17000` + `registration_code: 1354387`
2. Aguardar webhook `federal_payroll.balance` (succeeded) com `available_balance` retornado
3. `POST /debt_simulation` com `installment_face_value` ≤ `available_balance` retornado
4. `POST /debt` com `reservation_method: creation` (margem livre) ou com `refinanced_credit_operations` (port com `original_contract_number: 526985/WU`)
5. Aguardar webhook `credit_operation.collateral` (`pending_consent` → `success`) — em sandbox o consent é automático após o `/debt`
6. `POST /debt/{KEY}/signed` com QI Sign ou data-signature opt-in
7. Aguardar webhook `debt` (`disbursed`)
8. (opcional cancelamento) `PATCH /debt/{KEY}/cancel` → recebe PIX QR → simular pagamento → webhook `reversal`

## Janela operacional sandbox

Diferente da produção, o sandbox SIAPE **não respeita a janela 07:00-00:00** dias úteis — você pode rodar a qualquer hora, qualquer dia da semana. Em prod a janela é estrita.

## Endpoints mockados (referência interna)

O `siape_mocker.py` cobre estes operation types do SIAPE (SOAP):

| Operation type | Comportamento mockado |
|---|---|
| `consultarAutorizacoesMargemConsignavelV2` | Retorna dados do servidor + autorização emprestimo/portabilidade |
| `incluirContratoV2` | Inclui novo contrato — sucesso pra CPFs whitelist |
| `incluirContratoPortabilidade` | Inclui contrato de portabilidade — sucesso pra whitelist |
| `renovarContratoV2` | Refinanciamento — sucesso pra whitelist |
| `alterarContrato` | Sucesso fixo `cdRetCode: 0000` |
| `consultarContrato` | Retorna situação `Ativo` ou `Aguardando Encerramento do Contrato` (port) |
| `encerrarContrato` | Sucesso fixo |
| `consultarAnuenciaContratos` | Void (pula passo) |

---

# Portabilidade + Refinanciamento

URL: /zh-Hans/documentation/siape/portabilidade-refin

Fluxo de **compra de dívida consignada** SIAPE via assinatura em lote. A QI Tech emite uma CCB de quitação (`debt_purchase`) que paga o banco vendedor, uma CCB de portabilidade (`portability`) que porta o contrato, e um `refinancing` consolidador **sempre obrigatório** que carrega seguro e troco. Tudo assinado de uma única vez na QI Sign.

:::info Contas por operação
Cada operação do fluxo exige uma conta de desembolso distinta:

- **`debt_purchase`** → **conta interna QI** em nome do tomador. O desembolso cai nessa conta e quita a dívida origem no banco vendedor via `after_disbursement_actions` (boleto/PIX).
- **`refinancing`** → **conta externa do tomador**. O troco do refinanciamento é desembolsado nessa conta.

O parceiro abre a conta interna via `POST /account` antes da emissão. Ver [Conta Interna para Desembolso](./10-conta-interna-desembolso.md).
:::

## Cenários

O `refinancing` consolidador é **sempre obrigatório** no batch federal — é ele quem carrega seguro e troco.

| Cenário | Composição | Quando usar |
|---|---|---|
| **α** | 1× `debt_purchase` + 1× `portability` + 1× `refinancing` | Porta **uma** dívida externa |
| **β** | N× `debt_purchase` + N× `portability` + 1× `refinancing` | Porta **N dívidas** externas num único envelope |
| **γ** | α ou β + `financial.rebates` no `refinancing` | Qualquer composição acima com prêmio de seguro — gera `insurance_premium_term` automaticamente |

:::caution Regra do seguro e do troco
Seguro (`financial.rebates` com `fee_type: "insurance_premium_qi"`) e troco só podem ser enviados no `refinancing` consolidador (Passo 5).

- **`debt_purchase`** — `rebates` proibido (CCB de quitação não carrega seguro).
- **`portability`** — `rebates` proibido **e** `final_disbursement_amount` deve ser `0`.
:::

## Sequência de chamadas

```
1.  POST /upload   (documentos da operação)

2.  POST /account  (conta interna QI p/ debt_purchase)

3.  POST /document/document_batch

4.  POST /debt  (debt_purchase)        → desembolso em conta interna QI

5.  POST /debt  (portability)          → sem troco, sem seguro

6.  POST /debt  (refinancing)          → seguro + troco em conta externa

7.  PUT  /document/document_batch/{key}/send_to_signature
```

:::caution Ordem obrigatória de inserção no batch
`debt_purchase` deve ser inserido **antes** da `portability` que o referencia, e a `portability` **antes** do `refinancing` consolidador. Inverter a ordem dispara:

- **`DOC000110`** (HTTP 422) — `portability` cujo `refinanced_credit_operations[].operation_key` não casa com nenhum `debt_purchase` já inserido no batch.
- **`DOC000112`** (HTTP 422) — `refinancing` cujo `refinanced_credit_operations[].operation_key` não casa com nenhuma `portability` já inserida no batch.
:::

---

## 1. Upload dos documentos

Antes de abrir a conta e o lote, faça o **upload dos documentos** exigidos na operação via `POST /upload`. Cada chamada retorna um `document_key`, identificador do documento referenciado nas etapas seguintes.

ENDPOINT /upload
MÉTODO POST

→ Autenticação, headers, FormData e exemplos de código (Python / Node.js) em [Upload de Documentos](../upload_de_documentos/upload_de_documentos.md) .

:::caution Atenção
Salve o `document_key` retornado — ele é necessário para a consulta e o uso futuro do documento.
:::

---

## 2. Abrir a conta interna em nome do tomador

Em **compra de dívida**, **portabilidade** e **refinanciamento** do consignado federal (Siape), o desembolso da operação **não vai direto para a conta externa do tomador**: ele cai numa conta interna **em nome do tomador** (aberta pelo parceiro via `POST /account`). É a partir dessa conta que a QI executa as ações pós-desembolso — **quitação do contrato externo**, **repasse de troco**, **conciliação**.

ENDPOINT /account
MÉTODO POST

A conta é aberta pelo **parceiro** (autenticado com seus `client_integration_key`), com o `owner_document_number` apontando para o **CPF do tomador**. Reutilize a conta existente — uma por tomador (não abrir nova a cada operação).

**Request Body**

```json
{
  "owner_document_number": "<CPF DO TOMADOR>",
  "owner_person_key": "<PERSON_KEY DO TOMADOR>",
  "requester_key": "<REQUESTER_KEY DO PARCEIRO>",
  "webhook_enabled": true
}
```

**Response Body**

```json
{
  "account_key": "1167955-...",
  "account_branch": "0001",
  "account_number": "1167955",
  "account_digit": "1",
  "owner_document_number": "<CPF DO MILITAR>",
  "owner_name": "<NOME DO MILITAR>",
  "bank_code": "329",
  "account_status": "active",
  "webhook_enabled": true
}
```

:::tip Idempotência por tomador
Se já existe conta ativa para esse `owner_document_number` no parceiro, evite chamar `POST /account` de novo — consulte `GET /accounts?owner_document_number= ` antes e reaproveite o `account_key` retornado.
:::

---

## 3. Abrir o lote

ENDPOINT /document/document_batch
MÉTODO POST

**Request Body**

```json
{
  "type": "federal_payroll_external_batch",
  "certifier_type": "qi_sign",
  "batch_name": "Lote SIAPE portabilidade - <UUID_UNICO>",
  "request_control_key": "<UUID_UNICO_2>"
}
```

### Campos chave

| Campo | Tipo | Descrição |
|---|---|---|
| `type` | string | Fixo: **`federal_payroll_external_batch`** |
| `certifier_type` | string | Fixo: **`qi_sign`** |
| `batch_name` | string | Nome identificador do lote — **único** (não reutilize entre lotes) e **máximo 100 caracteres** |
| `request_control_key` | string (UUIDv4) | **Idempotência** — não reutilize entre lotes |

**Response Body**

```json
{
  "document_batch_key": "17f35e19-a039-468f-aaa7-84aa8edec3dc"
}
```

Guarde o `document_batch_key` retornado — ele é referenciado em todas as chamadas seguintes.

→ Para consultar, limpar documentos ou conferir o batch antes do envio, ver [Assinatura em Lote](./11-assinatura-em-lote.md).

---

## 4. Emitir `debt_purchase`

CCB de **quitação da dívida original**. A QI Tech vai pagar o banco vendedor.

ENDPOINT /debt
MÉTODO POST

:::info Particularidades do `debt_purchase`
- `document_batch_key` incluído na **raiz** do payload (mesmo nível de `borrower`, `financial`).
- `disbursement_bank_account` aponta para a **conta interna QI** do tomador (Criada no passo 2).
- `after_disbursement_actions` na raiz define a quitação automática da dívida origem após o desembolso (boleto ou PIX do banco vendedor).
:::

**Request Body**

```json
{
  "borrower": {
    "name": "MARIA DOS SANTOS",
    "email": "maria@email.com",
    "phone": { "number": "900000000", "area_code": "11", "country_code": "055" },
    "is_pep": false,
    "address": {
      "city": "Brasília",
      "state": "DF",
      "number": "100",
      "street": "Esplanada dos Ministérios",
      "complement": "",
      "postal_code": "70000000",
      "neighborhood": "Centro"
    },
    "role_type": "issuer",
    "birth_date": "1978-09-22",
    "mother_name": "JOSEFINA DOS SANTOS",
    "nationality": "Brasileiro",
    "person_type": "natural",
    "marital_status": "married",
    "individual_document_number": "25256363506",
    "gender": "female",
    "document_identification_type": "rg",
    "document_identification_number": "1234567",
    "document_identification_date": "2015-01-01"
  },
  "financial": {
    "first_due_date": "2026-06-10",
    "installment_face_value": 100,
    "disbursement_date": "2026-05-10",
    "limit_days_to_disburse": 5,
    "number_of_installments": 20,
    "monthly_interest_rate": 0.017,
    "interest_type": "pre_price_days",
    "fine_configuration": {
      "monthly_rate": 0.01,
      "interest_base": "calendar_days",
      "contract_fine_rate": 0.02
    },
    "credit_operation_type": "ccb",
    "interest_grace_period": 0,
    "principal_grace_period": 0
  },
  "simplified": true,
  "collaterals": [],
  "requester_identifier_key": "<UUIDv4 gerado por request>",
  "disbursement_bank_account": {
    "bank_code": "329",
    "account_digit": "7",
    "branch_number": "0001",
    "account_number": "4944068",
    "document_number": "25256363506",
    "name": "MARIA DOS SANTOS"
  },
  "purchaser_document_number": "<CNPJ do comprador>",
  "document_batch_key": "<document_batch_key DO PASSO 2>",
  "after_disbursement_actions": [
    {
      "action_type": "bankslip_payment",
      "action_data": {
        "qr_code": null,
        "destination": null,
        "digitable_line": "03399199530490000005237385601010297590005474921",
        "pix_transfer_type": null,
        "transaction_amount": 0
      }
    }
  ]
}
```

### Campos que devem ser alterados

| Campo | Obrigatório alterar? | Observação |
|---|---|---|
| `document_batch_key` | ✅ Sim | Valor retornado no Passo 2 |
| `borrower.*` | ✅ Sim | Dados reais do tomador |
| `financial.first_due_date` / `disbursement_date` | ✅ Sim | Conforme calendário da operação |
| `financial.installment_face_value` / `number_of_installments` / `monthly_interest_rate` | ✅ Sim | Conforme condições comerciais |
| `purchaser_document_number` | ✅ Sim | CNPJ do comprador (via variável de ambiente) |
| `requester_identifier_key` | ✅ Sim | UUIDv4 único por requisição |
| `disbursement_bank_account` | ✅ Sim | **Conta interna QI em nome do tomador** |
| `after_disbursement_actions` | ✅ Sim | Quitação da dívida origem. `action_type`: `bankslip_payment` (boleto) ou PIX. Preencha `digitable_line` (boleto) ou `qr_code` (PIX) do banco vendedor |

**Response Body**

```json
{
  "proposal_id": "<id interno>",
  "status": 200,
  "key": "<key da operação debt_purchase>",
  "data": {
    "credit_operation_key": "<mesmo valor de key>",
    "status": "waiting_signature"
  }
}
```

**Guarde a `key` retornada** — ela é passada em `refinanced_credit_operations[].operation_key` da `portability` correspondente.

---

## 5. Emitir `portability`

CCB de **portabilidade da dívida**. Cada portabilidade referencia **exatamente um** `debt_purchase` via `refinanced_credit_operations`. **Não carrega seguro nem troco** — ambos vão no `refinancing` consolidador.

ENDPOINT /debt
MÉTODO POST

:::info Particularidades da `portability`
- `collaterals[0].collateral_data.portability_data` é **obrigatório** — contém os dados do contrato de origem na instituição vendedora.
- `refinanced_credit_operations` carrega a `key` do `debt_purchase` correspondente.
:::

:::caution Portabilidade sem seguro e sem troco
Em batch federal, a `portability` **não pode** carregar `financial.rebates` (seguro). O seguro é enviado exclusivamente no `refinancing` consolidador. A QI Tech rejeita o `POST /debt` que violar essa regra.
:::

**Request Body**

```json
{
  "borrower": { "...": "mesmo borrower do Passo 4" },
  "financial": {
    "first_due_date": "2026-06-10",
    "disbursement_date": "2026-05-10",
    "limit_days_to_disburse": 5,
    "number_of_installments": 20,
    "monthly_interest_rate": 0.017,
    "interest_type": "pre_price_days",
    "final_disbursement_amount": 0,
    "fine_configuration": {
      "monthly_rate": 0.01,
      "interest_base": "calendar_days",
      "contract_fine_rate": 0.02
    },
    "credit_operation_type": "ccb",
    "interest_grace_period": 0,
    "principal_grace_period": 0
  },
  "simplified": true,
  "collaterals": [
    {
      "percentage": 1,
      "collateral_type": "federal_payroll",
      "collateral_data": {
        "authority": {
          "description": "GOVERNO DO DISTRITO FEDERAL",
          "authority_document_number": "00.394.601/0001-26"
        },
        "authority_code": "99072",
        "reservation_type": "portability",
        "registration_code": "1393831",
        "reservation_method": "issuing",
        "pensioner_registration_code": "",
        "portability_data": {
          "start_date": "2024-06-24",
          "control_number": "57309647149",
          "origin_contract": {
            "contract_number": "866415127",
            "financial_institution_document_number": "90400888000142"
          }
        }
      }
    }
  ],
  "requester_identifier_key": "<UUIDv4>",
  "disbursement_bank_account": { "...": "mesmo disbursement do Passo 4" },
  "purchaser_document_number": "<CNPJ do comprador>",
  "document_batch_key": "<document_batch_key DO PASSO 2>",
  "refinanced_credit_operations": [
    { "operation_key": "<key DO PASSO 4>" }
  ]
}
```

### Campos que devem ser alterados

| Campo | Obrigatório alterar? | Observação |
|---|---|---|
| `document_batch_key` | ✅ Sim | Valor retornado no Passo 2 |
| `refinanced_credit_operations[0].operation_key` | ✅ Sim | `key` do `debt_purchase` referenciado (Passo 4) |
| `collaterals[0].collateral_data.registration_code` | ✅ Sim | Matrícula SIAPE do servidor |
| `collaterals[0].collateral_data.authority_code` / `authority.description` / `authority.authority_document_number` | ✅ Sim | Órgão pagador (UPAG) |
| `portability_data.start_date` | ✅ Sim | Data de início do contrato de origem |
| `portability_data.control_number` | ✅ Sim | Número de controle no SIAPE |
| `portability_data.origin_contract.contract_number` | ✅ Sim | Nº do contrato na instituição vendedora |
| `portability_data.origin_contract.financial_institution_document_number` | ✅ Sim | CNPJ da instituição vendedora |
| `financial.installment_face_value` | 🚫 Não enviar | Valor da parcela (auto calculado) |
| `financial.rebates` | 🚫 Proibido | Seguro não é aceito em portabilidade — só no `refinancing` |

**Response Body**

```json
{
  "proposal_id": "<id interno>",
  "status": 200,
  "key": "<key da operação portability>",
  "data": {
    "credit_operation_key": "<mesmo valor de key>",
    "status": "waiting_signature"
  }
}
```

**Guarde a `key` desta portabilidade** — usada em `refinanced_credit_operations` do `refinancing` consolidador (Passo 5) no cenário β.

### Erros possíveis na criação

| Código | HTTP | Quando |
|---|---|---|
| `DOC000110` | 422 | `refinanced_credit_operations[].operation_key` não casa com nenhum `credit_operation_key` de `debt_purchase` já inserido no batch |
| `DOC000114` | 422 | `refinanced_credit_operations[].operation_key` já está em outra portabilidade do mesmo batch (duplicidade) |
| `COP000515` | 400 | `final_disbursement_amount` ≠ `0` — portabilidade não carrega troco |
| `COP000516` | 400 | `financial.rebates` presente — portabilidade federal não aceita seguro |

---

## 6. Emitir `refinancing` consolidador

CCB **mãe** que consolida as portabilidades num único instrumento. **Sempre obrigatória** no batch federal — tanto no cenário α (1 portabilidade) quanto no β (N portabilidades). É a única operação do fluxo que carrega **seguro** e **troco**.

ENDPOINT /debt
MÉTODO POST

:::info Particularidades do `refinancing` consolidador
- `reservation_type: "refinancing"` no `collateral_data`.
- `refinanced_credit_operations` lista as `key` de **todas** as portabilidades do batch.
- `disbursement_bank_account` aponta para a **conta externa do tomador** — destino do troco.
- `financial.rebates` é **opcional** — único lugar do fluxo que aceita seguro.
- `after_disbursement_actions` só é enviado **quando há seguro** — liquida o prêmio após o desembolso.
:::

:::caution `after_disbursement_actions` exige seguro
`after_disbursement_actions` só pode ser enviado no `refinancing` **quando a operação tem seguro** (`financial.rebates` presente). Enviar `after_disbursement_actions` sem `rebates` faz a QI Tech rejeitar o `POST /debt`.
:::

**Request Body**

**Sem seguro**

```json
{
  "borrower": { "...": "mesmo borrower" },
  "financial": {
    "first_due_date": "2026-06-10",
    "installment_face_value": 1000,
    "disbursement_date": "2026-05-10",
    "limit_days_to_disburse": 5,
    "number_of_installments": 20,
    "monthly_interest_rate": 0.017,
    "interest_type": "pre_price_days",
    "fine_configuration": {
      "monthly_rate": 0.01,
      "interest_base": "calendar_days",
      "contract_fine_rate": 0.02
    },
    "credit_operation_type": "ccb",
    "interest_grace_period": 0,
    "principal_grace_period": 0
  },
  "simplified": true,
  "collaterals": [
    {
      "percentage": 1,
      "collateral_type": "federal_payroll",
      "collateral_data": {
        "authority": {
          "description": "GOVERNO DO DISTRITO FEDERAL",
          "authority_document_number": "00.394.601/0001-26"
        },
        "authority_code": "99072",
        "reservation_type": "refinancing",
        "registration_code": "1393831",
        "reservation_method": "issuing",
        "pensioner_registration_code": ""
      }
    }
  ],
  "requester_identifier_key": "<UUIDv4>",
  "disbursement_bank_account": { "...": "conta externa do tomador" },
  "purchaser_document_number": "<CNPJ do comprador>",
  "document_batch_key": "<document_batch_key DO PASSO 2>",
  "refinanced_credit_operations": [
    { "operation_key": "<key da portabilidade 1>" },
    { "operation_key": "<key da portabilidade 2>" }
  ]
}
```

**Com seguro + troco (Cenário γ)**

```json
{
  "borrower": { "...": "mesmo borrower" },
  "financial": {
    "first_due_date": "2026-06-10",
    "installment_face_value": 1500,
    "disbursement_date": "2026-05-10",
    "limit_days_to_disburse": 5,
    "number_of_installments": 20,
    "monthly_interest_rate": 0.017,
    "interest_type": "pre_price_days",
    "fine_configuration": {
      "monthly_rate": 0.01,
      "interest_base": "calendar_days",
      "contract_fine_rate": 0.02
    },
    "credit_operation_type": "ccb",
    "interest_grace_period": 0,
    "principal_grace_period": 0,
    "rebates": [
      {
        "fee_type": "insurance_premium_qi",
        "description": "credit_insurance_blindado"
      }
    ]
  },
  "simplified": true,
  "collaterals": [
    {
      "percentage": 1,
      "collateral_type": "federal_payroll",
      "collateral_data": {
        "authority": {
          "description": "GOVERNO DO DISTRITO FEDERAL",
          "authority_document_number": "00.394.601/0001-26"
        },
        "authority_code": "99072",
        "reservation_type": "refinancing",
        "registration_code": "1393831",
        "reservation_method": "issuing",
        "pensioner_registration_code": ""
      }
    }
  ],
  "requester_identifier_key": "<UUIDv4>",
  "disbursement_bank_account": { "...": "conta externa do tomador" },
  "purchaser_document_number": "<CNPJ do comprador>",
  "document_batch_key": "<document_batch_key DO PASSO 2>",
  "refinanced_credit_operations": [
    { "operation_key": "<key da portabilidade 1>" },
    { "operation_key": "<key da portabilidade 2>" }
  ],
  "after_disbursement_actions": [
    {
      "action_type": "bankslip_payment",
      "action_data": {
        "qr_code": null,
        "destination": null,
        "digitable_line": "03399199530490000005237385601010297590005474921",
        "pix_transfer_type": null,
        "transaction_amount": 0
      }
    }
  ]
}
```

### Campos que devem ser alterados

| Campo | Obrigatório alterar? | Observação |
|---|---|---|
| `document_batch_key` | ✅ Sim | Valor retornado no Passo 2 |
| `refinanced_credit_operations` | ✅ Sim | **Todas** as `key` das portabilidades emitidas no Passo 5 |
| `collaterals[0].collateral_data.authority.*` / `authority_code` / `registration_code` | ✅ Sim | Conforme órgão e servidor |
| `reservation_method` | ✅ Sim | Sempre `"issuing"` para o consolidador |
| `disbursement_bank_account` | ✅ Sim | **Conta externa do tomador** — destino do troco |
| `financial.rebates` | ⚠️ Opcional | Único lugar do fluxo que aceita seguro. Incluir `[{ "fee_type": "insurance_premium_qi", ... }]` apenas se a operação tem seguro |
| `financial.final_disbursement_amount` | 🚫 Não enviar | Valor final do desembolso (troco) calculado automaticamente baseado no valor da parcela |
| `after_disbursement_actions` | ⚠️ Só com seguro | Liquida o prêmio do seguro após desembolso. **Só envie quando `rebates` está presente** — caso contrário a QI Tech rejeita o `POST /debt` |

### Erros possíveis na criação

| Código | HTTP | Quando |
|---|---|---|
| `DOC000109` | 422 | Batch já contém outro `refinancing` — só 1 por batch |
| `DOC000112` | 422 | `refinanced_credit_operations[].operation_key` não casa com nenhum `credit_operation_key` de portabilidade no batch |
| `COP000517` | 400 | `refinancing` **com** seguro (`rebates`) sem nenhuma `after_disbursement_actions` — seguro exige ao menos uma ação pós-desembolso |
| `COP000518` | 400 | `refinancing` **sem** seguro carregando `after_disbursement_actions` — só permitido quando há `rebates` |

---

## 7. Enviar para assinatura

Fecha o lote e dispara os documentos para o QI Sign. **Antes desse PUT, nada é enviado ao servidor.**

ENDPOINT /document/document_batch/DOCUMENT_BATCH_KEY/send_to_signature
MÉTODO PUT

Body: `{}`. Response: **HTTP 200**.

### Erros possíveis no envio

| Código | HTTP | Quando |
|---|---|---|
| `DOC000108` | 422 | Batch contém mais de 1 `insurance_premium_term` |
| `DOC000109` | 422 | Batch contém mais de 1 `refinancing` |
| `DOC000110` | 422 | `portability` cujo `refinanced_op` não casa com nenhum `debt_purchase` no batch |
| `DOC000111` | 422 | Batch **sem** `refinancing` consolidador |
| `DOC000114` | 422 | `debt_purchase` referenciado por 0 ou mais de 1 portabilidade |

:::tip Conferir antes de enviar
Use `GET /document/document_batch/DOCUMENT_BATCH_KEY` para listar os documentos agrupados e confirmar a composição antes do `send_to_signature`. Ver [Assinatura em Lote](./11-assinatura-em-lote.md).
:::

→ Próximo passo: [Formalização](./05-formalizacao.md)

---

## Mapa consolidado de erros

| Código | HTTP | Ponto de disparo | Quando |
|---|---|---|---|
| `DOC000108` | 422 | criação + envio | Mais de 1 `insurance_premium_term` no batch |
| `DOC000109` | 422 | criação + envio | Mais de 1 `refinancing` no batch |
| `DOC000110` | 422 | criação + envio | `portability` com `refinanced_op` sem `debt_purchase` casado no batch |
| `DOC000111` | 422 | envio | Batch sem `refinancing` consolidador |
| `DOC000112` | 422 | criação | `refinancing` com `refinanced_op` sem portabilidade casada no batch |
| `DOC000114` | 422 | criação + envio | `debt_purchase` referenciado por ≠ 1 portabilidade (0 órfão ou ≥ 2 duplicado) |
| `COP000515` | 400 | criação (`portability`) | `final_disbursement_amount` ≠ `0` na portabilidade |
| `COP000516` | 400 | criação (`portability`) | `financial.rebates` enviado na portabilidade federal |
| `COP000517` | 400 | criação (`refinancing`) | `refinancing` com seguro sem nenhuma `after_disbursement_actions` |
| `COP000518` | 400 | criação (`refinancing`) | `refinancing` sem seguro carregando `after_disbursement_actions` |

:::info Notas sobre erros recorrentes
- `DOC000110` dispara em **dois momentos**: na criação da portabilidade (validação imediata) e no envio (cobertura defensiva).
- `DOC000114` dispara em **dois momentos**: na criação da segunda portabilidade duplicada e no envio (cobre o `debt_purchase` órfão, i.e. `count = 0`).
- `DOC000111` dispara **apenas no envio** — não há validação na criação.
- Batches que **não** são `federal_payroll_external_batch` não disparam nenhuma das validações acima.
:::

---

## Glossário

| Termo | Significado |
|---|---|
| **CCB** | Cédula de Crédito Bancário — instrumento de dívida emitido pelo banco |
| **SIAPE** | Sistema Integrado de Administração de Recursos Humanos do Governo Federal — folha de pagamento dos servidores da União |
| **UPAG** | Unidade Pagadora — órgão da União que paga o salário do servidor (identificado por `authority_code` + `authority_document_number`) |
| **matrícula SIAPE** | `registration_code` — identificador do servidor na folha |
| **portability_data** | Dados do contrato de origem na instituição vendedora (`start_date`, `control_number`, `contract_number`, `financial_institution_document_number`) |
| **credit_operation_key** | Chave única da operação retornada por `POST /debt` — também chamada `key` |
| **insurance_premium_term** | Documento extra gerado automaticamente no batch quando uma `portability` ou `refinancing` carrega `financial.rebates` com `fee_type: "insurance_premium_qi"`. **Nunca** originado de `debt_purchase` |
| **QI Sign** | Provedor de assinatura digital QI Tech (configurado via `certifier_type: "qi_sign"`) |

---

# Webhooks

URL: /zh-Hans/documentation/siape/webhooks

Eventos assíncronos emitidos pela QI Tech durante o ciclo de vida da operação consignada SIAPE. Todos seguem o protocolo unificado de [Webhooks QI](/documentation/webhooks/notificacoes_baas_e_laas) — 5 segundos pra resposta HTTP 200 com `encoded_body` assinado, 3 retries de 5 minutos em caso de falha.

:::danger Atenção!
Os webhooks da QI Tech **não devem ser mapeados de forma restrita**. Campos adicionais podem ser incluídos aos payloads a qualquer momento. Use desserialização permissiva.
:::

## Webhooks específicos do produto SIAPE

| Webhook | Quando dispara | Origem |
|---|---|---|
| `federal_payroll.balance` | Resultado da consulta de margem (`succeeded` ou `failure`) | federal-payroll-api |
| `credit_operation.collateral` | Averbação ou desaverbação no SIGEPE | credit-operation-api |
| `credit_transfer.received_portability` | Portabilidade externa recebida (banco origem aceitou) | credit-transfer-api |
| `credit_transfer_status_change` | Atualização do credit-transfer | credit-transfer-api |

## Webhooks comuns LaaS

| Webhook | Status | Quando dispara |
|---|---|---|
| `debt` | `waiting_signature` | Operação criada, aguardando assinatura |
| `debt` | `signature_finished` | Assinatura concluída |
| `debt` | `disbursed` | Desembolso PIX/TED enviado |
| `debt` | `canceled` | Operação cancelada |
| `debt` | `canceled_permanently` | Cancelamento definitivo |
| `debt` | `settled` | Operação liquidada |
| `reversal` | `pending_fund` | Borrower pagou PIX QR de cancelamento — reversal iniciado |
| `installment.status_change` | `paid` / `overdue` / etc | Mudança de status de parcela individual |
| `laas.devolution.refund_receipt` | `refunded` | Devolução de overpayment via PIX |

## Estrutura padrão

```json
{
  "key": "<UUID da operação>",
  "data": ,
  "status": "<status>",
  "webhook_type": "<tipo>",
  "event_datetime": "2026-06-02 14:30:00"
}
```

## Exemplos

### `federal_payroll.balance` (sucesso)

```json
{
  "webhook_type": "federal_payroll.balance",
  "key": "81da8afb-e1b2-4215-8093-c4b5feab8a9f",
  "status": "succeeded",
  "data": {
    "balance_query": [
      {
        "available_balance": 3500.00,
        "authority_code": "17000",
        "registration_code": "1354387",
        "employment_relationship": "active",
        "consigned_credit": 1200.00,
        "consigned_card": 300.00
      }
    ]
  },
  "event_datetime": "2026-06-02 14:30:00"
}
```

### `credit_operation.collateral` (pending_consent)

```json
{
  "webhook_type": "credit_operation.collateral",
  "key": "27a099df-4688-43cb-87fa-515b1cf343a5",
  "status": "pending_consent",
  "data": {
    "collateral_constituted": false,
    "enumerator": "waiting_borrower_consent"
  },
  "event_datetime": "2026-06-02 15:00:00"
}
```

### `credit_operation.collateral` (success)

```json
{
  "webhook_type": "credit_operation.collateral",
  "key": "27a099df-4688-43cb-87fa-515b1cf343a5",
  "status": "success",
  "data": {
    "collateral_constituted": true,
    "enumerator": "successfully_reserved",
    "reservation_status": "reserved"
  },
  "event_datetime": "2026-06-02 15:30:00"
}
```

### `debt` (disbursed)

```json
{
  "webhook_type": "debt",
  "key": "27a099df-4688-43cb-87fa-515b1cf343a5",
  "status": "disbursed",
  "data": {
    "ted_receipt_list": [{
      "amount": 12500.00,
      "transaction_key": "...",
      "destination": { "name": "MARIA DOS SANTOS", "bank_ispb": "60746948" }
    }]
  },
  "event_datetime": "2026-06-02 16:00:00"
}
```

### `reversal` (cancelamento pós-desembolso)

```json
{
  "webhook_type": "reversal",
  "credit_operation_key": "2893b8bd-...",
  "contract_number": "0000049333/TW",
  "reversal": {
    "status": "pending_fund",
    "amount": 12500.00,
    "is_total": true,
    "is_operation_canceled": true,
    "reversal_key": "...",
    "date": "2026-09-06"
  }
}
```

## Cancel reasons (`cancel_reason_enumerator`)

| Enumerador | Significado |
|---|---|
| `manual` | Cancelado via API ou portal |
| `waiting_signature` | Não assinou no prazo |
| `not_collateral_constituted` | Averbação falhou (`consent_refused`, `consent_expired`, etc.) |
| `is_portability` | Portabilidade falhou |
| `pix_max_retry` | Muitas falhas no desembolso PIX |
| `lack_of_resource` | Sem recurso pra desembolsar |
| `kyc_not_accepted` | KYC reprovado |

→ Lista completa em [Mapa de Status](./08-mapa-de-status.md)

## Reenvio Manual

Webhooks podem ser consultados e reenviados via portal seguindo [Reenvio de Webhooks](/documentation/notificacoes/reenvio_de_notificacoes).