Skip to content

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 hora
  • DAILY: 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:

  1. Webhook enviado para a conta principal
  2. 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()
  }
});

Próximos Passos

Documentação da API DiviPay