O módulo uniconta é o sistema de carteira da plataforma. Ele não fala com uma rede de adquirência para autorizar um cartão — ele fica um nível acima, acompanhando, por vendedor, o dinheiro que já entrou em uma conta bancária administrada pela DL Pay. O saldo bancário é real (mantido em um parceiro bancário externo); os saldos por vendedor sobre ele são virtuais. Este guia descreve o caminho principal — o fluxo diário que uma integração de vendedor segue: provisionar uma conta virtual, ler o saldo, movimentar dinheiro para fora e, depois, inspecionar o livro contábil.

O que é uma conta virtual

Uma conta virtual é um sublivro contábil vinculado a uma conta unificada. Ela existe para que a plataforma consiga responder “quanto deste saldo bancário pertence ao vendedor X?” sem precisar abrir uma conta bancária separada por vendedor. O dinheiro entra (quando um recebível é pago, quando um depósito chega) e sai (quando o vendedor paga um boleto, transfere para um terceiro ou move valores entre contas virtuais). Cada movimentação é um lançamento — uma linha do livro contábil, imutável em espírito, com kind=IN ou kind=OUT. Contas virtuais existem apenas para subcontas. A conta pai (master) é a entidade pública que mantém a relação com o banco — seu dinheiro é o próprio saldo bancário real. Subcontas são as carteiras dos vendedores, e cada subconta possui exatamente uma conta virtual principal, cujo id é igual ao id da subconta.
Todos os valores são inteiros em centavos de BRL. 15000 significa R$ 150,00.

Os atores

AtorO que éOnde vive
Conta administradaEntidade administrativa de nível plataforma, representando uma relação bancária com um parceiro externo. Detém as configurações de notificação e a flag de automação.módulo uniconta
Conta unificada (pai)A conta master cujo saldo bancário é compartilhado por todas as suas subcontas.módulo unified
Conta unificada (subconta)Uma carteira de vendedor. Precisa ter is_sub_account=True.módulo unified
Conta virtualO próprio sublivro contábil. Seu balance é calculado a partir dos lançamentos.módulo uniconta
LançamentoUma linha do livro contábil. IN ou OUT. Vinculada a um recebível, a um pagamento ou a uma transferência via campo source.módulo uniconta
TransferênciaDetalhe de uma saída via TED/PIX/transferência interna.módulo uniconta
PagamentoDetalhe de um pagamento de boleto.módulo uniconta

Provisionamento automático

Não existe endpoint POST para criar uma conta virtual. A linha é criada na primeira leitura. Quando o painel ou uma integração chama:
GET /uniconta/seller/{account_id}/virtualaccounts/{account_id}/
com o mesmo id tanto no caminho do vendedor quanto no pk do detalhe, a view dispara o provisionamento automático. Esse fluxo:
  1. Garante que account.is_sub_account seja verdadeiro; caso contrário, devolve um erro 400 informando que a conta não é uma subconta.
  2. Localiza a conta administrada da conta pai e a vincula.
  3. Cria uma conta virtual cujo id é idêntico ao id da subconta. É idempotente — chamadas subsequentes retornam a linha existente e só preenchem o vínculo administrado caso esteja faltando.
O endpoint de lista nunca provisiona; apenas o de detalhe. A chamada de “criação” mais simples é, portanto, um GET.
Contas que não são subcontas (a master) não podem ter conta virtual. Chamar o caminho de provisionamento automático em uma master retorna 400 indicando que a conta não é subconta.

Saldo, calculado a partir do livro contábil

Uma conta virtual não tem uma coluna de saldo armazenada. Ele é sempre recalculado:
balance = SUM(entries IN, PAID)
        − SUM(entries OUT, PAID)
        − SUM(entries OUT, WAITING_CONFIRMATION)
É por isso que uma transferência iniciada, mas ainda não confirmada pelo banco (WAITING_CONFIRMATION), já é deduzida do saldo disponível — o vendedor não pode gastar duas vezes o mesmo dinheiro enquanto uma transferência está em curso.

O caminho principal

1

Provisionar e ler

GET …/virtualaccounts/{sub_account_id}/ para provisionar automaticamente e ler o saldo.
2

Movimentar dinheiro

