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

# Ganhos com Juro de Parcelamento

> Quanto de juro adicional de parcelamento foi cobrado do comprador num período e quanto disso ficou com você depois do rateio por comissão. São dois números diferentes.

#### Escopo

```bash theme={null}
    read payments
```

## O que é este endpoint?

O [juro adicional](/api-reference/installment-interest/retrieve) é um percentual configurado. Este endpoint responde o que ele **virou em dinheiro** num período, e responde com **dois números que não são o mesmo**:

| Campo     | Responde                                                            | Bate com                                                 |
| --------- | ------------------------------------------------------------------- | -------------------------------------------------------- |
| `charged` | Quanto de juro **o comprador pagou** nos seus pedidos.              | O extrato da adquirente, o valor da fatura do comprador. |
| `earned`  | Quanto desse juro **ficou com você** depois do rateio por comissão. | O que entrou no seu saldo.                               |

Em produto sem coprodutor nem afiliado, os dois são iguais. Assim que existe alguém dividindo receita, eles se separam — e é aí que mora o erro que este endpoint existe para evitar.

<Info>
  A operação lê **sempre a conta dona do token**. Não existe parâmetro de produtor.
</Info>

***

## O rateio, em um exemplo

<Warning>
  **O juro não é todo seu. Ele é dividido entre os comissionados do pedido, exatamente como o valor da venda.**

  Somar o juro dos pedidos e chamar de ganho — o cálculo "óbvio" — **superestima** o ganho de quem divide receita. O número é plausível, vem sozinho, e ninguém percebe até conferir com o extrato.
</Warning>

Uma venda de **R$ 1.000,00** parcelada em 12x com **10%** de juro adicional gera **R$ 100,00** de juro cobrado do comprador. O que acontece com esses R\$ 100,00 depende de quem participa da venda:

| Cenário                       | `charged`  | `earned`   |
| ----------------------------- | ---------- | ---------- |
| Você sozinho                  | `"100.00"` | `"100.00"` |
| Coprodutor com 30%            | `"100.00"` | `"70.00"`  |
| Afiliado com 20%              | `"100.00"` | `"80.00"`  |
| Afiliado 20% + coprodutor 30% | `"100.00"` | `"56.00"`  |

O `charged` é o mesmo nos quatro casos porque ele é o juro **do pedido**, não a sua fatia dele. O que muda é o `earned`.

<Tip>
  A última linha não é `50.00` porque as comissões **não se somam sobre o mesmo valor**: a do coprodutor incide sobre o que sobra depois da do afiliado. Com afiliado a 20%, o coprodutor de 30% leva 30% dos 80% restantes — 24% — e sobram 56% para você. O juro segue exatamente essa divisão.
</Tip>

<Note>
  **`charged` é do pedido, e por isso ele aparece igual para todo mundo que participa da venda.**

  No cenário do coprodutor a 30%, se ele consultar este endpoint com o token dele, vê `charged: "100.00"` e `earned: "30.00"` — o mesmo `charged` que você, porque é o mesmo pedido. **Somar o `charged` de vários parceiros conta o mesmo juro várias vezes.** Quem soma entre parceiros deve somar `earned`, nunca `charged`.
</Note>

### Por que a Cakto publica os dois

Publicar só `earned` faria você conferir com o extrato da adquirente e concluir que a API está errada — o extrato mostra o valor cobrado, que é o `charged`. Publicar só `charged` faria você contar como ganho um dinheiro que foi para outra pessoa.

Com os dois lado a lado, o rateio fica visível em vez de invisível, e `charged - earned` é exatamente o que foi para os seus parceiros no período.

<Accordion title="Um caso raro em que earned aparece acima de charged" icon="triangle-exclamation">
  Em pedidos antigos, criados por um caminho de comissionamento legado com afiliado, o rateio gravado pode somar mais de 100% do juro do pedido. Nesses pedidos o `earned` sai **acima** do `charged`.

  É defeito de gravação daquele histórico, não do cálculo desta consulta — o número devolvido é o que está registrado. Se você encontrar isso em um período recente, fale com o [suporte](mailto:infoprodutores@cakto.com.br).
