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

# Modelos de atribuição

> Os cinco modelos de atribuição e como dividem a comissão.

A Atribuição decide, no momento da Conversão, **qual Afiliado (ou Afiliados) recebe o crédito** por um Clique, e, em modelos multi-touch, em que proporção a Comissão é dividida entre eles. Cada [Programa](/docs/conceitos/programas-e-regras) escolhe um modelo; a decisão é congelada num snapshot na própria Conversão, garantindo auditabilidade total.

## Como a atribuição acontece

Quando uma Conversão é criada, a Repass monta a lista de **cliques candidatos** e aplica o modelo do Programa para produzir os **vencedores** (`winners`), cada um com um peso em basis points que soma exatamente `10000`.

<Steps>
  <Step title="Vincular a Conversão a um visitante">
    A identidade do convertido é resolvida na ordem `click_id` (S2S) → `visitor_id` (cookie) → `email_hash` (cross-device) → `fingerprint` (probabilístico). O método usado fica registrado em `matchMethod`.
  </Step>

  <Step title="Selecionar os cliques candidatos">
    Entram apenas Cliques **não expirados**, **não-bot** e do **mesmo visitante**, em qualquer Link de qualquer Afiliado do Programa. A expiração segue a janela de atribuição do Programa, contada a partir do `occurredAt` do Clique.
  </Step>

  <Step title="Aplicar o modelo do Programa">
    O modelo (`first_click`, `last_click`, `linear`, `time_decay` ou `position_based`) transforma os candidatos em vencedores com pesos em basis points.
  </Step>

  <Step title="Snapshotar a decisão">
    A Conversão guarda a lista de candidatos avaliados, o modelo aplicado, os vencedores e seus pesos. Esse snapshot é a fonte de verdade para a geração de Comissões e para [reprocessamento](/docs/conceitos/reprocessamento).
  </Step>
</Steps>

<Note>
  Janelas de atribuição usam o `occurredAt` (quando o fato aconteceu), nunca o `recordedAt` (quando a Repass registrou). Um Clique fora da janela simplesmente não entra como candidato: não há atribuição "tardia".
</Note>

## Os cinco modelos

`last_click` é o padrão de um Programa novo. Os três modelos multi-touch (`linear`, `time_decay`, `position_based`) distribuem o crédito entre todos os candidatos dentro da janela.

<AccordionGroup>
  <Accordion title="first_click: primeiro toque" icon="flag-checkered">
    Crédito integral (`10000` bps) ao Clique **mais antigo** dentro da janela. Premia a descoberta: o Afiliado que originou a jornada leva tudo.
  </Accordion>

  <Accordion title="last_click: último toque (default)" icon="circle-check">
    Crédito integral (`10000` bps) ao Clique **mais recente** dentro da janela. É o modelo padrão e o mais comum no mercado: o Afiliado que estava mais perto da Conversão leva tudo.
  </Accordion>

  <Accordion title="linear: distribuição igual" icon="equals">
    Divide o crédito **igualmente** entre todos os candidatos. Com 4 cliques, cada um recebe `2500` bps. Bom quando todos os toques têm valor comparável.
  </Accordion>

  <Accordion title="time_decay: decaimento temporal (meia-vida de 7 dias)" icon="hourglass-half">
    O peso bruto de cada Clique é `2^(−Δt/7d)`: cai pela metade a cada **7 dias** de distância em relação ao Clique mais recente. Cliques recentes pesam mais que os antigos, sem zerar a contribuição dos primeiros toques.
  </Accordion>

  <Accordion title="position_based: em U (40/20/40)" icon="bezier-curve">
    **40%** ao primeiro Clique, **40%** ao último e **20%** dividido igualmente entre os do meio. Casos de borda: 1 candidato → 100%; 2 candidatos → 50/50 (não há "meio").
  </Accordion>
</AccordionGroup>

### Tabela comparativa

| Modelo                 | Peso bruto              | Multi-touch | Resultado típico            |
| ---------------------- | ----------------------- | ----------- | --------------------------- |
| `first_click`          | 100% no mais antigo     | Não         | 1 vencedor, `10000` bps     |
| `last_click` (default) | 100% no mais recente    | Não         | 1 vencedor, `10000` bps     |
| `linear`               | igual entre todos       | Sim         | N vencedores, `10000/N` bps |
| `time_decay`           | `2^(−Δt/7d)` por Clique | Sim         | recentes pesam mais         |
| `position_based`       | 40 / 20 / 40            | Sim         | bordas dominam              |

## Multi-touch: divisão de peso em basis points

Nos modelos multi-touch, os pesos brutos do modelo são convertidos em **basis points que somam exatamente `10000`**, distribuindo o crédito de forma proporcional entre os cliques. Cliques que normalizam para **`0` bps são descartados**: não recebem Comissão nem marcação de convertido.

