Pular para o conteúdo principal

Explicação Completa dos Cálculos de Comissão e Spread

Documento de referência sobre como o sistema calcula spreads e comissões por nível (N4 ( N4 ( REPRESENTANTE)), Marketplace, White Label e Cronos), com fórmulas, tabelas envolvidas, trechos de código, exemplos numéricos e regras de borda.


1. Visão Geral

A operação é uma cadeia de revenda de adquirência. Quem paga a taxa é o Estabelecimento (EC); cada nível acima ganha a diferença (spread) entre o que recebe do nível abaixo e o seu próprio custo.

EC (paga a taxa) → N4 ( N4 ( REPRESENTANTE)) → Marketplace → White Label → Cronos (base/custo)

Diagrama da cadeia e dos spreads

FLUXO DA TAXA (de quem paga até a base)

┌─────────────┐ paga taxa do plano
│ EC │ ───────────────────────────────────────────────┐
│ (não ganha) │ │
└─────────────┘ ▼
taxa_plano_ec ─┐ valor da venda
│ spread_rep = taxa_plano_ec − taxa_rep

┌──────────────────────┐
│ N4 ( N4 ( REPRESENTANTE)) │ ganha: valor × spread_rep ÷ 100
└──────────────────────┘
taxa_rep ─┐
│ spread_mkt = taxa_rep − taxa_mkt (só se mkt na mesma cadeia)

┌──────────────────────┐
│ MARKETPLACE │ ganha: valor × spread_mkt ÷ 100
└──────────────────────┘
taxa_mkt ─┐
│ spread_wl = taxa_mkt − taxa_wl (ou taxa_rep − taxa_wl se não há mkt)

┌──────────────────────┐
│ WHITE LABEL │ ganha: valor × spread_wl ÷ 100
└──────────────────────┘
taxa_wl ─┐
│ spread_cronos = taxa_wl − taxa_padrao

┌──────────────────────┐
│ CRONOS (base/custo) │ ganha: valor × spread_cronos ÷ 100
└──────────────────────┘
taxa_padrao ◄── piso / custo da operação

Cada nível fica com a fatia (spread) entre a taxa que recebe do nível de cima na pilha (quem paga mais) e a sua própria taxa de custo. A soma de todos os spreads = taxa_plano_ec − taxa_padrao.

  • EC — não recebe comissão, apenas paga a taxa do plano.
  • N4 ( N4 ( N4 ( REPRESENTANTE))) — ganha sobre o EC.
  • Marketplace — ganha sobre o N4 ( N4 ( N4 ( REPRESENTANTE))) (só se estiver na mesma cadeia/WL).
  • White Label — ganha sobre o Marketplace (ou sobre o N4 ( N4 ( N4 ( REPRESENTANTE))), se não houver Mkt).
  • Cronos — é a base; fica com a margem entre a taxa do WL e o custo.

Existem dois modelos de cálculo, detectados automaticamente:

ModeloQuando é usadoBase de custo
Modelo 1 — Spread DiferencialPlanos sem taxas MDRtaxas_padrao (Cronos)
Modelo 2 — MDR com cadeia de custoPlanos com taxas MDR (plano_taxas_mdr)cronos_taxas_subadquirencia (custo por MCC)

A detecção é feita verificando se o plano possui taxas MDR cadastradas:

function planoUsaMdr($conn, $plano_id) {
if (!$plano_id) return false;
$stmt = $conn->prepare("SELECT 1 FROM plano_taxas_mdr WHERE plano_id = ? LIMIT 1");
$stmt->bind_param("i", $plano_id);
$stmt->execute();
$exists = $stmt->get_result()->num_rows > 0;
$stmt->close();
return $exists;
}

2. Hierarquia de Busca de Taxa

Quando o sistema precisa da taxa aplicável a uma transação, busca nesta ordem:

  1. Taxa do Plano vinculado ao EC → plano_taxas_cet / plano_taxas
  2. Taxa do Usuário (custo efetivo) → user_taxas
  3. Taxa do White Labelwhite_label_taxas
  4. Taxa Padrão do sistema → taxas_padrao

O primeiro nível que retornar valor encerra a busca:

