Renegociação com IOF Spread e Desconto Somente Juros - BNPL
Resumo
Esta página documenta o fluxo de renegociação em lote para operações BNPL em que a operação de crédito foi criada com iof_charge_method: "spread". Nesse modelo, o IOF não é financiado nas parcelas — ele é calculado normalmente, mas adicionado ao assignment_amount (valor de cessão), e não às prestações do tomador.
Além disso, é possível utilizar o campo discount_validation: "only_interest_discount" em cada operação do array operations[] para restringir os descontos aplicados somente à parcela de juros. Se o desconto exceder os juros e atingir o principal ou a multa, a API retornará o erro InvalidDiscountAmountOnlyInterestDiscount.
O fluxo utiliza os endpoints de lote: simulação (POST /renegotiation/batch_proposal_simulation) seguida da proposta (POST /renegotiation/batch_proposal). O campo discount_validation é definido por operação no array operations[], e não no nível raiz do payload.
O campo iof_charge_method é definido no momento da criação da operação de crédito (credit-operation-api), e não durante a renegociação. Quando iof_charge_method: "spread":
- O IOF é calculado normalmente (IOF base + IOF adicional), mas não é deduzido das parcelas do tomador
- O IOF é adicionado ao
assignment_amount— ou seja, o custo do IOF é refletido no valor de cessão - As parcelas do tomador são "limpas" de IOF
Os três valores possíveis são:
"financed"(padrão) — IOF é financiado nas parcelas (deduzido do valor creditado ao tomador)"spread"— IOF é adicionado ao valor de cessão (assignment_amount), não às parcelas"free"— Sem IOF (total_iof = 0)
Quando discount_validation: "only_interest_discount" é definido em uma operação, o sistema valida que o desconto aplicado em cada parcela não inclui amortização de principal (discount_principal_amortization_amount) nem multa (discount_fine_amount). Somente os juros (juros prefixados) podem ser descontados.
Se qualquer parcela tiver um desconto que atinja o principal ou a multa, a API retorna o erro InvalidDiscountAmountOnlyInterestDiscount e a requisição inteira falha.
Passo 1: Simulação em Lote
Os campos discount_amount e discount_percentage NÃO podem ser enviados juntos no mesmo payload (nível raiz).
Request Body
{
"amortization_type": "installment_payment",
"reference_date": "2026-04-20",
"discount_percentage": 0.0,
"operations": [
{
"debt_key": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"discount_validation": "only_interest_discount",
"installments": [
{
"installment_key": "f9e8d7c6-b5a4-3210-fedc-ba9876543210"
}
]
}
]
}
Body Params
| Campo | Tipo | Descrição | Caracteres |
|---|---|---|---|
amortization_type* | string | Tipo de amortização | Enumeradores Amortization Type |
reference_date* | string | Data de referência para cálculo do valor presente (precisa ser D+1) | 10 |
discount_percentage | float | Percentual de desconto sobre o valor presente ((1 - percentual) × Valor Presente) | 10 |
discount_amount | float | Valor de desconto aplicado sobre o valor presente | 10 |
operations* | array | Lista de operações a serem renegociadas | Objeto Operations |
Objeto Operations
| Campo | Tipo | Descrição | Caracteres |
|---|---|---|---|
debt_key* | string | Chave única da operação de crédito (DEBT-KEY) | UUID |
discount_validation | string | Regra de validação de desconto. Quando definido como "only_interest_discount", o desconto aplicado não pode ultrapassar a parcela de juros. | Enumeradores Discount Validation |
installments* | array | Parcelas a serem renegociadas | Objeto Installments |
Objeto Installments
| Campo | Tipo | Descrição | Caracteres |
|---|---|---|---|
installment_key* | string | Chave da parcela a ser renegociada | UUID |
paid_amount | float | Valor pago (ou alocado) na parcela, em reais (R$). Obrigatório quando amortization_type é present_amount. | 15,2 |
discount_amount | float | Valor de desconto em reais (R$) na parcela. Obrigatório quando amortization_type é present_amount (use 0 se não houver desconto). Opcional nos demais tipos. | 15,2 |
Enumeradores Discount Validation
| Campo | Descrição |
|---|---|
only_interest_discount | Valida que o desconto aplicado em cada parcela não ultrapassa o valor de juros. Caso o desconto atinja o principal ou multa, a API retorna o erro InvalidDiscountAmountOnlyInterestDiscount. |
Enumeradores Amortization Type
| Campo | Descrição |
|---|---|
| installment_payment | Renegociação para pagamento de parcelas específicas enviadas no payload. Requer installment_key de cada parcela. |
| overdue_installment_payment | Renegociação direcionada para pagamento de parcelas em atraso. Requer installment_key de cada parcela. |
| present_amount | Simulação com valor presente por parcela. Em cada installments[] é obrigatório installment_key, paid_amount e discount_amount. |
Response
Response Body
{
"batch_proposal_key": "7423c701-3578-4733-8f30-81ab60afdb6d",
"discount_percentage": 0,
"discount_amount": 0,
"amortization_type": "installment_payment",
"payment_amount": 517.88,
"requester_name": "Empresa Exemplo Ltda",
"requester_key": "78287247-947d-4730-9bd1-7efb068175b6",
"issuer_name": "João da Silva",
"reference_date": "2026-04-20",
"issuer_document_number": "31057466093",
"operations": [
{
"requester_key": "78287247-947d-4730-9bd1-7efb068175b6",
"contract_number": "DWF1761222116",
"payment_amount": 517.88,
"discount_amount": 0,
"origin_key": null,
"affected_installments": [
{
"installment_key": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
"due_date": "2026-05-07",
"principal_amount": 491.49,
"interest_amount": 52.40,
"fine_amount": 0,
"total_amount": 543.89,
"present_amount": 517.88,
"paid_amount": 517.88,
"principal_amortization_payment_amount": 491.49,
"prefixed_interest_payment_amount": 26.39,
"fine_payment_amount": 0,
"discount_amount": 0
}
],
"remaining_installments": [
{
"installment_key": "370e73d1-55d8-431e-9b22-d08fb8297999",
"due_date": "2026-06-07",
"principal_amount": 516.13,
"interest_amount": 27.76,
"fine_amount": 0,
"total_amount": 543.89
}
],
"debt_key": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
]
}
Passo 2: Proposta em Lote
Os campos discount_amount e discount_percentage NÃO podem ser enviados juntos no mesmo payload (nível raiz).
Request Body
{
"amortization_type": "installment_payment",
"reference_date": "2026-04-20",
"proposal_due_date": "2026-04-27",
"payment_type": "pix",
"discount_percentage": 0.0,
"request_control_key": "94b31045-c8e7-45be-a88d-2ae25c5df5db",
"operations": [
{
"debt_key": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"discount_validation": "only_interest_discount",
"installments": [
{
"installment_key": "f9e8d7c6-b5a4-3210-fedc-ba9876543210"
}
]
}
]
}
Body Params
| Campo | Tipo | Descrição | Caracteres |
|---|---|---|---|
amortization_type* | string | Tipo de amortização | Enumeradores Amortization Type |
reference_date* | string | Data de referência para cálculo do valor presente (D+1) | 10 |
proposal_due_date* | string | Data de vencimento da proposta de renegociação | 10 |
payment_type* | string | Tipo de pagamento | Enumeradores Payment Type |
request_control_key | string | Chave de controle para rastreamento e identificação única (opcional) | UUID |
discount_percentage | float | Percentual de desconto sobre o valor presente | 10 |
discount_amount | float | Valor de desconto sobre o valor presente | 10 |
operations* | array | Lista de operações a serem renegociadas | Objeto Operations |
Objeto Operations
| Campo | Tipo | Descrição | Caracteres |
|---|---|---|---|
debt_key* | string | Chave única da operação de crédito (DEBT-KEY) | UUID |
discount_validation | string | Regra de validação de desconto. Quando definido como "only_interest_discount", o desconto aplicado não pode ultrapassar a parcela de juros. | Enumeradores Discount Validation |
installments* | array | Parcelas a serem renegociadas | Objeto Installments |
Objeto Installments
| Campo | Tipo | Descrição | Caracteres |
|---|---|---|---|
installment_key* | string | Chave da parcela a ser renegociada | UUID |
paid_amount | float | Valor pago (ou alocado) na parcela, em reais (R$). Obrigatório quando amortization_type é present_amount. | 15,2 |
discount_amount | float | Valor de desconto em reais (R$) aplicado na parcela. Obrigatório quando amortization_type é present_amount (use 0 se não houver desconto). Para outros tipos de amortização, permanece opcional por parcela. | 15,2 |
Enumeradores Discount Validation
| Campo | Descrição |
|---|---|
only_interest_discount | Valida que o desconto aplicado em cada parcela não ultrapassa o valor de juros. Caso o desconto atinja o principal ou multa, a API retorna o erro InvalidDiscountAmountOnlyInterestDiscount. |
Enumeradores Payment Type
| Campo | Descrição |
|---|---|
bank_slip | Pagamento via boleto bancário (gera boleto e Pix) |
pix | Pagamento via Pix (gera apenas Pix) |
manual | Pagamento feito de forma manual (não gera forma de pagamento) |
Enumeradores Amortization Type
| Campo | Descrição |
|---|---|
| installment_payment | Renegociação para pagamento de parcelas específicas. Requer installment_key de cada parcela. |
| overdue_installment_payment | Renegociação direcionada para pagamento de parcelas em atraso. Requer installment_key de cada parcela. |
| present_amount | Renegociação com composição por valor presente por parcela. Em cada item de installments[] é obrigatório informar installment_key, paid_amount e discount_amount. |
Response
Response Body
{
"batch_proposal_key": "ff5ad6dd-2087-4850-a3e8-b37634448b4e",
"discount_percentage": 0,
"discount_amount": 0,
"amortization_type": "installment_payment",
"payment_amount": 517.88,
"requester_name": "Empresa Exemplo Ltda",
"requester_key": "78287247-947d-4730-9bd1-7efb068175b6",
"issuer_name": "João da Silva",
"reference_date": "2026-04-20",
"issuer_document_number": "31057466093",
"batch_proposal_status": "pending_payment",
"proposal_due_date": "2026-04-27",
"payment_type": "pix",
"request_control_key": "94b31045-c8e7-45be-a88d-2ae25c5df5db",
"origin_key": null,
"operations": [
{
"requester_key": "78287247-947d-4730-9bd1-7efb068175b6",
"contract_number": "DWF1761222116",
"payment_amount": 517.88,
"discount_amount": 0,
"origin_key": null,
"affected_installments": [
{
"installment_key": "f9e8d7c6-b5a4-3210-fedc-ba9876543210",
"due_date": "2026-05-07",
"principal_amount": 491.49,
"interest_amount": 52.40,
"fine_amount": 0,
"total_amount": 543.89,
"present_amount": 517.88,
"paid_amount": 517.88,
"principal_amortization_payment_amount": 491.49,
"prefixed_interest_payment_amount": 26.39,
"fine_payment_amount": 0,
"discount_amount": 0
}
],
"remaining_installments": [
{
"installment_key": "370e73d1-55d8-431e-9b22-d08fb8297999",
"due_date": "2026-06-07",
"principal_amount": 516.13,
"interest_amount": 27.76,
"fine_amount": 0,
"total_amount": 543.89
}
],
"debt_key": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
],
"payment": {
"digitable_line": null,
"qr_code_url": "00020126930014br.gov.bcb.pix2571qrcode-h.sandbox.qitech.app/bacen/cobv/acaeb341e1264cde99b93e247e12b3725204000053039865802BR5925QISOCIEDADEDECREDITODIRET6008SaoPaulo61080145200062070503***63043AD0",
"qr_code_key": "acaeb341-e126-4cde-99b9-3e247e12b372",
"bank_slip_key": null,
"paid_method_type": "pix",
"source_account_key": null,
"payment_data": {
"creditor_bank_account_key": "6108dd45-580d-48c4-b3bb-74c1e843be49",
"batch_renegotiation_proposal_key": "ff5ad6dd-2087-4850-a3e8-b37634448b4e"
}
}
}
Salve a batch_proposal_key retornada na resposta. Ela será necessária para consultar o status da renegociação em lote e para receber os webhooks de pagamento.
Erro: Desconto Excede Juros
Quando discount_validation: "only_interest_discount" é definido em uma operação e o valor de desconto aplicado excede a parcela de juros, a API retorna o seguinte erro:
Resposta de Erro
{
"code": "InvalidDiscountAmountOnlyInterestDiscount",
"message": "Discount amount must be only interest discount"
}
A validação é feita por parcela durante o processamento da amortização. Se qualquer parcela individual tiver um desconto cujo valor inclua amortização de principal (discount_principal_amortization_amount > 0) ou multa (discount_fine_amount > 0), a requisição inteira é rejeitada.
Cessão (Assignment)
Após a proposta ser paga, o passo de cessão (POST /credit_operations/assign) cria uma transferência formal da operação de crédito. Este é um endpoint separado da credit-operation-api.
Quando a operação de crédito possui iof_charge_method: "spread", o assignment_amount calculado inclui o IOF que não foi financiado nas parcelas. Ou seja, o valor de cessão reflete o custo total incluindo o IOF separado.