Pular para o conteúdo

Desenvolvedores

API de cobrança

Crie cobranças em cripto pelo sistema da sua loja, mostre o QR ao cliente e receba um aviso assinado quando o pagamento entrar. O valor cai direto na carteira da conta, sem intermediário. Comece pelo ambiente de testes, sem dinheiro real.

Autenticação

Crie a chave em Cobrar → API e webhook (a conta precisa ter a verificação em duas etapas ligada). Envie no cabeçalho Authorization e guarde só no servidor. Escolha o acesso: “ler e criar cobranças” (loja) ou “só ler” (conciliação, relatórios). Uma chave só de leitura que tenta criar recebe 403.

Authorization: Bearer ib_XXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Criar cobrança

token: USDC ou SOL. valor: decimal com ponto, ou omita para valor aberto. validade_horas: 1, 24, 72, 168 ou 720 (padrão 24). externo_id: o número do pedido na sua loja, único por conta. Envie Idempotency-Key (UUID) para poder repetir com segurança se a rede cair.

curl -X POST https://ducripto.com/api/v1/cobrancas \
  -H "Authorization: Bearer ib_XXXXXXXXXXXX_…" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1c2a8e-4b1d-4c55-9a3e-0d2b7f9e1c11" \
  -d '{"token":"USDC","valor":"25.90","descricao":"Pedido 1042","externo_id":"1042","validade_horas":24}'
{
  "id": "9b2f…", "estado": "pendente", "externo_id": "1042",
  "token": "USDC", "decimais": 6, "valor_unidades": "25900000", "valor": "25.9",
  "url_pagamento": "https://ducripto.com/pagar/9b2f…",
  "solana_pay": "solana:<carteira>?amount=25.9&spl-token=EPjF…&reference=…",
  "expira_em": "…", "pagamento": null
}

Consultar

Valores voltam sempre como texto em unidades inteiras do token (valor_unidades), sem perda de precisão. estado: pendente, paga, expirada ou cancelada. A lista vem em páginas: use limite (1 a 100, padrão 50) e passe em depois o valor de proximo para ler a página seguinte; proximo nulo = fim. Para carteiras que montam a transação no servidor (Solana Pay "transaction request"), use solana_pay_transacao; em cobrança de valor aberto, acrescente ?quantidade= à URL antes de codificar.

curl https://ducripto.com/api/v1/cobrancas/9b2f… -H "Authorization: Bearer ib_…"
curl "https://ducripto.com/api/v1/cobrancas?externo_id=1042" -H "Authorization: Bearer ib_…"
curl "https://ducripto.com/api/v1/cobrancas?limite=50&depois=<proximo>" -H "Authorization: Bearer ib_…"

Webhook: cobrança paga

Recebe um POST JSON com tipo cobranca.paga. Confira a assinatura: HMAC-SHA256 em hex de "timestamp.corpo" com o seu segredo, e recuse se o timestamp tiver mais de 5 minutos. Responda 2xx; senão repetimos com espera crescente. Use evento_id para ignorar repetições.

import { createHmac, timingSafeEqual } from 'node:crypto';

// corpo = texto CRU da requisição (antes de JSON.parse)
// x-interbank-assinatura-anterior só vem durante uma troca de chaves da plataforma: aceite qualquer uma
export function webhookValido(corpo, cab, segredo) {
  const ts = cab['x-interbank-timestamp'];
  if (!ts || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const esperado = createHmac('sha256', segredo).update(`${ts}.${corpo}`).digest();
  return ['x-interbank-assinatura', 'x-interbank-assinatura-anterior'].some((h) => {
    const veio = Buffer.from(cab[h] ?? '', 'hex');
    return veio.length === esperado.length && timingSafeEqual(veio, esperado);
  });
}

Botão de pagamento no seu site (SDK)

Uma linha de script desenha o botão com a sua marca e abre o checkout numa aba nova; quando o pagamento confirma, o seu site recebe o evento checkout:paga. O evento é só para a tela: entregue o pedido depois de confirmar no servidor (webhook assinado ou GET da cobrança).

<!-- data-cobranca: id devolvido por POST /api/v1/cobrancas · data-voltar: opcional, só do seu site -->
<script src="https://ducripto.com/sdk/v1/checkout.js" data-cobranca="9b2f…" data-voltar="/obrigado" async></script>
<script>
  addEventListener('checkout:paga', (e) => mostrarObrigado(e.detail.cobranca));
</script>

Receber em USDC de qualquer token

Envie "aceita_conversao": true ao criar uma cobrança em USDC com valor. Na página de pagamento, quem paga escolhe SOL, USDT, JUP ou BONK, vê quanto vai gastar, e a mesma transação converte e entrega o valor exato em USDC na sua carteira. O webhook e a consulta são os mesmos: o que conta é o USDC que chegou. Não vale no modo teste.

curl -X POST https://ducripto.com/api/v1/cobrancas -H "Authorization: Bearer ib_…" -H "Content-Type: application/json" \
  -d '{"token":"USDC","valor":"49.90","externo_id":"1043","aceita_conversao":true}'
# → { "aceita_conversao": true, "url_pagamento": "https://ducripto.com/pagar/…", … }
# quem paga escolhe SOL, USDT, JUP ou BONK na página; você recebe 49.90 USDC exatos

Ambiente de testes (sandbox)

Crie uma chave no modo Teste (começa com ib_test_). Ela usa a mesma API, mas só vê e cria cobranças de teste, que ficam na rede de testes (modo: "teste" na resposta e no webhook) e nunca entram no seu caixa. Para testar sem carteira, simule o pagamento: POST /api/v1/cobrancas/{id}/simular-pagamento (em valor aberto, envie {"valor": "…"}). O webhook cobranca.paga chega assinado, igual ao real. A chave de produção não simula, e uma chave não enxerga as cobranças da outra.

# chave de teste (ib_test_…): mesma API, só cobranças de teste, rede de testes
curl -X POST https://ducripto.com/api/v1/cobrancas -H "Authorization: Bearer ib_test_XXXXXXXXXXXX_…" \
  -H "Content-Type: application/json" -d '{"token":"USDC","valor":"25.90","externo_id":"teste-1"}'
# → { "id": "9b2f…", "modo": "teste", "rede": "devnet", "estado": "pendente", … }

curl -X POST https://ducripto.com/api/v1/cobrancas/9b2f…/simular-pagamento -H "Authorization: Bearer ib_test_XXXXXXXXXXXX_…"
# → { "estado": "paga", "pagamento": { "assinatura": "simulado_…", … } } e o webhook cobranca.paga com "modo": "teste"

Erros e limites

Erros vêm como { erro: { codigo, mensagem } }. 401 chave inválida ou revogada · 403 a chave não tem o escopo da operação · 404 cobrança de outra conta ou inexistente · 409 externo_id repetido ou Idempotency-Key reutilizada com outro corpo · 422 dados inválidos · 429 acima de 120 chamadas por minuto por chave.

Contrato (OpenAPI)

A especificação OpenAPI 3.1 completa (cobranças, erros e o webhook) está em /api/v1/openapi.json — importe no Postman, Insomnia ou num gerador de cliente. Ela é gerada dos mesmos esquemas que os testes conferem contra as respostas reais.

curl https://ducripto.com/api/v1/openapi.json