function buscarTaxaReal($conn, $estabelecimento_id, $user_id, $white_label_id, $bandeira_id, $tipo_pagamento, $parcelas) {
// 1. Taxa do plano vinculado ao estabelecimento
if ($estabelecimento_id) {
// ... busca plano_id e chama buscarTaxaPlano(...)
if ($taxa !== null) return $taxa;
}
// 2. Taxa do usuário (custo efetivo - user_taxas)
if ($user_id) {
$taxa = buscarTaxaUsuario($conn, $user_id, $bandeira_id, $tipo_pagamento, $parcelas);
if ($taxa !== null) return $taxa;
}
// 3. Taxa do white_label
if ($white_label_id) {
$taxa = buscarTaxaWhiteLabel($conn, $white_label_id, $bandeira_id, $tipo_pagamento, $parcelas);
if ($taxa !== null) return $taxa;
}
// 4. Taxa padrão do sistema
return buscarTaxaPadrao($conn, $bandeira_id, $tipo_pagamento, $parcelas);
}

Se nada for encontrado, usa-se um fallback fixo:

function buscarTaxaPadraoFallback($tipo_pagamento, $parcelas) {
if ($tipo_pagamento === 'pix') return 0.75;
if ($tipo_pagamento === 'debito') return 1.25;
// Crédito
if ($parcelas == 1) return 2.50;
if ($parcelas >= 2 && $parcelas <= 6) return 3.00;
if ($parcelas >= 7 && $parcelas <= 12) return 4.00;
return 2.50;
}

3. Tabelas Envolvidas

Modelo 1 (Spread Diferencial)

VariávelTabelaSignificado
taxa_plano_ecplano_taxas_cet, plano_taxasO que o EC paga
taxa_N4 ( N4 ( REPRESENTANTE))user_taxasCusto efetivo do rep
taxa_marketplaceuser_taxas (ou white_label_taxas do mkt)Custo efetivo do mkt
taxa_white_labelwhite_label_taxasCusto do WL
taxa_padraotaxas_padraoBase / custo Cronos

Modelo 2 (MDR)

VariávelTabelaSignificado
plano_mdrplano_taxas_mdrO que o EC paga
mdr_rep / mdr_mktuser_mdr_taxasSpread do rep/mkt
mdr_wlwhite_label_mdr_taxasSpread do WL
taxa_custo_mcccronos_taxas_subadquirenciaCusto base por MCC

Tabelas de apoio (ambos os modelos)

TabelaUso
estabelecimentos_locaisVincula EC ao plano, ao N4 ( N4 ( REPRESENTANTE)) (user_id) e ao MCC
usersDefine a cadeia: white_label_id e user_id (quem cadastrou cada nível)
bandeirasMapeia nome ↔ bandeira_id (Visa, Mastercard, Elo, Amex...)
transacoes_locaisTransações reais (valor em centavos, bandeira, método, parcelas, status)
prazo_medio_parcelasPrazo médio por nº de parcelas (usado no CET)

Trechos das funções de busca de taxa

Taxa do White Label (white_label_taxas):

function buscarTaxaWhiteLabel($conn, $white_label_id, $bandeira_id, $tipo_pagamento, $parcelas) {
$sql = "
SELECT taxa
FROM white_label_taxas
WHERE white_label_id = ?
AND bandeira_id = ?
AND tipo_pagamento = ?
AND parcelas = ?
AND ativo = TRUE
LIMIT 1
";
$stmt = $conn->prepare($sql);
$stmt->bind_param("iisi", $white_label_id, $bandeira_id, $tipo_pagamento, $parcelas);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
$stmt->close();
return (float)$row['taxa'];
}
$stmt->close();
return null;
}

Taxa do Usuário (user_taxas):

function buscarTaxaUsuario($conn, $user_id, $bandeira_id, $tipo_pagamento, $parcelas) {
$sql = "
SELECT taxa
FROM user_taxas
WHERE usuario_id = ?
AND bandeira_id = ?
AND tipo_pagamento = ?
AND parcelas = ?
LIMIT 1
";
$stmt = $conn->prepare($sql);
$stmt->bind_param("iisi", $user_id, $bandeira_id, $tipo_pagamento, $parcelas);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
$stmt->close();
return (float)$row['taxa'];
}
$stmt->close();
return null;
}

4. Como a Cadeia é Identificada

A cadeia de cada estabelecimento é montada via JOIN:

