💸 Operações Financeiras e Precisão Decimal

Esta página descreve como realizar operações de Pix (depósitos/saques), Transferência Interna, Swap (câmbio) e Cripto (saques blockchain), bem como os cuidados necessários com a formatação de valores.

Atenção à Precisão Decimal (Risco de Perda de Valor!)

Para evitar erros de arredondamento em computadores (erros de ponto flutuante), a DEX API não aceita valores com vírgulas ou pontos.

  • O campo de valor (amount) é sempre uma string.

  • O valor deve ser informado na menor unidade da moeda (equivalente a centavos ou satoshis).

⚠️ Risco Crítico: Enviar o valor em formato humano (ex: "1.0" em vez da menor unidade) pode fazer uma transferência de 1 BTC virar um milionésimo de BTC, ou vice-versa!

Tabela de Conversão

Moeda

Casas Decimais

Exemplo Legível (Humano)

Valor a Enviar na API (amount)

BRL / BRT

2

R$ 500,00

"50000" (cinquenta mil centavos)

BTC

8

0.01 BTC

"1000000" (um milhão de satoshis)

USDT / USDC

6

50.00 USDT

"50000000"

ETH

18

0.5 ETH

"500000000000000000"

Idempotência

Para evitar duplicidade em operações financeiras (ex: o usuário clicar duas vezes, ou seu sistema reenviar automaticamente após um timeout de rede), use o mecanismo de idempotência de cada operação:

Endpoint

Mecanismo

POST /ledger/transfer

Envie um idempotencyKey (UUIDv7) no corpo da requisição. Reenviar a mesma chave retorna a transferência já criada — nunca duplica o débito/crédito.

POST /ledger/crypto/withdraw

Mesmo padrão: campo idempotencyKey obrigatório no corpo.

POST /swap/execute

O próprio quoteId funciona como identificador de uso único — reexecutar a mesma quote nunca duplica a conversão.

POST /pix/deposit, POST /pix/withdraw

A idempotência dessas operações é controlada internamente pela plataforma. Como boa prática, sempre confirme o status pelo GET correspondente (/pix/deposit/{id}/status ou /pix/transactions/{id}) antes de reenviar uma chamada que pareceu falhar por timeout ou erro de rede, em vez de reenviar automaticamente sem checar.

Regra de ouro: gere a chave de idempotência uma vez por operação de negócio, nunca uma nova a cada tentativa de rede. Se a chamada falhar por timeout, reenvie com a mesma chave.

Exemplo de retry seguro (transferência):

import { v7 as uuidv7 } from 'uuid';

async function transferirComRetry(payload: object, tentativas = 3) {
  const idempotencyKey = uuidv7(); // gerado UMA vez, fora do loop de retry

  for (let i = 0; i < tentativas; i++) {
    try {
      const resposta = await fetch('https://api.dexkey.finance/v1/ledger/transfer', {
        method: 'POST',
        headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
        body: JSON.stringify({ ...payload, idempotencyKey }),
      });
      return await resposta.json();
    } catch (erro) {
      if (i === tentativas - 1) throw erro;
      // Repete o loop com a MESMA idempotencyKey — nunca gere uma nova aqui.
    }
  }
}

1. Pix

O Pix permite depósitos na plataforma (geração de QR Code) e saques para chaves externas.

1.1 — Depósito (Gerar QR Code Pix)

curl -X POST https://api.dexkey.finance/v1/pix/deposit \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "25000",
    "expirationTime": 3600
  }'
  • amount: R$ 250,00 (2 decimais, menor unidade)

  • expirationTime: expira em 1 hora (em segundos)

Resposta:

{
  "qrCodeId": "550e8400-e29b-41d4-a716-446655440000",
  "copypaste": "00020126580014br.gov.bcb.pix...",
  "qrCodeImageUrl": "https://.../qrcode.png",
  "amount": 25000,
  "status": "PENDING",
  "expirationTime": 3600,
  "expiresAt": "2026-06-17T13:00:00.000Z"
}
  • qrCodeId: use para consultar o status do depósito depois (GET /pix/deposit/{id}/status) — prefira Webhook a fazer polling nesse endpoint.

  • copypaste: o código "Pix Copia e Cola" a ser exibido/copiado pelo pagador.

