Skip to main content
A Comissão (comm_…) é o lançamento financeiro individual gerado por cada cobrança bem-sucedida de uma Conversão ativa. O modelo da Repass é por cobrança, não por conversão: uma conversão recorrente gera uma comissão por ciclo de faturamento, cada uma com seu próprio cálculo auditável. Refunds e chargebacks geram comissões negativas (clawbacks) de primeira classe. Toda aritmética é inteira: valores em centavos, percentuais em basis points (bps, onde 1% = 100 bps). Cada comissão carrega um campo calculation aberto que reconstrói “por que esse valor?”. É a fonte de auditoria do dinheiro.
Não há rota para criar comissões standard. Elas são geradas automaticamente quando uma cobrança é processada. A API expõe leitura, void, aprovação antecipada e criação de bônus avulso. Veja a aba Referência da API para os endpoints detalhados.

Como uma comissão é calculada

Cada cobrança bem-sucedida de uma conversão ativa dispara o cálculo. O caminho é determinístico.
1

Resolução da regra (snapshot)

A conversão já carrega um RuleSnapshot, uma cópia congelada da regra de comissão resolvida no momento da conversão. O cálculo usa o snapshot, nunca a regra atual. Mudar a regra do programa depois não altera comissões já calculadas; para retroagir, use Reprocessamento.
2

Cobertura de recorrência

A política de recorrência decide se o ciclo atual é coberto e qual taxa aplicar (one_time, lifetime, months:N, decreasing). Fora da cobertura, nenhuma comissão é criada (skipped: recurrence_exhausted).
3

Base de cálculo

gross (default) usa o valor cobrado; net_of_gateway_fees subtrai a taxa do gateway antes de aplicar o percentual. A base vem do programa (commissionBasis).
4

Aplicação da taxa + arredondamento

Percentual ou valor fixo aplicado sobre a base, com arredondamento half-up no centavo, sobre o produto inteiro, nunca em float.
5

Split multi-touch (se aplicável)

Quando a atribuição tem múltiplos afiliados winners, o valor é dividido proporcionalmente ao peso (weightBps), com a sobra de arredondamento creditada ao maior peso.
6

Hold

A comissão standard nasce pending com holdUntil = occurredAt + holdDays × 24h.

Base de cálculo

A base depende de commissionBasis no programa: Exemplo com net_of_gateway_fees: cobrança de 9900 centavos, taxa de gateway 900, regra de 2000 bps (20%) → base 9000 → comissão 1800.

Arredondamento half-up

O percentual é aplicado em centavos com half-up no centavo, calculado sobre o produto inteiro (amountCents × bps), nunca em float:
A API de criação de regras recebe e devolve percentual decimal (0.00 a 100.00, passo 0.01), mas o armazenamento e todo o cálculo são em bps (percentToBps = round(percentage × 100)). Uma regra de 20.00% vira 2000 bps internamente.

Split multi-touch

Em atribuição com vários afiliados winners (modelos linear, time_decay, position_based), cada parte arredonda para baixo (floor(total × weightBps / 10000)) e a sobra inteira vai ao winner de maior peso (empate → o winner primário/cupom). A sobra creditada é registrada em calculation.splitRemainderCents. Exemplo: total 1001 com pesos 7000 / 3000 bps → 701 (700 + 1 de sobra) e 300.
Uma cobrança gera no máximo uma comissão standard por afiliado. Quando o multi-touch atribui mais de um clique ao mesmo afiliado, os pesos são agregados (somados) antes do split. Veja Atribuição para os modelos e pesos. Comissão de valor 0 é criada (não suprimida) para preservar a numeração de billingCycle e a auditoria.

O campo calculation

Reconstrói o valor. Campos principais:
string
gross ou net_of_gateway_fees.
integer
Valor cobrado pelo gateway.
integer
Taxa do gateway (presente apenas em base net_of_gateway_fees).
integer
Base efetiva sobre a qual a taxa foi aplicada.
integer
Peso do afiliado na atribuição (10000 = 100%). Em bônus, sempre 10000.
object
{ ruleId, version, precedence, type }: a regra que originou o valor. Ausente em bonus e clawback, que não derivam de regra.
integer
Taxa efetivamente aplicada (um ou outro, conforme o tipo da regra).
string
Política de recorrência usada no ciclo.
object
{ minCount, approvedConversionsCount }: presente em regras tiered.
integer
Sobra de arredondamento creditada (apenas em split multi-touch).
object
{ refundedAmountCents, chargedAmountCents, originalCommissionAmountCents, chargeback }: presente em clawbacks.

Tipos de comissão

Ciclo de vida