SELECT
el.id, el.plano_id, el.user_id AS N4 ( N4 ( REPRESENTANTE))_id, el.ec_id_api,
u_rep.white_label_id AS N4 ( N4 ( REPRESENTANTE))_white_label_id,
u_rep.user_id AS marketplace_id,
u_mkt.white_label_id AS marketplace_white_label_id,
COALESCE(u_rep.white_label_id, u_mkt.white_label_id) AS white_label_id
FROM estabelecimentos_locais el
LEFT JOIN users u_rep ON el.user_id = u_rep.id -- N4 ( N4 ( REPRESENTANTE)) do EC
LEFT JOIN users u_mkt ON u_rep.user_id = u_mkt.id -- marketplace acima do rep
WHERE el.id = ?
  • N4 ( N4 ( REPRESENTANTE)) = el.user_id (quem cadastrou o EC).
  • Marketplace = u_rep.user_id (quem está acima do rep).
  • White Label = white_label_id do rep, ou do mkt como fallback.

Regras de borda da cadeia

// Mkt só entra na cadeia se estiver no MESMO white label do N4 ( N4 ( REPRESENTANTE))
$marketplace_na_cadeia = ($marketplace_id
&& $marketplace_white_label_id !== null
&& $N4 ( N4 ( REPRESENTANTE))_white_label_id !== null
&& (int)$marketplace_white_label_id === (int)$N4 ( N4 ( REPRESENTANTE))_white_label_id);

$marketplace_id_para_spread = $marketplace_na_cadeia ? $marketplace_id : null;

// Se quem cadastrou o EC foi o próprio marketplace, o rep não ganha spread
$rep_eh_o_cadastrante = ($N4 ( N4 ( REPRESENTANTE))_id && $marketplace_id
&& (int)$N4 ( N4 ( REPRESENTANTE))_id === (int)$marketplace_id);
  • marketplace_na_cadeia evita pagar comissão a um Mkt de outro white label.
  • rep_eh_o_cadastrante evita comissão duplicada quando o cadastrante é o próprio Mkt.

5. MODELO 1 — Spread Diferencial

5.1. Fórmulas dos spreads

spread_rep = taxa_plano_ec − taxa_N4 ( N4 ( REPRESENTANTE))
spread_mkt = taxa_N4 ( N4 ( REPRESENTANTE)) − taxa_marketplace (só se mkt na cadeia)
spread_wl = taxa_marketplace − taxa_white_label (se há mkt na cadeia)
= taxa_N4 ( N4 ( REPRESENTANTE)) − taxa_white_label (se NÃO há mkt)
spread_cronos = taxa_white_label − taxa_padrao

Todos os spreads são limitados a zero (max(0, spread)) — nunca negativos.

5.2. Trecho real do cálculo dos spreads

// Spread do N4 ( N4 ( REPRESENTANTE))
$spread_N4 ( N4 ( REPRESENTANTE)) = 0;
if (!$rep_eh_o_cadastrante && $N4 ( N4 ( REPRESENTANTE))_id && $taxa_N4 ( N4 ( REPRESENTANTE)) !== null && $taxa_plano_ec !== null) {
$spread_N4 ( N4 ( REPRESENTANTE)) = $taxa_plano_ec - $taxa_N4 ( N4 ( REPRESENTANTE));
}

// Spread do Marketplace
$spread_marketplace = 0;
if ($marketplace_id_para_spread && $taxa_marketplace !== null && $taxa_N4 ( N4 ( REPRESENTANTE)) !== null) {
$spread_marketplace = $taxa_N4 ( N4 ( REPRESENTANTE)) - $taxa_marketplace;
}

// Spread do White Label
$spread_white_label = 0;
if ($white_label_id && $taxa_white_label !== null) {
if ($marketplace_id_para_spread && $taxa_marketplace !== null) {
$spread_white_label = $taxa_marketplace - $taxa_white_label; // com Mkt
} elseif ($N4 ( N4 ( REPRESENTANTE))_id && $taxa_N4 ( N4 ( REPRESENTANTE)) !== null) {
$spread_white_label = $taxa_N4 ( N4 ( REPRESENTANTE)) - $taxa_white_label; // sem Mkt
} else {
$spread_white_label = $taxa_white_label - $taxa_padrao; // fallback
}
}

// Spread da Cronos (base)
$spread_cronos = 0;
if ($white_label_id && $taxa_white_label !== null) {
$spread_cronos = $taxa_white_label - $taxa_padrao;
}

// Nenhum spread pode ser negativo
$spread_N4 ( N4 ( REPRESENTANTE)) = max(0, $spread_N4 ( N4 ( REPRESENTANTE)));
$spread_marketplace = max(0, $spread_marketplace);
$spread_white_label = max(0, $spread_white_label);
$spread_cronos = max(0, $spread_cronos);

5.3. Conversão de spread em comissão (R$)

$valor = (float)$transacao['amount'] / 100; // centavos → reais