1.2 — Saque Pix (Withdraw)

curl -X POST https://api.dexkey.finance/v1/pix/withdraw \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "10000",
    "pixKeyType": "EMAIL",
    "pixKey": "destinatario@example.com"
  }'
  • amount: R$ 100,00 (2 decimais, menor unidade)

  • pixKeyType: "CPF", "CNPJ", "PHONE", "EMAIL" ou "EVP"

1.3 — Consultar Chave Pix Antes de Sacar (DICT)

Confira o titular de uma chave antes de confirmar o saque — evita enviar pro destinatário errado. Requer KYC FULL.

curl "https://api.dexkey.finance/v1/pix/dict/{key}?type=EMAIL" \
  -H "Authorization: Bearer $JWT"
{
  "found": true,
  "pixKey": "***.123.456-**",
  "name": "Fulano de Tal",
  "bank": { "name": "Banco do Brasil", "ispb": "00000000" },
  "branch": "0001",
  "accountNumber": "12345-6",
  "accountType": "CORRENTE",
  "document": "***.123.456-**"
}

422 se a chave não existir ou o formato for inválido.

1.4 — Preview de Taxas do Saque (Sem Executar)

Mostra quanto será cobrado antes de confirmar — útil para exibir o total ao usuário antes do saque de verdade.

curl -X POST https://api.dexkey.finance/v1/pix/withdraw/preview \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000,
    "pixKeyType": "EMAIL",
    "pixKey": "destinatario@example.com"
  }'
{
  "withdrawAmount": 10000,
  "fees": {
    "grossAmount": "100.70",
    "platformFee": { "fixed": "2.00", "fixedFormatted": "R$ 2,00", "percentage": "3.00", "percentageFormatted": "R$ 3,00", "total": "5.00", "totalFormatted": "R$ 5,00" },
    "participantFee": { "fixed": "1.00", "fixedFormatted": "R$ 1,00", "percentage": "1.00", "percentageFormatted": "R$ 1,00", "total": "2.00", "totalFormatted": "R$ 2,00" },
    "totalFee": "0.70",
    "netAmount": "99.30",
    "effectiveRate": "0.70"
  },
  "totalAmount": 10070,
  "netAmount": 9930,
  "feesEnabled": true,
  "currentBalance": 50000,
  "hasSufficientBalance": true,
  "missingAmount": 0
}

Existe também GET /pix/withdraw/preview?amount=10000 (mesma resposta, sem precisar informar pixKeyType/pixKey) para uma estimativa rápida só pelo valor.

2. Transferência Interna (Entre Usuários da Plataforma)

Move saldo entre duas contas da própria DEX, com dupla entrada atômica no ledger — sem passar por Pix ou blockchain.

2.1 — Consultar Destinatário Antes de Enviar (Opcional, Recomendado)

Confirma nome e conta antes de transferir, pelo telefone (Chave DEX) do destinatário:

curl "https://api.dexkey.finance/v1/ledger/dict/+5511999999999"

Endpoint público, sem autenticação, limitado a 10 requisições/minuto por IP.

{
  "found": true,
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "João Silva",
    "phone": "+5511999999999",
    "accountCode": "USER_550e8400-e29b-41d4-a716-446655440000"
  }
}

2.2 — Executar a Transferência

curl -X POST https://api.dexkey.finance/v1/ledger/transfer \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "5000",
    "currency": "BRT",
    "destinationIdentifier": "+5511999999999",
    "description": "Pagamento do jantar",
    "idempotencyKey": "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"
  }'
  • amount: R$ 50,00 (menor unidade — 2 decimais pra BRL/BRT)

  • destinationIdentifier: aceita telefone (Chave DEX, +55...), e-mail, ou Account Code (USER_<uuid>)

  • blockchain: obrigatório apenas para moedas cripto (BTC, ETH, USDT, USDC, BRT) — ignorado para BRL

  • idempotencyKey: obrigatório, gere um UUIDv7 novo por transferência

