Toda transação processada pelo DL Pay Acquirer é governada por dois planos distintos, que juntos decidem quanto do valor o vendedor efetivamente fica:

Plano de tarifas do adquirente

O cronograma de tarifas do adquirente. Define o MDR cobrado, dividido por tipo de pagamento, quantidade de parcelas e bandeira do cartão. Lado adquirente.

SplitPlan

O template de comissionamento. Define como a margem restante é distribuída entre agente, distribuidores, desenvolvedor e a conta administrativa da plataforma. Lado plataforma.
Um vendedor pode ter apenas um SplitPlan ativo (vinculado via unified.Split), e esse plano referencia exatamente um plano de tarifas do adquirente. Quando uma transação é capturada, a plataforma compila as duas tabelas juntas para produzir as regras finais de split que serão enviadas ao adquirente.

Plano de tarifas do adquirente

Um plans.Plan (frequentemente chamado de “plano de tarifas” no painel) espelha um recurso /plans/<id> no adquirente. O cronograma de tarifas vive no campo JSON fee_details — uma entrada por combinação de (payment_type, installments, card_brand, capture_mode), cada uma com um percent_amount. O modelo expõe duas funções auxiliares usadas em todos os pontos onde tarifas são cotadas:
AuxiliarFinalidade
Tarifas formatadasRetorna as tarifas indexadas por [payment_type][installments][brand]. Filtra por capture_mode (manually_keyed para online, null para cartão físico, barcode para PIX/boleto, ou any para ignorar o filtro). Múltiplas linhas de origem do adquirente para a mesma chave são somadas.
Detalhamento de tarifasOs mesmos dados acompanhados das listas de bandeiras e tipos descobertos, usados para renderizar tabelas de simulação.
Há duas regras importantes de capture_mode:
  • Tarifas barcode são sempre incluídas, independentemente do filtro — referem-se a PIX e boleto e não têm variante online/offline distinta.
  • Tarifas opf_initiator são ignoradas (tarifas de Open Finance são tratadas separadamente).
Um plano de tarifas é criado via Criar plano de tarifas e listado em Listar planos de tarifas.

SplitPlan — o template de comissionamento

O plans.SplitPlan define, para cada combinação de (payment_type, installments, card_brand), quem recebe uma fatia da transação e quanto. Ele se relaciona um-para-muitos com unified.Account via unified.Split. Cada SplitPlan carrega duas tabelas JSON armazenadas como texto:
CampoUsado quando
split_detailsA transação foi capturada offline (modo de entrada diferente de manually_keyed, mais PIX e boleto).
split_details_onlineA transação foi capturada online (entrada de cartão manually_keyed).
E mais um booleano:
CampoPadrãoO que faz
automatic_developer_feetrueQuando true, o processo de auto-split garante uma taxa mínima de 0,1% para o desenvolvedor em toda transação, mesmo que Programador não esteja presente em split_details. Quando false, somente entradas explícitas de Programador são honradas.

Anatomia de split_details e split_details_online

O JSON tem o mesmo formato em ambos os campos:
{
  "<payment_type>": {
    "<installments>": {
      "<card_brand>": {
        "<participant>": <percentage_or_string>
      }
    }
  }
}
Concretamente, um plano real se parece com:
{
  "credit": {
    "1": {
      "Visa":        { "Agente": 1.0, "Distribuidor N1": 0.5, "Programador": 0.1 },
      "MasterCard":  { "Agente": 1.0, "Distribuidor N1": 0.5, "Programador": 0.1 },
      "Todas as bandeiras %": { "Agente": 1.0, "Programador": 0.1 }
    },
    "2": { "...": "..." }
  },
  "debit": {
    "1": {
      "PIX":    { "Agente": 0.5, "Administrador": 0.79 },
      "Boleto": { "Agente": 2.00 }
    }
  }
}
Algumas regras a ter em mente:
Regra
As chaves do nível externo (credit, debit) correspondem ao payment_type do adquirente. PIX e boleto são normalizados para debit com installment igual a "1" e uma bandeira sintética de "PIX" ou "Boleto".
A bandeira-curinga "Todas as bandeiras %" é usada quando a bandeira do comprador não tem entrada dedicada.
Se nem a bandeira exata nem o curinga estão presentes, a busca recorre a Visa (quando a bandeira era Visa Electron) e, por último, a MasterCard.
Os nomes de participantes são padronizados, não arbitrários. Chaves reconhecidas: Administrador, Agente, Distribuidor N1, Distribuidor N2, Programador. Qualquer outra coisa é registrada como “Unknown split key” e ignorada.
Programador é um espaço reservado: o destinatário real é uma conta interna fixa de desenvolvedor da plataforma. Ele é removido da lista de splits antes do cálculo dos totais por participante e re-adicionado ao final se automatic_developer_fee estiver ativo.
Administrador sempre aponta para a conta administrativa da plataforma para split, definida nas configurações de ambiente.
Os percentuais podem ser armazenados como números (1.0) ou como strings com sufixo % ("1.0%"). O código de auto-split interpreta ambos.

