sales como verdade específica do adquirente, e uma vez no módulo unified como espelho agnóstico do adquirente. Toda visão do painel, todo relatório e todo consumidor externo da API leem da camada unificada. Esta página explica por que essa divisão existe, o que cada camada guarda e como os dados fluem entre elas.
Por que uma camada unificada
A plataforma integra diferentes parceiros de processamento. Cada um deles tem formatos próprios, ciclos de vida distintos, identificadores e particularidades. Duas consequências se seguem:- Se cada interface e relatório consultasse tabelas específicas de cada parceiro, precisaria conhecer cada uma delas. Adicionar um novo parceiro exigiria reescrever cada caminho de leitura.
- Parte dos dados — contas, splits, comissões, métricas — é nossa. Existe independentemente de qual rede liquidou um dado pagamento.
sales (quando o dado originou-se na adquirência).
sales conversa com os parceiros de processamento; o módulo unified conversa com o seu painel e com seus consumidores de API.As duas metades do modelo de dados
Modelos sales (camada de adquirência)
O módulo sales mantém a verdade específica do adquirente. Os registros espelham o que existe no parceiro de processamento usando um identificador externo como chave única. Exemplos:
sales.Transaction— uma linha por transação no parceiro, com o conjunto completo de campos retornados (taxas, pré-autorização, valor original etc.).sales.Receivable,sales.SplitRule,sales.Document,sales.PaymentMethod,sales.PaymentAuthorization, modelos de transferência e de ponto de venda.
sales possui um método de atualização que cria ou atualiza sua contraparte unificada.
Modelos unified (camada agnóstica)
Cada modelo unificado que se origina de um parceiro de processamento estende uma base abstrata comum que adiciona quatro campos:
Account, Transaction, Receivable, AccountDeposit, AccountDepositTransactions, AccountDepositDestination, Document, PointOfSale, TokenizedCard. Somam-se a eles modelos que são puramente nossos (sem contraparte na adquirência): Split, InvitationLink, Person, Company, BankAccount e todas as tabelas de métricas.
O mapeamento na prática
Fluxo de dados: adquirente → sales → unified
Esse é o caminho mais comum. Um webhook chega, a plataforma busca o estado autoritativo no parceiro, persiste o registrosales e projeta para a camada unificada.
Os passos-chave:
Webhook persistido, ouvinte invocado
ReceivedWebhookCall e despachado para todos os ouvintes registrados. Hoje o ouvinte relevante é o despachante da camada de transações.O ouvinte enfileira um job da camada sales
event['type'] e chama o auxiliar de enfileiramento correspondente. Para eventos de transação é o equivalente a fetch_transaction com execução imediata. Para recebíveis é fetch_receivables. Para transferências, update_transfer. Para eventos de lojista, documento e conta bancária, equivalentes.O job sales busca no parceiro
sales.Transaction indexada pelo identificador externo. Registros retornados pelo parceiro sobrescrevem campos locais; registros não retornados durante uma sincronização completa são tipicamente removidos da tabela sales (veja Limpeza de dados obsoletos).A persistência do modelo sales dispara a atualização unificada
sales.Transaction.save() verifica os indicadores de controle (skip_unified, sync_with_zoop). Se nenhum estiver ativo, dispara update_unified_transaction_job e fetch_receivables. Portanto a persistência é o que faz o trabalho se ramificar.O job unificado atualiza a contraparte
sales e invoca o método de atualização. Esse método procura a unified.Transaction existente pelo identificador externo ou cria uma nova, e então copia os campos normalizados (valor, status, tipo de pagamento, bandeira do cartão etc.). Também resolve receiver_account e acquirer_account através da conta unificada do lojista.Métricas e webhooks de saída são atualizados
SalesByDate, ProductByDate etc.) com expressões atômicas para evitar condições de corrida. Em seguida, a rotina de despacho envia a transação serializada via POST para cada webhook de saída registrado pelo lojista.Fluxo de dados: plataforma → adquirente (uploads)
Quando o dado nasce na plataforma (upload de documento, criação de conta, recebível manual), a ordem se inverte:Escreve primeiro no unificado
unified.Document) com o arquivo armazenado em nuvem e o status reportado como UNDEFINED.Enfileira um job da camada sales
upload_document). O job baixa o arquivo do armazenamento em nuvem e o envia ao parceiro de processamento.Registro sales é criado em caso de sucesso
sales.Document indexado pelo novo identificador externo retornado, invoca a atualização da contraparte unificada, e a linha unificada passa a carregar o identificador externo e um status OK.Resolução de contas
A ponte entre a entidade lojista específica (no móduloseller) e a unified.Account agnóstica é o identificador externo do lojista. Modelos sales usam essa resolução sempre que precisam definir a conta receptora ou a conta do adquirente em uma contraparte unificada. O caminho reverso permite recuperar a entidade do lojista a partir do identificador da conta unificada.
Limpeza de dados obsoletos
Quando a plataforma sincroniza a partir do parceiro de processamento, ele é tratado como verdade absoluta:- Registros
salesnão retornados pela API são deletados. - Registros
unifiedsão tratados de forma mais conservadora: apenas linhas que de fato possuem um identificador externo são elegíveis para serem marcadas como obsoletas, e são sinalizadas com status reportado igual aDELETEDem vez de removidas fisicamente. A camada unificada nunca apaga registros com base apenas na ausência de uma contraparte na camada de transações.
Escolhendo de qual camada ler
Leitura de dados
Leitura de dados
unified. Os endpoints de leitura unificados estão aninhados sob /sellers/{sellers_pk}/ e são o que qualquer consumidor da API deve utilizar.Criação de algo que a plataforma é dona (conta, split, link de convite)
Criação de algo que a plataforma é dona (conta, split, link de convite)
unified. A persistência do modelo se encarrega de propagar ao parceiro de processamento quando necessário.Criação de algo no parceiro de processamento (transação, cobrança, upload de documento)
Criação de algo no parceiro de processamento (transação, cobrança, upload de documento)
Account.create_transaction(...)) que delega para a camada sales. O lado sales conversa com o parceiro e depois projeta de volta para o unified.Recuperação após webhook perdido
Recuperação após webhook perdido
sales correspondente (fetch_transaction, fetch_receivables etc.). O caminho de sincronização completa é o mesmo do caminho de webhook — apenas disparado manualmente.O contrato de atualização da contraparte unificada
Todo modelosales que possui uma contraparte unificada implementa esse método. A forma esperada:
- Encerrar cedo se o identificador externo estiver vazio.
- Buscar a linha unificada existente pelo identificador externo; criar uma nova se não houver.
- Definir status reportado, status interno e marca temporal da última atualização.
- Copiar os campos normalizados.
- Resolver as relações (conta receptora, conta do adquirente, transação) através dos auxiliares de resolução por identificador externo.
- Persistir o registro. Se o modelo unificado possui dados derivados próprios (por exemplo, atualização de status de recebível que dispara métricas), deixe essas rotinas seguirem seu fluxo.