</Accordion>

***

## A janela de consulta

<AccordionGroup>
  <Accordion title="Sem parâmetro, a resposta é dos últimos 30 dias" icon="calendar-days">
    Não existe "consultar tudo". Omitindo `startDate` e `endDate`, a janela é dos **últimos 30 dias** terminando agora.

    Os campos `startDate` e `endDate` **da resposta** ecoam a janela que foi realmente aplicada — não a que você pediu. Confira esse eco antes de guardar o número, principalmente se você não mandou nenhuma das duas datas.
  </Accordion>

  <Accordion title="O período não pode passar de 92 dias" icon="ruler-horizontal">
    Acima disso a resposta é `400`, com o tamanho da janela no `detail`. Não adianta repetir a mesma chamada: quebre em blocos menores e some os `earned` (nunca os `charged`, veja acima).

    O teto existe para que o custo da consulta escale com o período pedido, e não com o tamanho do seu histórico.
  </Accordion>

  <Accordion title="As datas são inclusivas, no fuso de São Paulo" icon="clock">
    `startDate` conta a partir de `00:00` do dia informado; `endDate`, até `23:59:59` do dia informado. Ambas em `America/Sao_Paulo`. O formato é `YYYY-MM-DD`.

    O corte é pela **data de criação do pedido**.
  </Accordion>

  <Accordion title="Uma consulta responde sobre uma moeda só" icon="coins">
    `currency` tem padrão `BRL`. Somar moedas diferentes produziria um número que não existe, então não há resposta multimoeda: para vendas em outra moeda, consulte de novo com `currency` diferente.
  </Accordion>
</AccordionGroup>

***

## O que entra na conta

<Note>
  **Só pedidos pagos.** Pedido recusado, expirado ou aguardando pagamento não entra — nem em `charged`, nem em `earned`, nem na contagem `orders`.
</Note>

<Warning>
  **O total de um período passado pode mudar.**

  Não existe registro de reversão: um pedido reembolsado, com chargeback ou em disputa simplesmente **sai** do total do período em que foi vendido. O agosto que você consultou em setembro pode não ser o mesmo agosto se consultar em outubro.

  Se você armazenar o valor, trate-o como um retrato daquele momento e **reconcilie**, em vez de tratá-lo como fechado.
</Warning>

***

## Resposta

<Cards>
  <Card title="Totais da janela">
    * `currency` — moeda dos pedidos considerados
    * `startDate` / `endDate` — a janela **efetivamente aplicada**
    * `charged` — juro cobrado do comprador, string decimal
    * `earned` — a sua fatia depois do rateio, string decimal
    * `orders` — quantidade de pedidos pagos com juro adicional
  </Card>

  <Card title="byInstallments[] e byPaymentMethod[]">
    O mesmo total, recortado por número de parcelas e por método de pagamento. Cada item traz `charged`, `earned` e `orders`.

    Os recortes trazem **só o que teve movimento** na janela — não são tabelas de tamanho fixo.
  </Card>
</Cards>

<Note>
  **Dinheiro vem como string decimal** (`"1000.00"`), não como número. É o padrão do contrato para valores monetários: converta para o tipo decimal da sua linguagem antes de somar, em vez de acumular em ponto flutuante.

  Percentuais e contagens continuam sendo número — `orders` é `integer`, e `interestPercentage`, no endpoint de [configuração](/api-reference/installment-interest/retrieve), é `number`.
</Note>

### Exemplo de resposta

```json theme={null}
{
  "currency": "BRL",
  "startDate": "2026-08-01T00:00:00-03:00",
  "endDate": "2026-08-31T23:59:59.999999-03:00",
  "charged": "1000.00",
  "earned": "700.00",
  "orders": 42,
  "byInstallments": [
    { "installments": 6,  "charged": "400.00", "earned": "280.00", "orders": 20 },
    { "installments": 12, "charged": "600.00", "earned": "420.00", "orders": 22 }
  ],
  "byPaymentMethod": [
    { "paymentMethod": "credit_card", "charged": "900.00", "earned": "630.00", "orders": 38 },
    { "paymentMethod": "threeDs",     "charged": "100.00", "earned": "70.00",  "orders": 4 }
  ]
}
```