Lógica de busca

A busca dos splits para um dado (type, installment, brand, is_online) é o ponto único de entrada. PIX e boleto ignoram a flag is_online — são sempre offline, com installment="1" e a bandeira sintética. Para crédito, escolhe-se o lado correto entre split_details e split_details_online.

Tabela compilada de totais

Para simulações e para a tabela de parcelamento na página de pagamento, há uma função que percorre cada (type, installment, brand) do plano de tarifas correspondente e produz a tarifa total que o comprador (ou vendedor) vê. Esse total é a soma de:
ComponenteOrigem
Tarifa do adquirenteTarifas formatadas para a chave em questão.
Soma dos participantes de split_detailscom Programador extraído e substituído por max(declarado, 0.1).
Taxa padrão do desenvolvedor de 0.1%sempre — mesmo que o bucket não tenha entrada Programador.
O parâmetro de descarte de splits muito altos ignora qualquer participante configurado acima de 70% (uma proteção contra linhas-fantasma que existem apenas para planos de redirecionamento de chargeback). A tabela compilada alimenta duas visões:
  • Simular tarifas — dado um valor, retorna o preço a cargo do comprador e o a cargo do vendedor para cada parcela e bandeira.
  • A própria página de pagamento, ao renderizar o seletor de parcelas.

Atribuição padrão

Quando um vendedor é criado sem link de convite, a plataforma seleciona o plano padrão (configurado por ambiente; o valor padrão é "Plano Pro Padrão") e cria uma linha unified.Split com is_system_managed=true:
default_plan_name = getattr(settings, 'DEFAULT_SPLIT_PLAN_NAME', '')
if default_plan_name:
    default_plan = SplitPlan.objects.filter(name__icontains=default_plan_name).first()
    if default_plan:
        Split.objects.create(account=account, plan=default_plan, is_system_managed=True)
Quando o vendedor é criado a partir de um link de convite, o agent, n1_distributor, n2_distributor e o plan são copiados do link (com recuo para o split do próprio criador do link). Veja Links de convite. is_system_managed=true significa: o job de auto-split pode enviar novas regras de split ao adquirente para este vendedor. Defina como false (ou troque o plano manualmente) para sair — a plataforma ainda computa o split hipotético para fins de relatório, mas marca as transações como ALREADY_PROCESSED em vez de enviar.

Anatomia de unified.Split

Split é a linha por conta que liga o plano às contas destinatárias reais:
CampoPara o que aponta
accountO vendedor ao qual este split pertence.
agentA conta unificada que recebe o percentual de Agente.
n1_distributorA conta unificada que recebe Distribuidor N1.
n2_distributorA conta unificada que recebe Distribuidor N2.
developerConta de desenvolvedor cacheada; não é usada para roteamento (o job de auto-split utiliza o ID interno da conta de desenvolvedor da plataforma).
redirect_sales_toSe preenchido, a cota do próprio vendedor é redirecionada para esta conta (100% para cartões, valor integral para boleto). Usado em modelos de franquia/subconta.
planO SplitPlan a aplicar.
is_system_managedSe true, a plataforma pode enviar novas regras de split ao adquirente.

automatic_developer_fee

O booleano vive no SplitPlan e funciona como um piso:
  • true (padrão): toda transação recebe pelo menos 0,1% para a conta de desenvolvedor. Se o bucket correspondente declarar "Programador": 0.5, esse valor prevalece; se declarar "Programador": 0.05 ou omitir a chave, o piso de 0,1% se aplica.
  • false: apenas entradas explícitas de Programador são honradas. Não há piso automático.
A flag é exposta em Listar/recuperar split plans e em Criar/atualizar split plan, mas o serializer de criação é somente leitura sobre ela — o serializer de criação não a lista entre seus campos, então o valor fica travado no padrão true no momento da criação e só pode ser alterado pelo formulário do painel administrativo ou diretamente via o endpoint Atualizar split plan se o campo tiver sido adicionado ao serializer de criação. Trate o campo como somente leitura na criação, salvo confirmação em contrário no ambiente de execução.

Exemplo prático — PIX de R$ 100

Considere uma transação PIX de R$ 100,00 contra um vendedor cujo split plan se parece com:
{
  "debit": {
    "1": {
      "PIX": {
        "Agente": 0.50,
        "Distribuidor N1": 0.30,
        "Programador": 0.10,
        "Administrador": 0.79
      }
    }
  }
}
O plano de tarifas associado tem uma tarifa barcode de 0.00% para PIX (as tarifas de PIX do adquirente são configuradas por uma alíquota fixa de PIX, neste caso 0,79%, exposta via a entrada Administrador acima em vez da tabela de tarifas do adquirente). A busca segue:
1

Normalizar a chave

A busca para ('pix', '1', None) é reescrita para ('debit', '1', 'PIX') e ignora is_online.
2

Encontrar o bucket

Retorna {"Agente": 0.50, "Distribuidor N1": 0.30, "Programador": 0.10, "Administrador": 0.79}.
3