```json winners (exemplo: position_based, 4 cliques) theme={null}
{
  "attributionModel": "position_based",
  "matchMethod": "click_id",
  "winners": [
    { "clickId": "click_01HZX...A1", "affiliateId": "aff_01HZX...01", "weightBps": 4000 },
    { "clickId": "click_01HZX...D4", "affiliateId": "aff_01HZX...02", "weightBps": 4000 },
    { "clickId": "click_01HZX...B2", "affiliateId": "aff_01HZX...01", "weightBps": 1000 },
    { "clickId": "click_01HZX...C3", "affiliateId": "aff_01HZX...03", "weightBps": 1000 }
  ]
}
```

Os vencedores são snapshotados **por Clique** (para auditabilidade). Na hora de gerar [Comissões](/docs/conceitos/comissoes), os pesos do **mesmo Afiliado são agregados**: uma cobrança gera **no máximo uma Comissão standard por Afiliado**. No exemplo acima, `aff_...01` aparece em dois cliques (`4000 + 1000`) e recebe uma Comissão com peso agregado de `5000` bps.

A divisão do dinheiro funciona assim: cada parte é arredondada **para baixo** ao centavo e a sobra do arredondamento vai ao Afiliado de **maior peso**.

```mermaid theme={null}
flowchart LR
    A["4 cliques candidatos"] --> B["pesos brutos do modelo<br/>40 / 40 / 20 → 10/10"]
    B --> C["normaliza p/ bps<br/>(proporcional, soma = 10000)"]
    C --> D["winners por clique<br/>(snapshot)"]
    D --> E["agrega por afiliado<br/>5000 / 4000 / 1000 bps"]
    E --> F["divide o valor<br/>centavos · bps / 10000"]
```

<Tip>
  Trocar o modelo de atribuição de um Programa **não** altera Conversões já criadas: elas mantêm o snapshot original. Para recalcular o histórico sob um novo modelo, use [Reprocessamento](/docs/conceitos/reprocessamento). O passo a passo de uma divisão multi-touch está em [Multi-touch e atribuição](/docs/guias/multi-touch-atribuicao).
</Tip>

## Conflito cupom × link

Quando uma Conversão chega com um **Cupom de Afiliado** E também há um Clique atribuível de **outro Afiliado**, vale a política configurável do Programa, snapshotada na Conversão:

| Política                | Comportamento                                                                                                                                                |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `coupon_wins` (default) | O Afiliado dono do Cupom leva `10000` bps; `matchMethod` vira `coupon`.                                                                                      |
| `click_wins`            | Vencem os Cliques (mantém o modelo de atribuição); o Cupom é ignorado para crédito.                                                                          |
| `split_50_50`           | O Afiliado do Cupom é primário com `5000` bps; os vencedores do Clique são **reescalados** para somar os outros `5000`, preservando as proporções do modelo. |

<Info>
  Se o dono do Cupom **for o mesmo** Afiliado de um Clique vencedor, não há conflito: em modelos multi-touch ele apenas aparece como mais um vencedor, e os pesos do mesmo Afiliado são agregados na geração da Comissão.
</Info>

O Afiliado é identificado **pelo próprio Cupom** (`couponCode`). Você não envia um `affiliateId` ao criar uma Conversão.

```bash Conversão com cupom de afiliado theme={null}
curl https://api.userepass.com/conversions \
  -X POST \
  -H "Authorization: Bearer rstr_..." \
  -H "Content-Type: application/json" \
  -d '{
    "type": "one_time_purchase",
    "amountCents": 12990,
    "currency": "BRL",
    "sourceEventId": "order_98321",
    "couponCode": "MARIA10",
    "customer": { "email": "cliente@exemplo.com" }
  }'
```

Veja como Cupons se relacionam com Links em [Links e cupons](/docs/conceitos/links-e-cupons).

## Autorreferência (self-referral)

Uma Conversão cujo e-mail do cliente pertence ao **próprio Afiliado** é marcada como `self_referral` e **não gera Comissão**. A Conversão é registrada normalmente (para auditoria e antifraude), mas com `commissionSkippedReason: "self_referral"` e sem snapshot de regra de Comissão.

<Warning>
  Autorreferência é um sinal forte de fraude. A partir de **3 tentativas** de um mesmo Afiliado, o status dele muda para `paused` automaticamente e um Evento `affiliate.paused` é emitido. Detalhes em [Conversões e fraude](/docs/conceitos/conversoes-e-fraude).
</Warning>

## Próximos passos

<CardGroup cols={2}>
  <Card title="Multi-touch e atribuição" icon="diagram-project" href="/docs/guias/multi-touch-atribuicao">
    Passo a passo de uma divisão multi-touch, com os pesos calculados.
  </Card>

  <Card title="Comissões" icon="money-bill-trend-up" href="/docs/conceitos/comissoes">
    Como os pesos da atribuição viram dinheiro, por cobrança.
  </Card>

  <Card title="Conversões e fraude" icon="shield-halved" href="/docs/conceitos/conversoes-e-fraude">
    Estados da Conversão, score de fraude e autorreferência.
  </Card>

  <Card title="Reprocessamento" icon="rotate" href="/docs/conceitos/reprocessamento">
    Recalcular o histórico ao mudar o modelo de atribuição.
  </Card>
</CardGroup>