POST …/pay/, POST …/transfer/ ou POST …/deposit/ para empurrar dinheiro para fora ou puxar para dentro. Use GET …/known-transfer-destinations/ para preencher o formulário a partir de TEDs anteriores.
3

Inspecionar o livro contábil

GET …/entries/ para ler as linhas IN/OUT. GET …/entries/{id}/ para detalhar o recebível, o pagamento ou a transferência que produziu o lançamento.

Etapa 1 — Listar as contas virtuais de um vendedor

A view de lista devolve todas as contas virtuais cuja account corresponda ao vendedor. Nenhum saldo é incluído na lista — a linha é leve por design. Use o endpoint de detalhe para ler saldos.
GET /uniconta/seller/{account_id}/virtualaccounts/
Veja listagem de contas virtuais.

Etapa 2 — Ler o saldo

GET /uniconta/seller/{account_id}/virtualaccounts/{id}/
Se id == account_id, a view faz o provisionamento automático da linha antes de serializar (ver Provisionamento automático). O payload inclui balance em centavos. Veja detalhe de conta virtual.

Etapa 3 — Movimentar dinheiro

O viewset expõe quatro ações POST mais um auxiliar GET:
Body: bank_slip_code (linha digitável), target_date (data em que o boleto deve ser pago) e amount (centavos).Cria um lançamento com kind=OUT, source=PAYMENT, status=PLANNED e, em seguida, um registro de pagamento que vincula os dois. A submissão de fato ao banco acontece quando o pagamento é executado — tipicamente por meio de um worker dedicado de execução de transferências ou de uma ação administrativa. Em caso de sucesso, o lançamento passa para WAITING_CONFIRMATION e um webhook do parceiro bancário externo o move depois para PAID, REVERSED ou FAILED.Se a conta administrada tiver BANK_SLIP em notify_on_actions, a requisição também dispara um e-mail para notify_actions_to.
Os campos do body dependem do transfer_type:
  • TED (padrão) — receiver_name, receiver_tax_id, receiver_tax_id_type (PF/PJ), receiver_bank (código de 3 dígitos), receiver_agency, receiver_account, receiver_account_type (CHECKING_ACCOUNT/SAVINGS_ACCOUNT), target_date, amount. Cria um registro de transferência e um lançamento OUT. A submissão ao banco é feita ao executar a transferência e, depois, confirmada por webhook.
  • PIXreceiver_name, receiver_tax_id, pix_key, pix_key_type (CPF/CNPJ/EMAIL/PHONE/RANDOM), target_date, amount. Mesmo padrão contábil do TED, mas o trilho bancário é o PIX.
  • BETWEEN_ACCOUNTSdestination_account (id de outra conta virtual), amount. É o único fluxo que efetiva de forma atômica: a requisição valida se a origem tem saldo suficiente, depois grava dois lançamentos (OUT na origem, IN no destino) e um único registro de transferência dentro de uma transação de banco com status=PAID. Sem chamada ao banco. Sem webhook.
A validação rejeita a requisição se faltarem campos obrigatórios para o transfer_type escolhido.
Body: amount (decimal em reais, mínimo 0.01) e name (rótulo, no máximo 32 caracteres).Cria uma venda online avulsa (a primitiva de checkout do vendedor) sob um plano oculto chamado PIX Only - Uniconta, com cartão de crédito e boleto desabilitados. Retorna { "id": "<online_sell_id>" }. O vendedor então compartilha a URL de checkout resultante com quem deve pagar; quando o pagamento é liquidado, o pipeline normal de recebíveis registra um lançamento IN na conta virtual (veja Reconciliação).Use quando o vendedor quiser depositar valores na conta virtual a partir de uma origem externa.
Retorna os 10 destinos de TED mais usados desta conta virtual, calculados a partir de todos os registros de transferência com status=PAID e transfer_type=TED, agrupados por (receiver_bank, receiver_agency, receiver_account). Cada item traz usage_count, last_used_at e os campos do destinatário necessários para montar um body de POST .../transfer/.Use para alimentar uma UI de “destinatários recentes”; não há validação contra o banco de destino — é apenas uma busca por frequência baseada em transferências bem-sucedidas anteriores.

Etapa 4 — Inspecionar lançamentos