$comissao_N4 ( N4 ( REPRESENTANTE)) = ($valor * $spread_N4 ( N4 ( REPRESENTANTE))) / 100;
$comissao_marketplace = ($valor * $spread_marketplace) / 100;
$comissao_white_label = ($valor * $spread_white_label) / 100;
$comissao_cronos = ($valor * $spread_cronos) / 100;

Fórmula geral: comissão (R$) = valor_transação × spread(%) ÷ 100

5.4. Exemplo completo

Transação de R$ 1.000,00 — crédito à vista (Visa):

NívelTaxaSpreadComissão
Plano EC2,8%(paga R$ 28,00)
N4 ( N4 ( REPRESENTANTE))2,5%2,8 − 2,5 = 0,3%R$ 3,00
Marketplace2,3%2,5 − 2,3 = 0,2%R$ 2,00
White Label2,0%2,3 − 2,0 = 0,3%R$ 3,00
Cronos (padrão)1,5%2,0 − 1,5 = 0,5%R$ 5,00
Total comissões1,3%R$ 13,00

6. MODELO 2 — MDR com Cadeia de Custo

A base deixa de ser taxas_padrao e passa a ser o custo por MCC (cronos_taxas_subadquirencia, lido a partir de estabelecimentos_locais.mcc). O custo de cada nível = custo do nível abaixo + spread (MDR) daquele nível.

6.1. Cadeia de custo

taxa_custo_mcc = (cronos_taxas_subadquirencia, por MCC/bandeira/produto)
taxa_custo_wl = taxa_custo_mcc + mdr_cronos
taxa_custo_mkt = taxa_custo_wl + mdr_wl
taxa_custo_rep = taxa_custo_mkt + mdr_mkt

6.2. Fórmulas dos spreads (MDR)

spread_cronos = mdr_wl (margem da base)
spread_wl = max(0, plano_mdr − taxa_custo_wl)
spread_mkt = se cadastrante: max(0, plano_mdr − taxa_custo_mkt)
= se há rep: mdr_rep
spread_rep = max(0, plano_mdr − taxa_custo_rep) (0 se mkt é o cadastrante)

onde plano_mdr é a taxa que o EC efetivamente paga (plano_taxas_mdr).

6.3. Coluna MDR por produto

As tabelas MDR têm colunas por produto:

function getMdrColuna($tipo_pagamento, $parcelas) {
if ($tipo_pagamento === 'pix') return 'pix';
if ($tipo_pagamento === 'debito') return 'debito';
if ($parcelas == 1) return 'credito_vista';
if ($parcelas >= 2 && $parcelas <= 6) return 'credito_2a6';
return 'credito_7a12';
}
Tipo / parcelasColuna
PIXpix
Débitodebito
Crédito 1xcredito_vista
Crédito 2-6xcredito_2a6
Crédito 7-12xcredito_7a12

6.4. Trechos das funções MDR

Taxa MDR do White Label (white_label_mdr_taxas):

function buscarTaxaMdrWhiteLabel($conn, $wl_id, $bandeira_id, $tipo_pagamento, $parcelas) {
$coluna = getMdrColuna($tipo_pagamento, $parcelas);
$sql = "SELECT `$coluna` AS taxa FROM white_label_mdr_taxas WHERE white_label_id = ? AND bandeira_id = ? LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bind_param("ii", $wl_id, $bandeira_id);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
$stmt->close();
return ($row['taxa'] !== null) ? (float)$row['taxa'] : null;
}
$stmt->close();
return null;
}

Custo por MCC (cronos_taxas_subadquirencia), trecho da seleção de coluna por bandeira/produto:

$bandeiraSlug = normalizarBandeiraMcc($card_brand); // visa | master | elo | amex

if ($tipo_pagamento === 'debito') {
$coluna = $bandeiraSlug . '_debito'; // ex: master_debito
} else {
if ($parcelas == 1) {
$coluna = $bandeiraSlug . '_credito_vista';
} elseif ($parcelas >= 2 && $parcelas <= 6) {
$coluna = $bandeiraSlug . '_parcelado_loja_2_6';
} else {
$coluna = $bandeiraSlug . '_parcelado_loja_7_12';
}
}

$valor = (float)$mccData[$coluna];
if ($valor > 0 && $valor < 1) { // se vier em decimal, converte para percentual
$valor *= 100;
}

6.5. Exemplos passo a passo

Em todos os exemplos a cadeia é EC → Rep → Mkt → WL → Cronos, com MDR de 0,20% por nível. A coluna de custo no MCC muda conforme o produto (ver getMdrColuna e a seleção de coluna em 6.4).

