Skip to main content
Uma Conversão é o fato de negócio “um cliente atribuível executou uma ação comissionável”: ela é o vínculo auditável entre cliente e afiliado que justifica o pagamento de Comissões. A Conversão não é o objeto que recebe dinheiro: o dinheiro flui pelas Comissões ao longo das cobranças (1 Conversão → N Comissões). A Conversão guarda a prova de por que aquele afiliado merece comissão sobre aquele cliente. Ao registrar uma Conversão via API server-to-server, a Repass executa de forma síncrona todo o pipeline de decisão: matching de identidade, atribuição ao clique/cupom vencedor, resolução da regra de comissão, scoring antifraude e geração da Comissão do primeiro ciclo. Cada decisão é congelada em snapshots imutáveis dentro da própria Conversão e nos eventos que ela emite, de modo que o histórico possa ser reconstruído integralmente a partir do histórico de eventos.
IDs de Conversão têm o prefixo conv_ seguido de um ULID (ex.: conv_01J9Z3K8...). Valores monetários são sempre inteiros em centavos; pesos de atribuição em basis points (10000 = 100%). Veja IDs e recursos.

Tipos de conversão

O campo type classifica a ação comissionável:

Fontes de conversão

O campo source registra a origem do registro:
  • api: Conversão registrada server-to-server via POST /conversions. É o caminho recomendado para integrações. Veja o guia Conversões server-to-server.
  • manual: Registro feito por um operador via POST /conversions/manual, com afiliado explícito e justificativa obrigatória (1 a 1000 caracteres). Não roda matching de identidade.
  • webhook: Conversão derivada da ingestão de webhooks de gateway de pagamento (como o Stripe). Alimenta o mesmo pipeline com source: "webhook". Veja Ingestão.

Ingestão e deduplicação

Idempotência por sourceEventId

Todo registro de Conversão exige um sourceEventId, uma chave de idempotência permanente por organização (não tem TTL). Reentregar o mesmo sourceEventId retorna a Conversão existente com replayed: true, sem criar uma nova nem reemitir eventos.
A idempotência de negócio por sourceEventId é independente da idempotência de transporte HTTP por Idempotency-Key. As duas convivem por desenho: o Idempotency-Key curto-circuita reentregas idênticas do mesmo cliente HTTP; o sourceEventId garante que o mesmo evento de negócio nunca crie duas Conversões, qualquer que seja o Idempotency-Key.

Deduplicação de cliente ativo

Um cliente que já possui uma Conversão ativa (pending ou approved) no mesmo Programa não gera nova atribuição: cobranças subsequentes pertencem à Conversão original. A resposta retorna a Conversão original com deduplicated: true. A exceção é type: upgrade: em vez de deduplicar, cria-se uma Conversão filha vinculada via parentConversionId, herdando o afiliado da original (sem rodar matching de novo).

Matching e atribuição

O matching vincula a Conversão a um clique através de uma ordem determinística de fallthrough. O primeiro identificador que produzir candidatos válidos vence; o método vencedor é gravado em matchMethod:
1

clickId explícito

click_id: clique informado diretamente pela integração S2S.
2

visitorId

visitor_id: cookie de visitante.
3

emailHash (cross-device)

email_hash: SHA-256 do e-mail do cliente em minúsculas. Derivado de customer.email quando o hash não é enviado.
4

fingerprint

fingerprint: fingerprint probabilístico.
Um clique só é candidato se pertence ao mesmo Programa, não é bot, ainda não expirou e ocorreu antes da Conversão. Candidatos cujo afiliado está banned ou rejected são descartados. Se nenhum identificador casa e não há cupom, nada é persistido: a resposta retorna { attributed: false, conversion: null } e nenhum evento é emitido. A escolha do vencedor entre os candidatos segue o modelo de atribuição do Programa (last_click, first_click, linear, time_decay, position_based) e a política de conflito cupom × clique. Toda a decisão (candidatos avaliados, modelo, janela, vencedores e pesos) é congelada em attributionSnapshot. Os detalhes dos modelos e do conflito de cupom estão em Atribuição.
O attributionSnapshot é a trilha auditável da decisão de atribuição: ele lista todos os cliques considerados (candidates[]) e os vencedores com seus pesos em basis points (winners[]). Use-o para responder “por que esse afiliado foi escolhido?”.

Resolução de regra e comissão

Quando há vencedor, a Repass resolve a regra de comissão por precedência: regra custom do afiliado → regra do tier → regra padrão do Programa. A regra vigente é congelada em ruleSnapshot e a Comissão do primeiro ciclo é gerada junto com a Conversão. Detalhes em Programas e regras e Comissões. A geração de comissão pode ser pulada; nesse caso ruleSnapshot fica null e commissionSkippedReason registra o motivo:

Scoring de fraude

Toda Conversão recebe um score de risco determinístico entre 0 e 1, calculado de forma síncrona na criação. O motor é baseado em regras com pesos: o score é a soma ponderada dos sinais disparados, saturada em 1 e arredondada a 4 casas decimais.

Sinais

conversion_velocity só dispara se houver clique vencedor com timestamp. disposable_email só é avaliado quando o customer.email em texto puro é enviado (o hash não permite extrair o domínio).
A Conversão manual também roda fraude: autorreferência, idade da conta e e-mail descartável valem normalmente. conversion_velocity e click_burst ficam zerados por não haver clique.

Bandas de decisão

O campo fraudDecision é atribuído comparando o score com a política de fraude da organização (approveBelow, reviewAbove). Os limites são inclusivos na banda monitor: Apenas a banda review trava a Conversão em pending e a coloca na fila de revisão manual. monitor é aprovado: não entra na fila. Toda a decisão é congelada em fraudSnapshot (score, decision, signals[] com key/weight/triggered, e a policy vigente).
O fraudSnapshot deixa explícito por que uma Conversão foi flagada: o operador vê cada sinal disparado e o peso, não apenas o score final.

Política de fraude

As bandas são configuráveis por organização. O default (quando não configurada) é approveBelow = 0.3 e reviewAbove = 0.7.
A validação exige approveBelow <= reviewAbove (do contrário retorna 400 parameter_invalid). Veja a aba Referência da API para o schema completo.

Isolamento por afiliado e auto-pause

Confirmar fraude anula apenas a Conversão: nada além dela é travado e o Programa segue ativo; o isolamento é por afiliado. Há uma exceção automática: ao detectar autorreferência na criação, se o afiliado está approved e acumulou 3 ou mais tentativas de autorreferência, ele é pausado automaticamente. O evento affiliate.paused é emitido com ator system e reason: "self_referral_recurrence".

Ciclo de vida da conversão

O campo status reflete o estado da Conversão:
  • pending: aguardando revisão de fraude (nasce assim quando fraudDecision = review).
  • approved: ativa e válida para comissão.
  • voided: anulada (void manual ou fraude confirmada).
  • refunded: reembolsada. Este estado existe no enum, mas a transição para refunded vive no fluxo de refund e clawback de comissões/ingestão, não neste módulo.

Revisão de fraude

Conversões travadas (status = pending e fraudDecision = review) aparecem em GET /fraud/review-queue. O operador inspeciona o score e os sinais em GET /fraud/checks/{conversionId} e decide:
  • Falso positivo: POST /fraud/checks/{conversionId}/clear move a Conversão para approved + cleared e emite fraud.cleared.
  • Fraude confirmada: POST /fraud/checks/{conversionId}/confirm move a Conversão para voided + confirmed, grava voidReason: "fraud_confirmed" e emite fraud.confirmed.
Ambas as ações só são válidas a partir de fraudDecision = review; fora disso retornam 409 conflict.

Void

POST /conversions/{conversionId}/void anula uma Conversão e exige um motivo. Aceita apenas Conversões em pending ou approved; outros estados retornam 409 conflict. Emite conversion.voided com o status anterior, after: "voided" e o reason.

Auditoria

GET /conversions/{conversionId}/audit reconstrói a trilha de auditoria a partir do histórico de eventos, e não do estado atual. Todos os eventos da Conversão são listados em ordem, permitindo reconstruir cada decisão: criação, comissão gerada, void, clear e confirm de fraude, e o auto-pause por reincidência. Eventos emitidos pela Conversão:

Exemplo: registrar uma conversão

O endpoint exige ao menos um identificador de matching (clickId, visitorId, emailHash, fingerprint, couponCode ou customer.email). Sem nenhum, retorna 400 parameter_invalid. Respostas: 201 quando atribuiu e criou; 200 quando replayed, deduplicated ou attributed=false. Veja a aba Referência da API para todos os campos e filtros de listagem.

Regras relacionadas

Conversão é o vínculo cliente↔afiliado, não o objeto que recebe dinheiro. Idempotência permanente por sourceEventId; dedupe de cliente ativo com exceção de upgrade via parentConversionId. Registro manual exige justificativa. Estados pending/approved/voided/refunded.
Score determinístico 0 a 1 com sinais ponderados; bandas configuráveis approve/monitor/review; auto-pause na 3ª autorreferência; isolamento por afiliado; clear de falso positivo.

Próximos passos

Atribuição

Modelos last/first click, multi-touch e conflito cupom × clique.

Comissões

Como cada cobrança gera uma Comissão a partir do snapshot de regra.

Conversões server-to-server

Guia prático de integração da API de conversões.

Refund e clawback

O que acontece com a Conversão e as Comissões em um reembolso.