GET /uniconta/seller/{account_id}/virtualaccounts/{virtualaccounts_pk}/entries/
Lista de lançamentos do mais novo para o mais antigo, com CANCELED e PREDICTED filtrados (esses status são ruído contábil — a plataforma escreve linhas PREDICTED para recebíveis que ainda não foram pagos; ficam visíveis pelo id, mas não na lista). Cada lançamento carrega:
CampoSignificado
kindIN (crédito) ou OUT (débito).
amountCentavos, sempre positivo. O sinal é dado por kind.
statusPLANNED, SCHEDULED, PAID, WAITING_CONFIRMATION, REVERSED, FAILED, além dos filtrados CANCELED / PREDICTED.
status_reasonTexto livre com o motivo em falhas terminais (por exemplo, "Saldo insuficiente").
nameRótulo legível, por exemplo "PIX para Ada Lovelace", "Venda de 3 ingresso(s) para SomeEvent".
O endpoint de detalhe adiciona três objetos aninhados — somente um deles é preenchido, conforme o source do lançamento:
sourceObjeto aninhado preenchidoO que é
RECEIVABLEreceivableO recebível unificado de origem (dinheiro entrando das vendas).
PAYMENTpaymentO registro do pagamento (detalhe do boleto).
TRANSFERtransferO registro da transferência (detalhe TED/PIX/BETWEEN_ACCOUNTS).
Veja lista de lançamentos e detalhe de lançamento. Há também uma ação de exportação sob o endpoint de lista: GET …/entries/report/ retorna até 1000 linhas em CSV / XLSX / TXT (o formato é selecionado pelo cabeçalho Accept).

Reconciliação

A reconciliação tem duas metades — colocar dinheiro dentro de uma conta virtual e confirmar dinheiro saindo. Entradas (recebíveis → lançamentos IN). Quando o pipeline unificado atualiza um recebível pertencente a uma subconta, ele dispara um job de sincronização do lançamento. O job:
  1. Mapeia o status do recebível para o status do lançamento (paidPAID, pending/scheduledPREDICTED, deletedCANCELED, refundedREVERSED).
  2. Se já existe um lançamento para aquele recebível, atualiza o status.
  3. Caso contrário, provisiona a conta virtual, monta um name amigável (rótulo de venda de ingressos, rótulo do checkout, dados da parcela) e escreve um novo lançamento IN com source=RECEIVABLE.
Isso mantém o livro contábil virtual eventualmente consistente com os recebíveis unificados. Um comando de auditoria percorre toda a cadeia (recebível em sales → recebível unificado → lançamento) para uma conta e reporta divergências. Saídas (transferências/pagamentos → confirmação bancária). Transferências e pagamentos de boleto não vão para PAID de forma síncrona. O fluxo é:
  1. A API grava um lançamento PLANNED e os respectivos registros de transferência / pagamento.
  2. Um processo em segundo plano (ou uma ação administrativa manual) executa a operação, submetendo-a ao parceiro bancário externo. Em uma resposta 2xx, o lançamento transita para WAITING_CONFIRMATION e um external_id é armazenado.
  3. O parceiro bancário envia um webhook de volta ao listener do módulo. Com base no eventType (payment.COMPLETED, transfer.REFUNDED, payment.CANCELED, …) o listener marca o registro e o lançamento como pago, estornado ou cancelado.
Transferências BETWEEN_ACCOUNTS não passam por isso — são efetivadas atomicamente dentro de uma transação de banco e nunca entram em WAITING_CONFIRMATION. Verificação de saldo total. Operadores administrativos podem comparar a soma de todos os saldos virtuais com o saldo bancário real:
GET /uniconta/admin/managed-accounts/total-balance/
A resposta traz a soma dos saldos virtuais (em centavos) ao lado do saldo bancário externo de referência. Divergências entre os dois sinalizam que a reconciliação está quebrada em algum ponto.

Operações administrativas