A) Crédito 1x — Mastercard — venda de R$ 1.000,00

Coluna MCC: master_credito_vista · Coluna MDR: credito_vista

Passo 1 — Custo base (MCC): taxa_custo_mcc = 1,78%

Passo 2 — Cadeia de custo (sobe somando o MDR de cada nível):

taxa_custo_wl = 1,78 + 0,20 = 1,98%
taxa_custo_mkt = 1,98 + 0,20 = 2,18%
taxa_custo_rep = 2,18 + 0,20 = 2,38%

Passo 3 — Taxa que o EC paga (plano_taxas_mdr): plano_mdr = 2,41%

Passo 4 — Spreads:

spread_cronos = mdr_wl = 0,20%
spread_wl = max(0, 2,41 − 1,98) = 0,43%
spread_mkt = mdr_rep / regra cadeia = 0,20%
spread_rep = max(0, 2,41 − 2,38) = 0,03%

Passo 5 — Comissões (valor × spread ÷ 100), venda R$ 1.000,00:

NívelSpreadComissão
Cronos0,20%R$ 2,00
White Label0,43%R$ 4,30
Marketplace0,20%R$ 2,00
N4 ( N4 ( REPRESENTANTE))0,03%R$ 0,30

B) Débito — Visa — venda de R$ 500,00

Coluna MCC: visa_debito · Coluna MDR: debito

Passo 1 — Custo base (MCC): taxa_custo_mcc = 0,85%

Passo 2 — Cadeia de custo:

taxa_custo_wl = 0,85 + 0,20 = 1,05%
taxa_custo_mkt = 1,05 + 0,20 = 1,25%
taxa_custo_rep = 1,25 + 0,20 = 1,45%

Passo 3 — Taxa que o EC paga: plano_mdr = 1,55%

Passo 4 — Spreads:

spread_cronos = mdr_wl = 0,20%
spread_wl = max(0, 1,55 − 1,05) = 0,50%
spread_mkt = mdr_rep = 0,20%
spread_rep = max(0, 1,55 − 1,45) = 0,10%

Passo 5 — Comissões, venda R$ 500,00:

NívelSpreadComissão
Cronos0,20%R$ 1,00
White Label0,50%R$ 2,50
Marketplace0,20%R$ 1,00
N4 ( N4 ( REPRESENTANTE))0,10%R$ 0,50

C) PIX — venda de R$ 200,00

Coluna MCC: pix (campo genérico, não depende de bandeira) · Coluna MDR: pix Para PIX, a bandeira de fallback é Visa (bandeira_id = 1).

Passo 1 — Custo base (MCC): taxa_custo_mcc = 0,40%

Passo 2 — Cadeia de custo (MDR de 0,10% por nível neste exemplo):

taxa_custo_wl = 0,40 + 0,10 = 0,50%
taxa_custo_mkt = 0,50 + 0,10 = 0,60%
taxa_custo_rep = 0,60 + 0,10 = 0,70%

Passo 3 — Taxa que o EC paga: plano_mdr = 0,99%

Passo 4 — Spreads:

spread_cronos = mdr_wl = 0,10%
spread_wl = max(0, 0,99 − 0,50) = 0,49%
spread_mkt = mdr_rep = 0,10%
spread_rep = max(0, 0,99 − 0,70) = 0,29%

Passo 5 — Comissões, venda R$ 200,00:

NívelSpreadComissão
Cronos0,10%R$ 0,20
White Label0,49%R$ 0,98
Marketplace0,10%R$ 0,20
N4 ( N4 ( REPRESENTANTE))0,29%R$ 0,58

Atenção: as fórmulas de spread do Modelo 2 (spread_wl = plano_mdr − taxa_custo_wl e spread_rep = plano_mdr − taxa_custo_rep) seguem a documentação inline do código. Como cada uma mede a margem total acima do próprio custo, os valores se sobrepõem — a soma dos spreads pode ultrapassar plano_mdr − taxa_custo_mcc. Antes de usar em fechamento financeiro, confirme com a regra de negócio quem efetivamente fica com cada fatia (mesma ressalva do item 7 da seção 9).


7. Composição da Taxa Final do EC (MDR) e CET

A taxa cobrada do estabelecimento é montada somando camadas:

taxa_final = taxa_MCC (base) + taxa_MDR_usuário + taxa_MDR_white_label

Trecho da soma das camadas (por bandeira e produto):

