> ## Documentation Index
> Fetch the complete documentation index at: https://developers.uvvipague.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Simulação de Parcelas

> Simule opções de parcelamento antes de processar o pagamento

## Visão Geral

A API de Simulação de Parcelas permite calcular as opções de parcelamento disponíveis para um determinado valor, incluindo juros e valores totais. Esta funcionalidade é essencial para apresentar ao usuário as opções de pagamento antes de finalizar a transação.

<Info>
  **Transparência**: Mostre ao usuário todas as opções de parcelamento com valores exatos antes de processar o pagamento.
</Info>

<Warning>
  **Importante**: Todos os pagamentos possuem juros aplicados, incluindo pagamento à vista (1x) e PIX. As taxas variam conforme o método de pagamento e número de parcelas.
</Warning>

## Quando Usar

A simulação de parcelas deve ser usada:

<CardGroup cols={2}>
  <Card title="Antes do Checkout" icon="cart-shopping">
    Mostre as opções de parcelamento antes do usuário confirmar a compra
  </Card>

  <Card title="Cálculo de Juros" icon="percent">
    Apresente de forma transparente os juros aplicados em cada opção
  </Card>

  <Card title="Comparação de Valores" icon="scale-balanced">
    Permita que o usuário compare o valor à vista vs parcelado
  </Card>

  <Card title="Melhor Experiência" icon="star">
    Ofereça uma experiência completa mostrando todas as possibilidades
  </Card>
</CardGroup>

## Endpoint

```http theme={null}
POST /uvvi/v1/installments
```

## Parâmetros

<ParamField body="amount" type="number" required>
  Valor total a ser parcelado em reais (formato decimal)

  Exemplo: `1302.86`
</ParamField>

<ParamField body="paymentMethod" type="string" required>
  Método de pagamento para simular. Atualmente suportado: `credit_card`
</ParamField>

## Limites e Restrições

<CardGroup cols={2}>
  <Card title="Valor Mínimo por Parcela" icon="money-bill">
    **R\$ 5,00**

    Cada parcela deve ter no mínimo R\$ 5,00. Parcelas com valores inferiores não serão disponibilizadas.
  </Card>

  <Card title="Quantidade de Parcelas" icon="list-ol">
    **1 a 12 parcelas**

    O número máximo de parcelas depende do valor total dividido pelo valor mínimo de R\$ 5,00.
  </Card>

  <Card title="Juros Aplicados" icon="percent">
    **Todos os pagamentos**

    Juros são aplicados em todas as formas de pagamento, incluindo 1x e PIX.
  </Card>

  <Card title="Cálculo Dinâmico" icon="calculator">
    **Automático**

    A API retorna apenas as opções de parcelamento válidas conforme o valor informado.
  </Card>
</CardGroup>

