Split de pagamentos
Referência
Split divide automaticamente o valor de uma cobrança Pix entre a conta que a criou e outras contas ValidaPay, no momento em que o pagamento é confirmado. Este guia explica os dois modelos de split, os campos de uma regra, como o valor é calculado e limitado, e quando a transferência de fato acontece.
POST /v1/charges/pix e GET /v1/charges/:chargeId. O que muda é o array split no corpo e o header X-Sub-Account.Duas rotas já conhecidas
Cobrança imediata com split e Split para Conta Master são as duas variações de POST /v1/charges/pix (escopo charges/write). Status de cobrança com split é a mesma GET /v1/charges/:chargeId (escopo charges/read) do grupo Pix, só que aplicada a uma cobrança que tem split.
Os dois modelos de split
| Modelo | Onde a cobrança nasce | Como configurar |
|---|---|---|
| Master divide com parceiros | Conta master (sem X-Sub-Account) | Array split com accountNumber de cada recebedor |
| Seller divide com a master | Subconta, header X-Sub-Account | Array split sem accountNumber: a parcela cai automaticamente na master que autenticou a chamada |
Master divide com parceiros (Cobrança imediata com split): a cobrança nasce na sua conta e a regra informa a conta de cada parceiro.
Seller divide com a master (Split para Conta Master): você envia o header X-Sub-Account com o número da subconta do seller, e a cobrança nasce nela. Como a regra do split não informa accountNumber, a API resolve automaticamente para a sua conta master.
Master divide com parceiros
{
"amount": 1.00,
"externalTxid": "loja-01-caixa-03",
"split": [
{ "type": "fixed", "accountNumber": "896532569", "amount": 0.10 },
{ "type": "fixed", "accountNumber": "125485692", "amount": 0.10 }
]
}Seller divide com a master (com X-Sub-Account)
{
"amount": 1.00,
"externalTxid": "loja-01-caixa-03",
"split": [
{ "type": "fixed", "amount": 0.10 }
]
}Campos de uma regra de split
| Campo | Obrigatório | Descrição |
|---|---|---|
type | Sim | "fixed" ou "percentage", sempre em minúsculo. |
amount | Sim | Valor em reais quando fixed; percentual de 0 a 100 quando percentage. Sempre positivo. |
accountNumber | Condicional | Conta do recebedor. Omitido no modelo "seller para a master" (ver acima). |
- •Informe
accountNumber. No modelo "seller para a master", deixe de fora: a API preenche com a master do token. - •Máximo de 20 recebedores por cobrança.
- •A soma dos splits do tipo
percentagenão pode passar de 100%. - •A mesma conta não pode aparecer em duas regras do mesmo split.
Cálculo e limite do split
- •Uma regra
percentageé sempre calculada sobre o valor bruto da cobrança (amount), nunca sobre o valor líquido. - •Uma regra
fixedusa exatamente o valor informado. - •A soma de todas as regras já resolvidas não pode passar do valor líquido da cobrança (valor bruto menos a taxa Pix da conta). Se a conta tiver crédito de taxa suficiente, o limite passa a ser o próprio valor bruto.
- •Passar do limite retorna
400 SPLIT_EXCEEDS_NET_AMOUNT, com os dois valores já calculados na mensagem.
{
"error": {
"message": "O valor dos splits (R$12.00) excede o valor líquido da cobrança (R$9.80)",
"code": "SPLIT_EXCEEDS_NET_AMOUNT",
"details": null,
"timestamp": "2026-02-18T22:19:31.013Z"
}
}Quando o dinheiro é transferido
Criar a cobrança só registra as regras do split; nenhuma transferência acontece nesse momento. O dinheiro só se move quando o Pix é efetivamente pago: nesse instante, a ValidaPay calcula o valor de cada regra sobre o valor bruto, credita cada recebedor (categoria SPLIT_IN no extrato dele) e credita o restante, já descontadas taxa e splits, na conta que gerou a cobrança (categoria PAYMENT).
splitRules[].error, e o split como um todo fica PARTIAL (nenhuma regra passou) ou FAILED (nenhuma regra deu certo) na consulta de status.Consultando uma cobrança com split
O mesmo GET /v1/charges/:chargeId de Pix traz, quando a cobrança tem split, o objeto splitscom o resultado de cada regra. Quando a cobrança nasceu numa subconta (modelo "seller para a master"), a resposta também traz accountId (a subconta dona da cobrança) e masterAccountId (a master dela):
{
"chargeId": "cha_1774539002481_sp1itxk9a",
"status": "PAID",
"amount": 1.00,
"paymentType": "PIX",
"accountId": "896532569",
"masterAccountId": "428965347",
"emv": "00020101021226910014br.gov.bcb.pix2569qrcode.pix.celcoin.com.br/pixqrcode/v2/77e66fbad26b0b294eeb56c7c7c29f5204000053039865802BR5909ValidaPix6013Florianopolis62070503***6304BA13",
"paidAt": "2026-02-18T22:22:50.031Z",
"createdAt": "2026-02-18T22:19:31.013Z",
"splits": {
"id": "spl_1774539002481_a1b2c3d4e",
"chargeId": "cha_1774539002481_sp1itxk9a",
"splitRules": [
{
"type": "fixed",
"amount": 0.10,
"accountNumber": "428965347",
"paidAmount": 0.10,
"paidAt": "2026-02-18T22:22:51.203Z",
"error": null
}
],
"createdAt": "2026-02-18T22:19:31.013Z",
"updatedAt": "2026-02-18T22:22:51.203Z"
}
}A conta master pode consultar diretamente o status de uma cobrança criada em qualquer uma das suas subcontas, sem precisar enviar X-Sub-Account no GET.
Webhooks de confirmação
Não existe um evento próprio para o split. A confirmação do pagamento chega pelo mesmo payment.success de Pix. No modelo "seller para a master" (cobrança com masterAccountId), a ValidaPay dispara payment.success duas vezes: uma para a subconta dona da cobrança, e outra para a conta master, com o campo extra subAccountId identificando a subconta de origem.
Para saber se uma regra específica do split falhou, consulte GET /v1/charges/:chargeId e leia splitRules[].error: essa informação não vai no webhook.
Erros comuns
| code | Status | Quando acontece |
|---|---|---|
INVALID_DATA | 400 | Corpo não passou na validação: type/amount ausente, split percentual acima de 100%, soma dos percentuais acima de 100%, mais de 20 recebedores, ou regra sem accountNumber. |
SPLIT_ACCOUNT_NOT_FOUND | 400 | O accountNumber informado não corresponde a nenhuma conta ValidaPay. |
SPLIT_ACCOUNT_BLOCKED | 400 | Uma das contas de destino do split está bloqueada. |
SPLIT_DUPLICATE_RECIPIENT | 400 | A mesma conta aparece em mais de uma regra do split. |
SPLIT_EXCEEDS_NET_AMOUNT | 400 | A soma das regras (já resolvidas) passa do valor líquido disponível para split. |
NOT_FOUND | 404 | X-Sub-Account aponta para uma subconta que não existe. |
UNAUTHORIZED | 401 | A subconta em X-Sub-Account não pertence à master autenticada. |
NOT_FOUND e UNAUTHORIZED só acontecem no modelo "seller para a master", quando X-Sub-Account aponta para uma subconta inexistente ou que não pertence à master autenticada.