Nesse mês o comprador pagou R$ 1.000,00 de juro adicional; R$ 700,00 ficaram com esta conta e R\$ 300,00 foram para coprodutores e afiliados.

<AccordionGroup>
  <Accordion title="byInstallments reflete as vendas, não a sua tabela" icon="chart-column">
    Ele traz o número de parcelas dos **pedidos que existiram** na janela. Faixa que você configurou mas ninguém usou não aparece; e um pedido antigo com um número de parcelas fora de 2..12 aparece como está.

    Para saber o que está configurado hoje, use [Consultar Juro Adicional](/api-reference/installment-interest/retrieve) — esta consulta é sobre o passado.
  </Accordion>

  <Accordion title="byPaymentMethod só traz métodos que parcelam" icon="credit-card">
    `credit_card`, `threeDs`, `googlepay` e `applepay` — o mesmo vocabulário de [`POST /public_api/payments/`](/api-reference/payments/create-pix). Pix e boleto não parcelam, então não geram juro adicional e nunca aparecem aqui.
  </Accordion>

  <Accordion title="A soma dos recortes bate com o total" icon="equals">
    Somando `charged` de todos os itens de `byInstallments` você chega ao `charged` do topo, e o mesmo vale para `byPaymentMethod` e para `earned`.

    A contagem `orders` é a exceção: um pedido conta uma vez em cada recorte, mas o `orders` do topo conta pedidos distintos — os números coincidem porque um pedido tem um número de parcelas e um método só.
  </Accordion>
</AccordionGroup>

***

## Respostas de erro

| Código | Quando ocorre                                                                         | Corpo de exemplo                                                                                |
| ------ | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `400`  | Janela acima de 92 dias, janela invertida, data malformada ou moeda desconhecida.     | `{ "detail": "Janela de 120 dias excede o máximo de 92 dias. Consulte por períodos menores." }` |
| `401`  | Token ausente, inválido ou expirado.                                                  | `{ "detail": "As credenciais de autenticação não foram fornecidas." }`                          |
| `403`  | Chave de API sem o escopo `payments`, ou sem `read`.                                  | `{ "detail": "Você não tem permissão para executar esta ação." }`                               |
| `429`  | Limite de requisições excedido. Veja [Limites de Requisição](/conceitos/rate-limits). | `{ "detail": "Request was throttled. Expected available in 42 seconds." }`                      |

<Note>
  O `400` de janela vem em `detail`; o de formato de data ou moeda vem no nome do parâmetro (`startDate`, `endDate`, `currency`), como lista de mensagens. Em nenhum dos casos repetir a mesma chamada resolve — corrija o parâmetro.
</Note>

***