Calcular os valores por destinatário

O auto-split multiplica cada percentual pelo valor da transação.
O resultado:
Destinatário%Valor (BRL)Observações
Agente (a conta de agente vinculada ao Split deste vendedor)0,50%0,50
Distribuidor N10,30%0,30
Programador → conta fixa de desenvolvedor0,10%0,10Sujeito ao piso do automatic_developer_fee.
Administrador → conta administrativa da plataforma0,79%0,79Sempre aponta para a conta administrativa da plataforma para split.
Vendedor recebe o restante98,31Implícito — o adquirente credita ao vendedor tudo que não for reivindicado por uma regra de split.
O job de auto-split arredonda cada valor para 2 casas decimais e substitui qualquer zero por R$ 0,01 para garantir que o adquirente aceite a regra de split. Um mecanismo de proteção é acionado quando o MDR (soma dos splits + tarifas do adquirente) excede o valor da transação: o maior split é reduzido até o total caber. Esse evento é registrado no campo auto_split_error da transação.

Sobrescritas por transação

Não existe um botão de sobrescrita na requisição de criação da transação. O split plan é resolvido inteiramente a partir da conta recebedora:
account_split = account.split
try:
    receiver = transaction.receiver_account
    if receiver and receiver.split and receiver.split.plan:
        account_split = receiver.split
except:
    pass
plan = account_split.plan
Dois pontos a notar:
  • Se a transação unificada tem um receiver_account distinto do acquirer_account (um redirecionamento de Ponto de Venda, por exemplo) e esse recebedor tem seu próprio split configurado, o split do recebedor prevalece. Caso contrário, é usado o split da conta do adquirente.
  • Após o fato, ainda é possível adicionar ou remover regras de split manualmente no adquirente usando Permissão de split na transação — métodos no registro unificado encaminham para os métodos correspondentes do registro específico, que conversam com /transactions/{id}/split_rules. Essas operações são reservadas a administradores (permissão split_transaction).
Se você precisa de uma taxa de comissão por checkout, o caminho canônico é redirecionar o comprador por uma subconta cujo Split carregue o plano desejado.

Edição de splits

Split plans são templates mutáveis — podem ser alterados via:
PATCH /plans/splits/{id}/
Veja Atualizar split plan. Os campos que você pode alterar via o serializer de criação são name, zoop_tax_plan, split_details e split_details_online. Para alternar automatic_developer_fee, vá pelo formulário do painel administrativo ou exponha o campo explicitamente no serializer de criação. O que propaga e o que não propaga:
MudançaTransações existentesTransações novas
Editar split_details / split_details_onlineSem efeito. As regras de split são enviadas ao adquirente no momento da captura e armazenadas como linhas SplitRule vinculadas à transação. Elas não são recalculadas depois.Aplicadas a partir da próxima captura.
Trocar Split.plan em uma contaSem efeito sobre transações já capturadas.Aplicado a partir da próxima captura.
Trocar is_system_managed para falseSem efeito — regras já enviadas permanecem no adquirente.Novas capturas são marcadas como ALREADY_PROCESSED e nenhuma regra de split é enviada, mas a plataforma ainda registra o MDR hipotético para relatórios.
Trocar agent / n1_distributor / n2_distributorSem efeito sobre recebíveis existentes.Roteados para o novo destinatário.
Trocar redirect_sales_toSem efeito sobre transações já capturadas.A cota do vendedor em novas capturas é redirecionada.
Se você realmente precisa retro-corrigir os splits de uma transação existente, use os endpoints administrativos por transação (criar/remover split) — essa é a saída manual suportada.

Referência de status do auto-split

Toda transação unificada mantém um auto_split_status para auditar o resultado da aplicação do split:
StatusSignificado
WAITINGEnfileirado; o job em segundo plano ainda não rodou.
PROCESSINGO job está processando esta transação no momento.
CREATEDSplits enviados ao adquirente com sucesso.
ALREADY_EXISTENTA transação já tinha regras de split equivalentes; nada a criar.
ALREADY_PROCESSEDO split da conta não é gerenciado pelo sistema; o MDR foi calculado, mas nada foi enviado.
NOT_SUPPORTEDO adquirente não suporta splits. Nenhuma ação tomada.
NO_SPLIT_PLANA conta não tem Split ou o Split.plan está vazio. Nenhuma ação tomada.
ERRORPelo menos um envio ao adquirente falhou; detalhes em auto_split_error. Tenta novamente até 15 vezes.
Os splits são executados via um comando de longa duração que varre as linhas em WAITING e também podem ser disparados sob demanda para transações individuais.

Páginas relacionadas

Fluxo de transação

O ciclo de vida que produz as transações sobre as quais esses splits são aplicados.

Contas unificadas

As contas que carregam a linha Split e atuam como agente / distribuidor / desenvolvedor / administrador.

Simular tarifas

Cote o preço para comprador e vendedor para qualquer valor, detalhado por parcelas e bandeira.

API de split plans

Crie, edite e exclua registros de SplitPlan.