A comissão tem quatro estados (status) mais um flag ortogonal underReview:
  • pending: calculada, em carência (holdUntil no futuro). Só comissões standard nascem assim.
  • approved: liberada para pagamento. Chega aqui pelo job de hold, por aprovação manual antecipada, ou já nasce assim (bonus, clawback).
  • paid: quitada por um Payout concluído (transição feita pelo módulo de payouts).
  • voided: anulada (terminal).
O flag underReview é independente do status: uma comissão approved mas underReview = true está congelada (não entra em payout nem é projetada no saldo) por causa de uma revisão de ban.

Hold e carência

Toda comissão standard nasce pending com uma janela de carência. O hold conta a partir de occurredAt da cobrança (não da data de registro):
holdDays é configurável por programa (default 30, faixa 0 a 90). Ao fim do hold, um job promove pending → approved em lotes, desde que:
  • a comissão esteja pending e underReview = false;
  • a conversão de origem esteja approved (fraude resolvida);
  • o afiliado não esteja banned.
bonus e clawback nunca entram no job: nascem approved.

Aprovação antecipada e revisão de ban

POST /commissions/:commissionId/approve cobre dois cenários:
  • Aprovação antecipada de uma comissão pending: aplica as mesmas guardas do job, exceto a de holdUntil. Emite commission.approved com early: true.
  • Limpeza de revisão: sobre uma comissão approved + underReview, apenas limpa o flag (underReview = false) e emite commission.review_cleared, sem mudar o status, devolvendo a comissão ao fluxo de payout.

Void

POST /commissions/:commissionId/void anula manualmente uma comissão. Só comissões pending ou approved sem payoutId podem ser anuladas; paid/voided ou já atribuídas a um payout são rejeitadas com 409 conflict. Exige uma razão (reason, 1 a 500 caracteres).
Cancelar uma assinatura enquanto há comissões pending voida essas comissões com razão subscription_canceled_in_hold, a menos que a organização desligue void_on_cancel_in_hold (default ON). Banir o afiliado voida suas pending e congela (underReview) suas approved não pagas.

Clawback (refund e chargeback)

Refunds são tratados como entidade de primeira classe e auditável, não como ajuste opaco. O comportamento depende de o refund ser total ou parcial e de a comissão original já ter sido paga. O clawback é uma comissão type: clawback, status: approved (débito imediato, sem hold), com amountCents negativo e originalCommissionId apontando a comissão revertida. O refund parcial sempre vira clawback, mesmo que a comissão original não esteja paga. Valor do clawback parcial (arredondado para baixo):
Para o passo a passo completo de integração de refunds via API, veja o guia Refund e clawback.

Saldo do afiliado e projeção não-negativa

GET /affiliates/:affiliateId/balance retorna o saldo agregado por bucket e a projeção do próximo payout: A projeção do próximo payout é max(0, approvedCents + clawbackCents): um débito que excede o crédito não vira cobrança ao afiliado: rola para payouts futuros.

Bônus

POST /commissions/bonus cria uma comissão bonus avulsa, fora do ciclo normal: sem conversão, sem ciclo de faturamento e sem hold. Nasce approved, com currency igual à moeda do programa do afiliado e calculation.weightBps = 10000.
Bônus para um afiliado banned ou rejected é rejeitado com 409 conflict.

Listagem e idempotência

GET /commissions lista comissões com paginação por cursor (limit 1 a 100, default 25; starting_after / ending_before) e filtros: affiliate_id, conversion_id, status, type (clawbacks são listados via type=clawback), billing_cycle, payout_id, occurred_after, occurred_before. A resposta é { data, hasMore }. O detalhe (GET /commissions/:commissionId) já vem com o calculation embutido: não há expand[] neste módulo.
A geração de comissões é idempotente: cobranças e refunds já processados para um mesmo sourceEventId retornam o resultado existente (replayed: true) sem duplicar comissões. Reenviar o mesmo evento de cobrança ou refund é seguro. Todas as rotas POST aceitam o header Idempotency-Key (veja Idempotência); replays retornam a resposta armazenada com Idempotent-Replay: true.

Eventos de domínio

Cada mudança de estado emite um evento, útil para assinar via webhook. Os principais deste módulo: Consulte o catálogo de eventos e o event store para os payloads completos.

Erros comuns

Veja Erros para o formato completo da resposta de erro.

Próximos passos

Programas e regras

Como configurar regras versionadas (percentage, fixed, tiered) e recorrência.

Refund e clawback

Guia prático de como registrar refunds e chargebacks via API.

Payouts

Como comissões aprovadas viram pagamentos, com netting de clawbacks.

Reprocessamento

Aplicar uma nova versão de regra retroativamente, gerando ajustes auditáveis.