## Exemplo de requisição

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET 'https://api.cakto.com.br/public_api/installment-interest/earnings/?startDate=2026-08-01&endDate=2026-08-31' \
    -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsIn...'
  ```

  ```python Python theme={null}
  from datetime import date, timedelta
  from decimal import Decimal

  import requests

  BASE = "https://api.cakto.com.br/public_api/installment-interest/earnings/"
  HEADERS = {"Authorization": "Bearer eyJhbGciOiJIUzI1NiIsIn..."}
  MAX_DIAS = 92


  def ganhos(inicio: date, fim: date) -> dict:
      resposta = requests.get(
          BASE,
          headers=HEADERS,
          params={"startDate": inicio.isoformat(), "endDate": fim.isoformat()},
          timeout=30,
      )
      resposta.raise_for_status()
      return resposta.json()


  # Um ano quebrado em blocos de 92 dias -- a janela tem teto.
  inicio, fim = date(2026, 1, 1), date(2026, 12, 31)
  cobrado = ganho = Decimal("0.00")

  atual = inicio
  while atual <= fim:
      bloco_fim = min(atual + timedelta(days=MAX_DIAS - 1), fim)
      dados = ganhos(atual, bloco_fim)
      cobrado += Decimal(dados["charged"])
      ganho += Decimal(dados["earned"])
      atual = bloco_fim + timedelta(days=1)

  print(f"Comprador pagou de juro: R$ {cobrado}")
  print(f"Ficou com você:          R$ {ganho}")
  print(f"Foi para parceiros:      R$ {cobrado - ganho}")
  ```

  ```javascript Node.js theme={null}
  const BASE = "https://api.cakto.com.br/public_api/installment-interest/earnings/";
  const headers = { Authorization: "Bearer eyJhbGciOiJIUzI1NiIsIn..." };

  const url = new URL(BASE);
  url.searchParams.set("startDate", "2026-08-01");
  url.searchParams.set("endDate", "2026-08-31");

  const resposta = await fetch(url, { headers });
  if (!resposta.ok) throw new Error(`Cakto API error ${resposta.status}`);

  const dados = await resposta.json();

  // A janela da resposta é a que valeu, não necessariamente a que foi pedida.
  console.log(`Período aplicado: ${dados.startDate} a ${dados.endDate}`);
  console.log(`Comprador pagou de juro: R$ ${dados.charged}`);
  console.log(`Ficou com você:          R$ ${dados.earned}`);

  for (const linha of dados.byInstallments) {
    console.log(`${linha.installments}x -> R$ ${linha.earned} em ${linha.orders} pedidos`);
  }
  ```
</CodeGroup>

***

## Boas práticas

* **Use `earned` para "quanto eu ganhei" e `charged` para conferir com o extrato.** Trocar os dois é o erro clássico aqui, e ele só aparece na conciliação.
* **Nunca some `charged` entre parceiros.** O mesmo pedido aparece com o mesmo `charged` para cada comissionado; somar conta o juro várias vezes. Entre parceiros, some `earned`.
* **Leia o `startDate`/`endDate` da resposta** antes de rotular o número, sobretudo quando você não mandou as datas.
* **Quebre períodos longos em blocos de até 92 dias** em vez de tentar de novo com o intervalo inteiro.
* **Reconcilie o que você armazenar.** Reembolso e chargeback retiram pedidos de um período já consultado.
* **Compare com a tabela configurada.** Se o `earned` não subiu depois de você aumentar o percentual em [Configurar Juro Adicional](/api-reference/installment-interest/update), provavelmente a conversão no parcelado caiu — `byInstallments` mostra em qual faixa.


## OpenAPI

````yaml GET /public_api/installment-interest/earnings/
openapi: 3.0.3
info:
  title: Cakto API
  version: 1.0.0
  description: Documentação da API pública do Cakto.
servers:
  - url: https://api.cakto.com.br
    description: Cakto API
security: []
paths:
  /public_api/installment-interest/earnings/:
    get:
      tags:
        - installment-interest
      description: >-
        Quanto você cobrou e quanto ganhou de juro adicional num período.


        São dois números, e eles não são o mesmo: `charged` é o juro que o
        comprador pagou

        nos seus pedidos, `earned` é a fatia que ficou com você depois do rateio
        por

        comissão. Num produto com coprodutor a 30%, `earned` é 70% de `charged`.
        Somar o

        juro dos pedidos e chamar de ganho — o cálculo "óbvio" — superestima o
        ganho de quem

        divide receita, e a diferença só aparece na conciliação com o extrato.


        Só entram pedidos **pagos**. Como não existe registro de reversão, o
        total de um

        período passado muda se um pedido daquele período for reembolsado ou
        sofrer

        chargeback depois: se você armazenar o valor, reconcilie em vez de
        tratá-lo como

        fechado.


        A janela é obrigatória por consequência: sem `startDate`/`endDate` a
        consulta

        responde os últimos 30 dias, e o período pedido não pode passar de 92
        dias. Os campos

        `startDate` e `endDate` da resposta ecoam a janela que foi realmente
        aplicada.
      operationId: installment_interest_earnings_retrieve
      parameters:
        - in: query
          name: currency
          schema:
            enum:
              - BRL
              - EUR
              - MXN
              - PEN
              - USD
              - CLP
              - COP
              - ARS
              - BOB
              - UYU
            type: string
            default: BRL
            minLength: 1
          description: >-
            Moeda dos pedidos considerados. Uma consulta responde sobre uma
            moeda só — somar moedas diferentes produziria um número que não
            existe.


            * `BRL` - Real

            * `EUR` - Euro

            * `MXN` - Peso Mexicano

            * `PEN` - Sol Peruano

            * `USD` - Dólar

            * `CLP` - Peso Chileno

            * `COP` - Peso Colombiano

            * `ARS` - Peso Argentino

            * `BOB` - Boliviano

            * `UYU` - Peso Uruguayo
        - in: query
          name: endDate
          schema:
            type: string
            format: date
          description: >-
            Fim do período (`YYYY-MM-DD`), inclusive até 23:59:59. Omitido, vale
            agora. O período entre `startDate` e `endDate` não pode passar de 92
            dias.
        - in: query
          name: startDate
          schema:
            type: string
            format: date
          description: >-
            Início do período (`YYYY-MM-DD`), inclusive, a partir de 00:00 no
            fuso de São Paulo. Omitido, a janela é dos últimos 30 dias.
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InstallmentInterestEarnings'
              examples:
                Sucesso:
                  value:
                    currency: BRL
                    startDate: '2026-08-01T00:00:00-03:00'
                    endDate: '2026-08-31T23:59:59.999999-03:00'
                    charged: '1000.00'
                    earned: '700.00'
                    orders: 42
                    byInstallments:
                      - installments: 6
                        charged: '400.00'
                        earned: '280.00'
                        orders: 20
                      - installments: 12
                        charged: '600.00'
                        earned: '420.00'
                        orders: 22
                    byPaymentMethod:
                      - paymentMethod: credit_card
                        charged: '900.00'
                        earned: '630.00'
                        orders: 38
                      - paymentMethod: threeDs
                        charged: '100.00'
                        earned: '70.00'
                        orders: 4
          description: >-
            Juro adicional cobrado e ganho na janela. `charged` é o que o
            comprador pagou; `earned` é a fatia que ficou com a conta
            autenticada depois do rateio por comissão. Só pedidos pagos entram,
            e o total de um período passado pode mudar se houver reembolso ou
            chargeback depois.
        '400':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
                  startDate:
                    type: array
                    items:
                      type: string
                  endDate:
                    type: array
                    items:
                      type: string
                  currency:
                    type: array
                    items:
                      type: string
              examples:
                JanelaAcimaDoTeto:
                  value:
                    detail: >-
                      Janela de 120 dias excede o máximo de 92 dias. Consulte
                      por períodos menores.
                JanelaInvertida:
                  value:
                    detail: Início da janela é posterior ao fim.
                DataInvalida:
                  value:
                    startDate:
                      - >-
                        Formato inválido para data. Use um dos formatos ao
                        invés: YYYY-MM-DD.
          description: >-
            Janela inválida ou parâmetro malformado. O período pedido não pode
            passar de 92 dias — consulte por blocos menores em vez de tentar de
            novo com o mesmo intervalo.
        '401':
          description: Request não autenticado devido à ausência ou invalidez do token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthenticatedError'
              examples:
                Token ausente ou inválido:
                  $ref: '#/components/examples/UnauthenticatedErrorExample'
        '403':
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: string
              examples:
                EscopoInsuficiente:
                  value:
                    detail: Você não tem permissão para executar esta ação.
          description: >-
            Chave de API sem o escopo `payments`, ou sem `write` na operação de
            escrita. Leitura exige `payments` e `read`; escrita exige `payments`
            e `write`.
      security:
        - OAuth Token: []
components:
  schemas:
    InstallmentInterestEarnings:
      type: object
      properties:
        currency:
          type: string
          description: Moeda dos pedidos considerados.
        startDate:
          type: string
          format: date-time
          description: >-
            Início da janela **efetivamente aplicada**, não a que foi pedida:
            sem `startDate` a consulta responde os últimos 30 dias, e este campo
            é onde isso fica visível.
        endDate:
          type: string
          format: date-time
          description: Fim da janela efetivamente aplicada.
        charged:
          type: string
          format: decimal
          example: '2.49'
          description: >-
            Juro adicional **cobrado do comprador** nos pedidos pagos da janela
            em que você é comissionado, como string decimal (`"1000.00"`). É o
            número que bate com o extrato da adquirente — e **não** é o seu
            ganho quando o produto tem coprodutor ou afiliado.
        earned:
          type: string
          format: decimal
          example: '2.49'
          description: >-
            A fatia do juro que **ficou com você** depois do rateio por
            comissão, como string decimal. Em produto sem coprodutor nem
            afiliado é igual a `charged`; com coprodutor a 30%, é 70% dele. Este
            é o número de "quanto eu ganhei com juro". Em pedidos antigos de um
            caminho legado com afiliado, o rateio gravado pode passar de 100% e
            `earned` sair acima de `charged`.
        orders:
          type: integer
          description: Quantidade de pedidos pagos com juro adicional na janela.
        byInstallments:
          type: array
          items:
            $ref: '#/components/schemas/InstallmentInterestEarningsByInstallments'
          description: O mesmo total, recortado por número de parcelas do pedido.
        byPaymentMethod:
          type: array
          items:
            $ref: '#/components/schemas/InstallmentInterestEarningsByPaymentMethod'
          description: O mesmo total, recortado por método de pagamento do pedido.
      required:
        - byInstallments
        - byPaymentMethod
        - charged
        - currency
        - earned
        - endDate
        - orders
        - startDate
    UnauthenticatedError:
      type: object
      properties:
        detail:
          type: string
    InstallmentInterestEarningsByInstallments:
      type: object
      properties:
        installments:
          type: integer
          description: >-
            Número de parcelas do pedido. Reflete o que aconteceu nas vendas,
            então pode trazer faixas fora de 2..12 se houver pedido antigo
            assim.
        charged:
          type: string
          format: decimal
          example: '2.49'
          description: Juro cobrado do comprador nesses pedidos, como string decimal.
        earned:
          type: string
          format: decimal
          example: '2.49'
          description: A fatia que ficou com você nesses pedidos, como string decimal.
        orders:
          type: integer
          description: Quantidade de pedidos no recorte.
      required:
        - charged
        - earned
        - installments
        - orders
    InstallmentInterestEarningsByPaymentMethod:
      type: object
      properties:
        paymentMethod:
          type: string
          description: >-
            Método de pagamento do pedido, no mesmo vocabulário de `POST
            /public_api/payments/`. Só métodos com parcelamento aparecem:
            `credit_card`, `threeDs`, `googlepay` e `applepay`.
        charged:
          type: string
          format: decimal
          example: '2.49'
          description: Juro cobrado do comprador nesses pedidos, como string decimal.
        earned:
          type: string
          format: decimal
          example: '2.49'
          description: A fatia que ficou com você nesses pedidos, como string decimal.
        orders:
          type: integer
          description: Quantidade de pedidos no recorte.
      required:
        - charged
        - earned
        - orders
        - paymentMethod
  examples:
    UnauthenticatedErrorExample:
      summary: Token ausente ou inválido
      description: Token ausente ou inválido
      value:
        detail: As credenciais de autenticação não foram fornecidas.
  securitySchemes:
    OAuth Token:
      type: http
      scheme: bearer
      in: header
      name: Authorization
      description: >-
        Token de autenticação do tipo `Bearer {access_token}`, onde
        `{access_token}` é o token obtido no fluxo de
        [autenticação](/authentication).

````