## Exemplo de Requisição

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url 'https://api.uvvipague.com.br/uvvi/v1/installments' \
    --header 'x-api-key: SUA_API_KEY_AQUI' \
    --header 'Content-Type: application/json' \
    --data '{
      "amount": 1302.86,
      "paymentMethod": "credit_card"
    }'
  ```

  ```javascript JavaScript theme={null}
  const requestBody = {
    amount: 1302.86,
    paymentMethod: "credit_card"
  };

  const options = {
    method: 'POST',
    headers: {
      'x-api-key': 'SUA_API_KEY_AQUI',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(requestBody)
  };

  fetch('https://api.uvvipague.com.br/uvvi/v1/installments', options)
    .then(response => response.json())
    .then(data => {
      console.log('Opções de parcelamento:');
      data.installments.forEach(opt => {
        console.log(`${opt.number}x de R$ ${opt.installmentAmount.toFixed(2)}`);
      });
    })
    .catch(error => console.error('Erro:', error));
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.uvvipague.com.br/uvvi/v1/installments"
  headers = {
      "x-api-key": "SUA_API_KEY_AQUI",
      "Content-Type": "application/json"
  }
  payload = {
      "amount": 1302.86,
      "paymentMethod": "credit_card"
  }

  response = requests.post(url, headers=headers, json=payload)
  data = response.json()

  print('Opções de parcelamento:')
  for opt in data['installments']:
      print(f'{opt["number"]}x de R$ {opt["installmentAmount"]:.2f}')
  ```

  ```php PHP theme={null}
  <?php
  $curl = curl_init();

  $payload = json_encode([
      "amount" => 1302.86,
      "paymentMethod" => "credit_card"
  ]);

  curl_setopt_array($curl, [
      CURLOPT_URL => "https://api.uvvipague.com.br/uvvi/v1/installments",
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_POST => true,
      CURLOPT_POSTFIELDS => $payload,
      CURLOPT_HTTPHEADER => [
          "x-api-key: SUA_API_KEY_AQUI",
          "Content-Type: application/json"
      ],
  ]);

  $response = curl_exec($curl);
  curl_close($curl);

  $data = json_decode($response, true);

  echo "Opções de parcelamento:\n";
  foreach ($data['installments'] as $opt) {
      echo sprintf("%dx de R$ %.2f\n", $opt['number'], $opt['installmentAmount']);
  }
  ?>
  ```
</CodeGroup>

## Resposta

```json theme={null}
{
  "success": true,
  "amount": 1302.86,
  "installments": [
    {
      "number": 1,
      "installmentAmount": 1342.95,
      "totalAmount": 1342.95,
      "interestRate": 3.08,
      "interestAmount": 40.09
    },
    {
      "number": 2,
      "installmentAmount": 676.49,
      "totalAmount": 1352.98,
      "interestRate": 3.84,
      "interestAmount": 50.12
    },
    {
      "number": 3,
      "installmentAmount": 467.95,
      "totalAmount": 1403.85,
      "interestRate": 7.75,
      "interestAmount": 100.99
    },
    {
      "number": 4,
      "installmentAmount": 363.46,
      "totalAmount": 1453.84,
      "interestRate": 11.59,
      "interestAmount": 150.98
    },
    {
      "number": 5,
      "installmentAmount": 301.18,
      "totalAmount": 1505.90,
      "interestRate": 15.58,
      "interestAmount": 203.04
    },
    {
      "number": 6,
      "installmentAmount": 259.65,
      "totalAmount": 1557.90,
      "interestRate": 19.57,
      "interestAmount": 255.04
    },
    {
      "number": 7,
      "installmentAmount": 229.93,
      "totalAmount": 1609.51,
      "interestRate": 23.53,
      "interestAmount": 306.65
    },
    {
      "number": 8,
      "installmentAmount": 207.64,
      "totalAmount": 1661.12,
      "interestRate": 27.49,
      "interestAmount": 358.26
    },
    {
      "number": 9,
      "installmentAmount": 190.74,
      "totalAmount": 1716.66,
      "interestRate": 31.76,
      "interestAmount": 413.80
    },
    {
      "number": 10,
      "installmentAmount": 177.56,
      "totalAmount": 1775.60,
      "interestRate": 36.29,
      "interestAmount": 472.74
    },
    {
      "number": 11,
      "installmentAmount": 167.00,
      "totalAmount": 1837.00,
      "interestRate": 41.00,
      "interestAmount": 534.14
    },
    {
      "number": 12,
      "installmentAmount": 158.40,
      "totalAmount": 1900.80,
      "interestRate": 45.90,
      "interestAmount": 597.94
    }
  ]
}
```

## Exemplos de Valores e Parcelas Disponíveis

A quantidade de parcelas disponíveis varia conforme o valor total:

| Valor Total  | Parcelas Disponíveis | Motivo                               |
| ------------ | -------------------- | ------------------------------------ |
| R\$ 30,00    | 1x a 6x              | Máximo 6x (R$ 30,00 ÷ R$ 5,00 = 6)   |
| R\$ 50,00    | 1x a 10x             | Máximo 10x (R$ 50,00 ÷ R$ 5,00 = 10) |
| R\$ 100,00   | 1x a 12x             | Valor permite 20x, mas limite é 12x  |
| R\$ 1.302,86 | 1x a 12x             | Valor permite todas as 12 parcelas   |

<Note>
  **Importante**: A API retorna automaticamente apenas as opções válidas. Não é necessário calcular manualmente quais parcelas estão disponíveis.
</Note>

## Estrutura da Resposta

<ResponseField name="success" type="boolean">
  Indica se a simulação foi realizada com sucesso
</ResponseField>

<ResponseField name="amount" type="number">
  Valor original solicitado para simulação
</ResponseField>

<ResponseField name="installments" type="array">
  Lista de opções de parcelamento disponíveis
</ResponseField>

### Objeto Installment

Cada opção de parcelamento contém:

<ResponseField name="number" type="number">
  Número de parcelas (1 a 12)
</ResponseField>

<ResponseField name="installmentAmount" type="number">
  Valor de cada parcela em reais
</ResponseField>

<ResponseField name="totalAmount" type="number">
  Valor total a ser pago (com juros)
</ResponseField>

<ResponseField name="interestRate" type="number">
  Taxa de juros aplicada em percentual
</ResponseField>

<ResponseField name="interestAmount" type="number">
  Valor total dos juros em reais
</ResponseField>

## Regras de Parcelamento

<AccordionGroup>
  <Accordion title="Valor Mínimo da Parcela" icon="dollar-sign">
    O valor mínimo permitido por parcela é de **R\$ 5,00**

    * Parcelas inferiores a R\$ 5,00 não serão retornadas na simulação
    * O número máximo de parcelas é calculado automaticamente com base no valor total
    * Exemplo: Um valor de R$ 30,00 permite no máximo 6 parcelas de R$ 5,00 cada
  </Accordion>

  <Accordion title="Quantidade de Parcelas" icon="calculator">
    O parcelamento é limitado entre **1 e 12 parcelas**

    * Mínimo: 1 parcela (pagamento à vista)
    * Máximo: 12 parcelas
    * A quantidade disponível depende do valor total e do valor mínimo por parcela
    * Apenas parcelas válidas são retornadas na resposta da API
  </Accordion>

  <Accordion title="Aplicação de Juros" icon="percent">
    Todos os métodos de pagamento possuem juros aplicados

    * Pagamento à vista (1x): Taxa de juros aplicada
    * Parcelamento (2x a 12x): Taxa de juros progressiva conforme número de parcelas
    * PIX: Taxa de juros aplicada no momento do pagamento
    * As taxas são calculadas e retornadas automaticamente pela API
  </Accordion>

  <Accordion title="Cálculo Automático" icon="calculator-simple">
    A API calcula automaticamente as opções disponíveis

    * Considera o valor total informado
    * Aplica o valor mínimo de R\$ 5,00 por parcela
    * Calcula juros conforme tabela vigente
    * Retorna apenas opções válidas e disponíveis
  </Accordion>
</AccordionGroup>

## Exemplo de Interface

Veja como apresentar as opções de parcelamento ao usuário:

<CodeGroup>
  ```javascript React theme={null}
  import React, { useState, useEffect } from 'react';

  function InstallmentSelector({ amount, onSelect }) {
    const [installments, setInstallments] = useState([]);
    const [selected, setSelected] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
      fetchInstallments();
    }, [amount]);

    const fetchInstallments = async () => {
      try {
        const response = await fetch('/api/installments', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ 
            amount, 
            paymentMethod: 'credit_card' 
          })
        });
        
        const data = await response.json();
        setInstallments(data.installments);
        setSelected(data.installments[0]); // Seleciona 1x por padrão
      } catch (error) {
        console.error('Erro ao buscar parcelas:', error);
      } finally {
        setLoading(false);
      }
    };

    const handleSelect = (option) => {
      setSelected(option);
      onSelect(option);
    };

    if (loading) return <div>Carregando opções...</div>;

    return (
      <div className="installment-selector">
        <h3>Escolha a forma de pagamento</h3>
        
        {installments.map((option) => (
          <div
            key={option.number}
            className={`installment-option ${selected?.number === option.number ? 'selected' : ''}`}
            onClick={() => handleSelect(option)}
          >
            <div className="installment-info">
              <strong>
                {option.number}x de R$ {option.installmentAmount.toFixed(2)}
              </strong>
              <span className="interest">
                Total: R$ {option.totalAmount.toFixed(2)} 
                ({option.interestRate.toFixed(2)}% de juros)
              </span>
            </div>
          </div>
        ))}
      </div>
    );
  }

  export default InstallmentSelector;
  ```

  ```html HTML + JavaScript theme={null}
  <!DOCTYPE html>
  <html>
  <head>
    <style>
      .installment-option {
        padding: 15px;
        margin: 10px 0;
        border: 2px solid #e0e0e0;
        border-radius: 8px;
        cursor: pointer;
        transition: all 0.3s;
      }
      
      .installment-option:hover {
        border-color: #16A34A;
        background-color: #f0fdf4;
      }
      
      .installment-option.selected {
        border-color: #16A34A;
        background-color: #dcfce7;
      }
      
      .badge {
        background-color: #16A34A;
        color: white;
        padding: 2px 8px;
        border-radius: 4px;
        font-size: 12px;
        margin-left: 10px;
      }
      
      .interest {
        color: #666;
        font-size: 14px;
        margin-left: 10px;
      }
    </style>
  </head>
  <body>
    <div id="installments-container"></div>

    <script>
      async function loadInstallments(amount) {
        const response = await fetch('/api/installments', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ 
            amount, 
            paymentMethod: 'credit_card' 
          })
        });
        
        const data = await response.json();
        renderInstallments(data.installments);
      }

      function renderInstallments(installments) {
        const container = document.getElementById('installments-container');
        
        container.innerHTML = '<h3>Escolha a forma de pagamento</h3>';
        
        installments.forEach(option => {
          const div = document.createElement('div');
          div.className = 'installment-option';
          
          const info = `<strong>${option.number}x de R$ ${option.installmentAmount.toFixed(2)}</strong>
               <span class="interest">Total: R$ ${option.totalAmount.toFixed(2)} 
               (${option.interestRate.toFixed(2)}% de juros)</span>`;
          
          div.innerHTML = info;
          div.onclick = () => selectInstallment(option, div);
          container.appendChild(div);
        });
      }

      function selectInstallment(option, element) {
        document.querySelectorAll('.installment-option').forEach(el => {
          el.classList.remove('selected');
        });
        element.classList.add('selected');
        console.log('Selecionado:', option);
      }

      // Carregar ao iniciar
      loadInstallments(1302.86);
    </script>
  </body>
  </html>
  ```
</CodeGroup>

## Boas Práticas

<Steps>
  <Step title="Simule Antes do Checkout">
    Sempre simule as parcelas antes de criar o checkout para mostrar opções atualizadas ao usuário.
  </Step>

  <Step title="Destaque a Melhor Opção">
    Evidencie visualmente a opção com menor taxa de juros ou mais vantajosa para o cliente.
  </Step>

  <Step title="Mostre o Total">
    Sempre exiba o valor total a ser pago, não apenas o valor da parcela.
  </Step>

  <Step title="Seja Transparente">
    Mostre claramente a taxa de juros e o valor dos juros em reais.
  </Step>

  <Step title="Pré-selecione uma Opção">
    Deixe uma opção pré-selecionada (recomendado: 1x ou a opção mais popular).
  </Step>

  <Step title="Cache Inteligente">
    Considere cachear a simulação por alguns minutos para o mesmo valor, evitando chamadas desnecessárias.
  </Step>
</Steps>

## Códigos de Erro

<ResponseField name="400" type="Bad Request">
  Parâmetros inválidos (valor negativo, método de pagamento não suportado, etc.)
</ResponseField>

<ResponseField name="401" type="Unauthorized">
  API Key inválida ou ausente
</ResponseField>

<ResponseField name="429" type="Too Many Requests">
  Limite de requisições excedido
</ResponseField>

<ResponseField name="500" type="Server Error">
  Erro interno do servidor
</ResponseField>

## Exemplo de Erro

```json theme={null}
{
  "success": false,
  "error": "Bad Request",
  "message": "O valor deve ser maior que zero",
  "statusCode": 400
}
```

## Fluxo Recomendado

```mermaid theme={null}
sequenceDiagram
    participant U as Usuário
    participant F as Frontend
    participant API as Uvvipague API

    U->>F: Seleciona débitos
    F->>F: Calcula valor total
    F->>API: POST /installments (amount)
    API-->>F: Retorna opções de parcelamento
    F->>U: Exibe opções (1x a 12x)
    U->>F: Seleciona número de parcelas
    F->>API: POST /checkout (com débitos)
    API-->>F: Retorna checkout ID
    F->>API: POST /payment (checkout + parcelas)
    API-->>F: Confirma pagamento
    F->>U: Exibe confirmação