{
  "id": "660e8400-e29b-41d4-a716-446655440001",
  "type": "TRANSFER_INTERNAL",
  "status": "COMPLETED",
  "amount": "5000",
  "currency": "BRT",
  "entries": [
    { "id": "...", "accountCode": "...", "amount": "-5000", "currency": "BRT", "type": "DEBIT" },
    { "id": "...", "accountCode": "...", "amount": "5000", "currency": "BRT", "type": "CREDIT" }
  ],
  "createdAt": "2026-01-20T10:00:00Z",
  "completedAt": "2026-01-20T10:00:00Z"
}

404 se o destinatário não for encontrado.

400 se tentar transferir para a própria conta.

3. Swap (Troca de Moedas)

O Swap realiza a conversão instantânea de uma moeda para outra (ex: Reais para Bitcoin). O processo exige obter uma cotação (válida por 30 segundos) e depois executá-la.

📌 Diferente de Pix e Cripto, o Swap não exige KYC completo (FULL) — está disponível também para contas no nível BASIC.

3.1 — Solicitar Cotação

curl -X POST https://api.dexkey.finance/v1/swap/quote \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "fromCurrency": "BRT",
    "toCurrency": "BTC",
    "fromAmount": "10000"
  }'
  • fromAmount: R$ 100,00 (menor unidade da moeda de origem)

Resposta (simplificada — a resposta real inclui mais campos de taxa e cotação):

{
  "quoteId": "qt_1705787200000_a1b2c3d4",
  "fromCurrency": "BRT",
  "toCurrency": "BTC",
  "fromAmount": "10000",
  "netAmount": "19006", // valor líquido que receberá, na menor unidade de BTC (satoshis)
  "netAmountFormatted": "0.00019006 BTC",
  "rate": "1.9006",
  "status": "PENDING",
  "expiresAt": "2026-06-17T12:00:30.000Z"
}

3.2 — Executar o Swap

Utilize o quoteId retornado na cotação para efetivar a conversão antes do prazo expirar:

curl -X POST https://api.dexkey.finance/v1/swap/execute \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "quoteId": "qt_1705787200000_a1b2c3d4"
  }'

3.3 — Consultar Status de uma Cotação

Útil pra saber se uma quote ainda está pendente, já foi executada, ou expirou:

curl https://api.dexkey.finance/v1/swap/status/qt_1705787200000_a1b2c3d4 \
  -H "Authorization: Bearer $JWT"

Retorna o mesmo formato da resposta de POST /swap/quote (seção 3.1), com status atualizado: PENDING, EXECUTED ou EXPIRED.

404 se a quote não pertencer ao usuário ou não existir.

4. Criptomoedas (Saques Blockchain)

Permite enviar criptomoedas da carteira do usuário para um endereço externo (on-chain) em redes como Bitcoin ou Ethereum.

Endpoint

POST /v1/ledger/crypto/withdraw

Exemplo — Saque de 0.01 BTC

curl -X POST https://api.dexkey.finance/v1/ledger/crypto/withdraw \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "BTC",
    "amount": "1000000",
    "toAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493...",
    "idempotencyKey": "0195a1b2-c3d4-7e5f-8a90-1234567890ab"
  }'
  • amount: 0.01 BTC (8 decimais, menor unidade)

  • idempotencyKey: obrigatório — gere um UUIDv7 novo por saque (ver seção Idempotência acima)

Não existe um endpoint de status dedicado para depósito/saque cripto (diferente do Pix). Para consultar status, comprovante completo, contrato de GET /ledger/statement e exemplos de todos os tipos de transação (incluindo CRYPTO_SWAP), veja Referência Completa do Ledger. Para consultar a taxa cobrada antes ou depois de qualquer operação desta página, veja Referência de Taxas.