Sub-contas
Sistema de sub-contas para marketplaces e plataformas com split automático de pagamentos.
O que são Sub-contas?
Sub-contas permitem que você crie contas vinculadas à sua conta principal, ideal para:
- Marketplaces: Cada vendedor tem sua própria sub-conta
- Plataformas SaaS: Cada cliente tem controle de seu saldo
- Agregadores: Gerencie múltiplos negócios em uma única integração
Benefícios
- ✅ Split automático de pagamentos
- ✅ Saldo isolado por sub-conta
- ✅ Saques independentes
- ✅ Webhooks individuais
- ✅ Bloqueio de saldo
- ✅ Relatórios separados
Fluxo de Funcionamento
mermaid
sequenceDiagram
participant P as Plataforma
participant API as DiviPay API
participant V as Vendedor
participant C as Comprador
P->>API: 1. Criar Sub-conta
API->>P: customerId
P->>API: 2. Criar Cobrança (com customerId)
API->>P: QR Code
C->>API: 3. Pagar
API->>API: 4. Split Automático
API->>P: 5. Webhook (conta principal)
API->>V: 6. Webhook (sub-conta)Criando uma Sub-conta
Pessoa Física
bash
curl -X POST https://api.divipay.com.br/api/customer \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "João Silva",
"document": "12345678901",
"email": "joao@email.com",
"phone": "11999999999",
"initDate": "1990-01-15",
"webhookUrl": "https://vendedor.com/webhook",
"address": {
"street": "Rua das Flores",
"streetNumber": "123",
"complement": "Apto 45",
"neighborhood": "Centro",
"cep": "01234567"
}
}'Pessoa Jurídica
bash
curl -X POST https://api.divipay.com.br/api/customer \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Empresa LTDA",
"document": "12345678000190",
"email": "contato@empresa.com",
"phone": "11999999999",
"initDate": "2020-01-15",
"webhookUrl": "https://empresa.com/webhook",
"address": {
"street": "Av. Paulista",
"streetNumber": "1000",
"complement": "Sala 10",
"neighborhood": "Bela Vista",
"cep": "01310100"
},
"responsable": {
"name": "Maria Santos",
"document": "98765432100",
"phone": "11988888888",
"birthDate": "1985-05-20",
"email": "maria@empresa.com",
"address": {
"street": "Rua das Acácias",
"streetNumber": "456",
"complement": "Casa",
"neighborhood": "Jardim",
"cep": "04567890"
}
}
}'Resposta:
json
{
"id": "sub_abc123xyz",
"success": true
}Split de Pagamento
Split Simples
Ao criar uma cobrança, informe o customerId e a taxa:
javascript
{
"customerId": "sub_abc123xyz",
"fee": "10.00",
"amount": 100.00,
// ... outros campos
}Resultado:
- R$ 10,00 → Conta principal (sua comissão)
- R$ 90,00 → Sub-conta (vendedor)
Split Inverso
Use valor negativo para inverter:
javascript
{
"customerId": "sub_abc123xyz",
"fee": "-10.00",
"amount": 100.00
}Resultado:
- R$ 90,00 → Conta principal
- R$ 10,00 → Sub-conta
Split por Item
Configure taxa percentual por item:
javascript
{
"customerId": "sub_abc123xyz",
"itens": [
{
"name": "Produto A",
"quantity": 1,
"unitPrice": 100.00,
"feePercent": 10.0 // 10% de comissão
}
]
}Resultado:
- R$ 10,00 → Conta principal (10% de R$ 100)
- R$ 90,00 → Sub-conta
Gerenciando Sub-contas
Consultar Sub-conta
bash
curl -X GET https://api.divipay.com.br/api/customer/{customerId} \
-H "Authorization: Bearer SEU_TOKEN"Resposta:
json
{
"id": "sub_abc123xyz",
"name": "João Silva",
"email": "joao@email.com",
"document": "12345678901",
"phone": "11999999999",
"balance": 1500.00,
"blockedBalance": 0.00,
"status": 1,
"taxes": [
{
"id": "tax_pix",
"name": "Pix",
"percent": 0.99
}
]
}Atualizar Sub-conta
bash
curl -X PUT https://api.divipay.com.br/api/customer/{customerId} \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "João Silva Santos",
"email": "joao.novo@email.com",
"phone": "11988888888"
}'Bloqueio de Saldo
Bloqueie parte do saldo da sub-conta (útil para garantias):
Bloquear Saldo
bash
curl -X POST https://api.divipay.com.br/api/customer/{customerId}/blocks \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": 100.00
}'Desbloquear Saldo
Use valor negativo:
bash
curl -X POST https://api.divipay.com.br/api/customer/{customerId}/blocks \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"amount": -100.00
}'Consultar Bloqueios
bash
curl -X GET https://api.divipay.com.br/api/customer/{customerId}/blocks \
-H "Authorization: Bearer SEU_TOKEN"Saque Automático
Configure saques automáticos para sub-contas:
Saque via Chave Pix
bash
curl -X POST https://api.divipay.com.br/api/customer/{customerId}/account \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "DICT",
"keyPix": "joao@email.com",
"periodType": "DAILY",
"days": [1, 15]
}'Períodos disponíveis:
HOURLY: A cada horaDAILY: Dias específicos do mês (1-31)WEEKLY: Dias da semana (0=Domingo, 6=Sábado)MONTHLY: Uma vez por mês
Saque via Dados Bancários
bash
curl -X POST https://api.divipay.com.br/api/customer/{customerId}/account \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "MANU",
"accountHolderDocument": "12345678901",
"accountHolderName": "João Silva",
"account": "12345",
"accountType": "CC",
"agency": "0001",
"ispb": "00000000",
"periodType": "WEEKLY",
"days": [1, 5]
}'Webhooks de Sub-contas
Configure webhook individual para cada sub-conta:
bash
curl -X PUT https://api.divipay.com.br/api/customer/{customerId}/webhook \
-H "Authorization: Bearer SEU_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://vendedor.com/webhook"
}'Quando um pagamento for confirmado:
- Webhook enviado para a conta principal
- Webhook enviado para a sub-conta (se configurado)
Exemplo Completo: Marketplace
javascript
class MarketplaceIntegration {
constructor(token) {
this.token = token;
this.apiUrl = 'https://api.divipay.com.br';
}
// 1. Criar vendedor
async createSeller(seller) {
const response = await fetch(`${this.apiUrl}/api/customer`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: seller.name,
document: seller.cpf,
email: seller.email,
phone: seller.phone,
initDate: seller.birthDate,
webhookUrl: `${process.env.BASE_URL}/webhook/seller/${seller.id}`,
address: seller.address
})
});
const data = await response.json();
// Salvar customerId no banco
await db.sellers.update({
where: { id: seller.id },
data: { diviPayCustomerId: data.id }
});
return data.id;
}
// 2. Criar venda com split
async createSale(sale) {
const seller = await db.sellers.findUnique({
where: { id: sale.sellerId }
});
const marketplaceFee = sale.total * 0.10; // 10% de comissão
const response = await fetch(`${this.apiUrl}/api/charge/pix`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
customerId: seller.diviPayCustomerId,
fee: marketplaceFee.toFixed(2),
amount: sale.total,
description: `Pedido #${sale.id}`,
referenceId: sale.id,
callbackUrl: `${process.env.BASE_URL}/webhook/sale`,
expirationSeconds: 3600,
client: {
name: sale.customer.name,
document: sale.customer.cpf,
email: sale.customer.email,
phone: sale.customer.phone,
ip: sale.customer.ip
},
itens: sale.items.map(item => ({
name: item.name,
quantity: item.quantity,
unitPrice: item.price,
feePercent: 10.0 // 10% por item
}))
})
});
return await response.json();
}
// 3. Processar webhook
async handleWebhook(event) {
if (event.event === 'charge.paid') {
const sale = await db.sales.findUnique({
where: { id: event.referenceId }
});
// Atualizar venda
await db.sales.update({
where: { id: sale.id },
data: {
status: 'PAID',
paidAt: event.paidAt
}
});
// Notificar vendedor
await this.notifySeller(sale.sellerId, event);
// Processar pedido
await this.processOrder(sale.id);
}
}
}Boas Práticas
1. Validação de Documentos
Valide CPF/CNPJ antes de criar sub-contas:
javascript
function validateCPF(cpf) {
cpf = cpf.replace(/[^\d]/g, '');
if (cpf.length !== 11) return false;
// Implementar validação completa
return true;
}2. Gestão de Saldos
Monitore saldos das sub-contas:
javascript
async function checkSellerBalance(customerId) {
const customer = await getCustomer(customerId);
if (customer.balance < 100) {
await notifyLowBalance(customer);
}
}3. Auditoria
Mantenha log de todas as operações:
javascript
await db.auditLog.create({
data: {
action: 'CREATE_SUBACCOUNT',
customerId: data.id,
userId: req.user.id,
timestamp: new Date()
}
});