// Crédito 1x — soma usuário + white label sobre a base do MCC
if ($user_id) {
$taxaUser = buscarTaxasUsuarioMDR($conn, $user_id, $bandeira_id, 'credito_1');
$taxasFinais[$bandeiraNome]['credito_1'] += $taxaUser;
}
if ($white_label_id) {
$taxaWL = buscarTaxasWhiteLabelMDR($conn, $white_label_id, $bandeira_id, 'credito_1');
$taxasFinais[$bandeiraNome]['credito_1'] += $taxaWL;
}

O mesmo vale para PIX e Antecipação:

// PIX: MCC + Usuário MDR + White Label MDR
$pixFinal = $pixMCC;
if ($user_id) $pixFinal += buscarPixUsuarioMDR($conn, $user_id);
if ($white_label_id) $pixFinal += buscarPixWhiteLabelMDR($conn, $white_label_id);

// Antecipação: MCC + Usuário MDR + White Label MDR
$antecipacaoFinal = $antecipacaoMCC;
if ($user_id) $antecipacaoFinal += buscarAntecipacaoUsuarioMDR($conn, $user_id);
if ($white_label_id) $antecipacaoFinal += buscarAntecipacaoWhiteLabelMDR($conn, $white_label_id);

As taxas do WL vêm de white_label_mdr_taxas e são convertidas de percentual para decimal (taxa / 100).

7.1. Cálculo do CET (Custo Efetivo Total)

CET = 1 − ( (1 − taxa_final) × (1 − antecipacao_final × prazo_medio) )

Trecho real do cálculo (recalculado com as taxas finais já somadas):

$taxas[$index]['visa'] =
number_format((1 - ((1 - $visaBaseFinal) * (1 - $antecipacaoFinal * $prazoMedio))) * 100, 2, ',', '') . '%';
  • taxa_final e antecipacao_final já incluem a camada do WL.
  • prazo_medio vem de prazo_medio_parcelas (1,0 para 1x).
  • O CET é recalculado após somar todas as camadas.

8. Resumo das Fórmulas (cola rápida)

ItemFórmula
Spread Reptaxa_plano_ec − taxa_rep
Spread Mkttaxa_rep − taxa_mkt (se mkt na cadeia)
Spread WLtaxa_mkt − taxa_wl (ou taxa_rep − taxa_wl sem mkt)
Spread Cronostaxa_wl − taxa_padrao
Comissão (R$)valor × spread ÷ 100
Taxa final (MDR)taxa_mcc + taxa_usuário + taxa_wl
CET1 − ((1 − taxa_final) × (1 − antecipacao × prazo_medio))

9. Regras de Borda e Pontos de Atenção

  1. Spread nunca negativo — todos passam por max(0, ...). Se a taxa do WL for maior que a do nível abaixo, a comissão é zero (não há prejuízo registrado).

  2. Fallback para taxa padrão — taxas ausentes caem para taxa_padrao, o que pode zerar spreads:

    if ($taxa_plano_ec === null) $taxa_plano_ec = $taxa_padrao;
    if ($taxa_N4 ( N4 ( REPRESENTANTE)) === null) $taxa_N4 ( N4 ( REPRESENTANTE)) = $taxa_padrao;
    if ($taxa_marketplace === null) $taxa_marketplace = $taxa_padrao;
    if ($taxa_white_label === null) $taxa_white_label = $taxa_padrao;
  3. Marketplace fora da cadeia — Mkt de outro white label é ignorado (marketplace_na_cadeia = false); o WL passa a ganhar sobre o N4 ( N4 ( REPRESENTANTE)).

  4. Rep = cadastrante — se o N4 ( N4 ( REPRESENTANTE)) é o próprio marketplace, spread_rep = 0 (evita duplicidade).

  5. Valor em centavostransacoes_locais.amount está em centavos; sempre dividir por 100.

  6. Só transações aprovadas — o cálculo filtra status = 'APPR':

    WHERE tl.merchant_id = ?
    AND DATE(tl.start_date) BETWEEN ? AND ?
    AND tl.status = 'APPR'
  7. Ambiguidade WL × Cronos (Modelo 1)spread_cronos = taxa_wl − taxa_padrao é calculado de forma independente do spread_wl. Vale validar com a regra de negócio se a margem da base não está sendo contabilizada em duplicidade.

  8. Conversão percentual ↔ decimal — taxas MDR são gravadas em percentual e divididas por 100 no consumo; nos campos MCC, valores entre 0 e 1 são multiplicados por 100.