```

## Integração com Checkout

Após o usuário selecionar a opção de parcelamento, use o número de parcelas no pagamento:

```javascript theme={null}
// 1. Simular parcelas
const simulacao = await simularParcelas(1302.86);

// 2. Usuário seleciona 3 parcelas
const parcelasSelecionadas = 3;

// 3. Criar checkout
const checkout = await criarCheckout({ debts: [...] });

// 4. Efetuar pagamento com as parcelas selecionadas
const pagamento = await efetuarPagamento({
  checkoutId: checkout.checkoutId,
  paymentMethod: 'credit_card',
  cardToken: token,
  installments: parcelasSelecionadas  // Usa o número selecionado
});
```

## Próximos Passos

<CardGroup cols={2}>
  <Card title="Fluxo Completo" icon="diagram-project" href="/fluxo-completo">
    Veja como integrar a simulação no fluxo completo de pagamento
  </Card>

  <Card title="Efetuar Pagamento" icon="credit-card" href="/fluxo-completo#24-efetuar-pagamento">
    Aprenda como processar o pagamento com as parcelas selecionadas
  </Card>

  <Card title="Autenticação" icon="key" href="/autenticacao">
    Configure sua API Key para começar
  </Card>

  <Card title="Tratamento de Erros" icon="triangle-exclamation" href="/tratamento-erros">
    Aprenda a lidar com erros
  </Card>
</CardGroup>