Superusuários gerenciam contas administradas e inspecionam todas as contas virtuais por meio de endpoints dedicados sob /uniconta/admin/. O viewset não administrativo é somente leitura; o administrativo adiciona atualização, métricas e relatórios.
  • Lista admin de contas administradas, detalhe, criação.
  • Lista admin de contas virtuais — todas as contas virtuais sob uma conta administrada, com balance e a identidade do vendedor vinculada.
  • GET /uniconta/admin/managed-accounts/total-balance/ — soma dos saldos virtuais contra o saldo bancário real.
  • GET /uniconta/admin/managed-accounts/{id}/metrics/ — contagens de transferências e boletos agrupadas por status, mais o saldo agregado daquela conta administrada.
  • POST /uniconta/admin/managed-accounts/{id}/export-report/ — body { "statuses": ["PLANNED", ...] }. Gera um relatório .xlsm (Excel com macros) de boletos e TEDs no formato esperado pelo parceiro bancário externo, pronto para upload no portal corporativo.
A flag de automação na conta administrada controla se o worker de execução pode disparar operações de saída automaticamente; defini-la como false mantém tudo em PLANNED até que um operador atue.

Exemplo de ponta a ponta

Um backend de vendedor recupera a conta virtual do vendedor, transfere R$ 100,00 para uma conta virtual irmã e, em seguida, lista os lançamentos resultantes.
ACCOUNT_ID="9c2a1f3e-7d8b-4a1c-9f2e-0b6a5d4c1e10"
DEST_ID="1d3b8a2c-4e5f-4a91-8b22-77c91e0d9aaa"
TOKEN="eyJ0eXAiOiJKV1QiLCJh..."

curl -s "https://api.dlpay.cloud/uniconta/seller/$ACCOUNT_ID/virtualaccounts/$ACCOUNT_ID/" \
  -H "Authorization: Bearer $TOKEN"

curl -s -X POST "https://api.dlpay.cloud/uniconta/seller/$ACCOUNT_ID/virtualaccounts/$ACCOUNT_ID/transfer/" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"transfer_type\": \"BETWEEN_ACCOUNTS\",
    \"destination_account\": \"$DEST_ID\",
    \"amount\": 10000
  }"

curl -s "https://api.dlpay.cloud/uniconta/seller/$ACCOUNT_ID/virtualaccounts/$ACCOUNT_ID/entries/" \
  -H "Authorization: Bearer $TOKEN"
Após a transferência, o livro contábil de origem ganha um novo lançamento OUT com source=TRANSFER e status=PAID, e o livro contábil de destino ganha um lançamento espelho IN com status=PAID. Ambos apontam para o mesmo registro de transferência.

Armadilhas

Sem criação direta. O viewset de contas virtuais só expõe detalhe e lista. POST /uniconta/seller/{id}/virtualaccounts/ retorna 405 Method Not Allowed. A única forma de materializar uma conta virtual é fazer GET …/virtualaccounts/{sub_account_id}/.
Apenas subcontas. O provisionamento automático verifica account.is_sub_account. Se a conta for a master, é devolvido um erro 400 indicando que a conta não é subconta. Contas master não têm conta virtual porque seu saldo é o próprio saldo bancário real.
O saldo inclui saídas pendentes. Saídas em WAITING_CONFIRMATION são subtraídas do saldo. Uma transferência em curso não pode ser gasta novamente. Se posteriormente falhar e o lançamento for para FAILED, o saldo é automaticamente restaurado (já que FAILED deixa de contar).
O tipo do lançamento importa. Ao ler o payload de detalhe, apenas um entre receivable, payment e transfer estará preenchido — o que corresponder ao source do lançamento. Faça branch em source (ou verifique qual objeto aninhado está não nulo) antes de aprofundar.
BETWEEN_ACCOUNTS valida saldo; TED/PIX não. Uma transferência interna é rejeitada já na API com 400 Saldo insuficiente se a origem não tiver saldo. Uma requisição TED ou PIX é aceita; a verificação de saldo acontece depois, na execução, momento em que o lançamento transita para FAILED com status_reason="Saldo insuficiente". UIs devem pré-checar o saldo para TED/PIX.
A ação deposit não credita a conta diretamente. Ela cria um link de venda online que o pagador precisa concluir. O lançamento IN só aparece quando o recebível resultante é pago e o job de sincronização é executado.

Onde ir em seguida

Modelo de dados unificado

Como recebíveis se tornam lançamentos IN nas contas virtuais.

Webhooks e jobs

O mecanismo que move lançamentos de WAITING_CONFIRMATION para PAID.

Referência da API Uniconta

Todos os endpoints expostos pelo módulo uniconta.

Autenticação e acesso

Acesso legado, permissões de superusuário e o que cada viewset verifica.