dry_run) que você aprova, e o estado anterior nunca é apagado: o recálculo gera eventos novos encadeados ao histórico, e comissões já pagas (imutáveis) recebem ajustes em vez de serem reescritas.
O fluxo em duas fases
O reprocessamento é uma dupla confirmação explícita: você cria um dry-run, revisa o impacto, e só então executa. Não há atalho: o create nunca altera estado e o execute só aplica um dry-run aprovado.1
Crie o dry-run (relatório de impacto)
POST /reprocess congela uma cópia da regra nova, recalcula cada cobrança no intervalo e cria um job em dry_run com o summary de impacto e um item por comissão afetada. Nenhuma comissão é alterada. A resposta inclui um confirmationToken (só enquanto o job está dry_run).2
Revise o impacto
Leia o
summary (delta total, afiliados impactados, maiores variações) e, se precisar, GET /reprocess/{id}/items para o detalhe before/after por comissão. Decida se o resultado é o esperado.3
Execute ou cancele
POST /reprocess/{id}/execute aplica exatamente o relatório aprovado, de forma atômica. Se o delta exceder o limiar da política, envie o confirmationToken. Para descartar o dry-run, use POST /reprocess/{id}/cancel.executed e canceled são terminais: tentar executar ou cancelar um job que não está mais em dry_run retorna 409 conflict.
Dry-run obrigatório
Todo job nasce obrigatoriamente emdry_run. O body de POST /reprocess aceita apenas dryRun: true (é o default). Enviar dryRun: false resulta em 400 parameter_invalid. A aplicação real é sempre o passo separado POST /reprocess/{id}/execute.
O escopo de um job é:
string (prog_)
required
Programa-alvo. Obrigatório.
string (ISO 8601)
required
Início do intervalo (inclusivo). Filtra pelo
occurredAt da conversão.string (ISO 8601)
required
Fim do intervalo (exclusivo). O intervalo é meio-aberto
[from, to). Exige from < to (senão 400 parameter_invalid).string (cmrl_)
required
Regra de comissão cuja versão será aplicada. Deve pertencer ao programa (senão
404 resource_not_found).array de string (aff_)
Subconjunto opcional de afiliados (mínimo 1 elemento). Omitido ou
null = todos os afiliados do programa. Cada id deve pertencer ao programa (senão 400).boolean (literal true)
Sempre
true (default). Enviar false resulta em 400.Criar dry-run
Um job é resolvido por cobrança inteira (conversão × ciclo), não por linha de afiliado isolada. Se uma conversão cai dentro de
[from, to), todos os seus ciclos de cobrança são recalculados, inclusive os que ocorreram depois de to. O escopo é a conversão, não a data de cada cobrança individual.Relatório de impacto
Osummary é congelado no create e descreve, em centavos, o impacto que o execute aplicaria. Ele classifica cada comissão afetada em um de três tipos (kind):
Campos do
summary:
integer
Conversões distintas com pelo menos um item de mudança.
integer
Itens
recalculate (comissão não paga que mudaria de valor).integer
Itens
adjustment (comissão paga cujo delta vira ajuste).integer
Itens
blocked (comissão reservada em payout aberto).integer
Comissões cujo recálculo deu delta 0. Não geram item nem evento.
integer
Afiliados distintos com algum item.
integer (centavos)
Soma dos deltas aplicáveis (exclui
blocked). É a base do limiar de confirmação.array
Até 5 entradas
{ affiliateId, deltaCents }, ordenadas por |deltaCents| decrescente (exclui blocked).Resposta 201 (resumida)
calculation.baseAmountCents), com a aritmética original: taxa efetiva, arredondamento half-up em basis points e split multi-touch por peso (com a sobra de centavos indo ao winner de maior peso). Para regras tiered, o contexto de volume é o congelado no cálculo original: recálculo determinístico, não recontagem ao vivo. Veja Comissões e Atribuição para a mecânica de cálculo e split.
A versão da regra é congelada no momento do create. O execute aplica essa versão congelada, não a regra “ao vivo”, então alterar a regra entre o create e o execute não muda o resultado aprovado.
Sem mudança retroativa de pagamento
Comissões pagas são imutáveis. O reprocessamento nunca reescreve uma comissãopaid: o delta vira uma comissão nova do tipo adjustment, status approved, sem payout, que entra no netting do próximo payout do afiliado, positivo ou negativo, pelo mesmo mecanismo do clawback.
A comissão de ajuste referencia o job que a originou:
calculation.reprocess
+10000 (R$ 100,00) acima entra como crédito no próximo payout; um delta negativo entra como débito. Saldos negativos não geram cobrança ao afiliado: rolam para payouts futuros, como qualquer clawback. Comissões voided são ignoradas pelo job, e comissões dos tipos clawback/bonus ficam de fora do escopo (são fatos derivados, não recalculáveis pela regra).
Dupla confirmação por token
O execute exigeconfirmationToken quando, e somente quando, |deltaTotalCents| excede o confirmationThresholdCents da política (default R$ 1.000,00 / 100000 centavos). O campo confirmationRequired é calculado no create e congelado no job.
Token ausente ou errado acima do limiar retorna 409 conflict (não 403: um admin sem token continua admin). Abaixo do limiar, o execute funciona sem token.
confirmationToken é exposto na API somente enquanto o job está dry_run e nunca aparece em payload de evento. Após o execute ou cancel, ele deixa de circular.
A política é configurável por organização via PUT /settings/reprocess-policy:
integer (centavos)
Limite acima do qual o execute exige token. Default
100000. Mínimo 0 (zero = qualquer delta diferente de 0 exige confirmação).enum
Transparência ao afiliado impactado:
notify_always (default), notify_negative_only ou silent. A escolha é registrada no evento reprocess.completed.Encadeamento de eventos
O reprocessamento não reescreve o histórico: ele gera eventos novos encadeados, junto com a mudança de estado. O estado anterior permanece reconstruível pelo event store. A ordem no execute é determinística:
Consulte o catálogo de eventos para os schemas completos e Webhooks para entregá-los aos seus sistemas.
Garantias de consistência
O execute aplica exatamente o relatório aprovado, ou nada.- Um job por programa. No máximo um job aberto (
dry_run) por programa. Criar um segundo enquanto há um aberto retorna409 conflict. Jobs em programas diferentes podem coexistir.executedecanceledliberam a vaga. - Proteção contra dados desatualizados, tudo ou nada. Cada comissão não paga só é atualizada se ainda casa exatamente com o relatório (
amountCents+statusdo dry-run + sem payout); cada comissão paga só vira ajuste se continuapaidcom o mesmoamountCents. Qualquer divergência (refund, aprovação, reserva, pagamento entre o dry-run e o execute) cancela o execute inteiro com409 conflict: nenhum item parcial é aplicado. - Bloqueio por payout aberto. Se o relatório contém qualquer item
blocked, o execute é recusado com409 conflictantes de qualquer escrita. Liquide ou cancele o payout e crie um novo dry-run.
Erros
Todas as escritas (
POST /reprocess, /execute, /cancel, PUT /settings/reprocess-policy) exigem papel owner ou admin. As leituras (listar jobs, ver summary, listar itens, ler a política) estão abertas a qualquer membro. As rotas POST aceitam Idempotency-Key. Veja a Referência da API para os schemas detalhados de cada endpoint.
Próximos passos
Reprocessar mudança de regra
Guia passo a passo para aplicar uma nova versão de regra ao histórico.
Comissões
A aritmética de cálculo, ajustes e o ciclo de vida das comissões.
Refund e clawback
O mesmo mecanismo de netting que os ajustes de reprocessamento usam.
Event store
Como os eventos encadeados preservam o histórico auditável.