Desenvolvedores
Uma API de pagamentos em cripto feita para liquidação direta
Crie uma cobrança com uma única requisição autenticada e a Unheld devolve o endereço a pagar, o valor exato e a profundidade de confirmação que vai esperar. Os pagamentos caem direto numa carteira que você controla — a API nunca fica com a custódia daquilo que ela informa.
Criar uma cobrança
Um POST. O valor é escrito do jeito que uma pessoa escreve e é escalado no servidor pelas casas decimais do próprio ativo, então você nunca converte para unidades base na mão.
curl -X POST https://api.unheld.io/api/v1/invoices \
-H "Authorization: Bearer $UNHELD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chainId": "11155111",
"assetType": "native",
"amountDecimal": "0.05",
"expiresInSeconds": 900,
"metadata": { "orderId": "A-1043" }
}'Resposta
{
"id": "e2b0…",
"status": "CREATED",
"receiveAddress": "0x…",
"expectedAmount": "50000000000000000",
"minConfirmations": 3,
"expiresAt": "2026-08-10T14:15:00.000Z",
"instructions": {
"chainId": "11155111",
"to": "0x…",
"amount": "50000000000000000",
"assetType": "native"
}
}receiveAddress é derivado da sua carteira e travado nesta cobrança. expectedAmount está em unidades base. minConfirmations é o limite da própria rede, não uma configuração que inventamos.
Autenticação e escopos
As chaves são tokens bearer, criadas no painel e exibidas uma única vez. Cada chave carrega uma lista explícita de escopos e a requisição é recusada se a chave não tiver o escopo daquela rota.
Escopos disponíveis
- invoices:write
- invoices:read
- webhooks:write
- webhooks:read
- balances:read
- customers:write
- customers:read
- subscriptions:write
- subscriptions:read
Conceda o conjunto mais estreito que funcione. Uma chave que só cria cobranças não consegue ler seus clientes, e uma chave de leitura vazada não move nada — porque nada nesta API move.
Webhooks que você pode verificar
Toda entrega é assinada. A assinatura é um HMAC-SHA256 do timestamp e do corpo bruto unidos por um ponto, usando o seu segredo de webhook, enviado como digest hexadecimal.
Verificar uma entrega
const signature = crypto
.createHmac("sha256", webhookSecret)
.update(`${req.headers["x-timestamp"]}.${rawBody}`)
.digest("hex");
crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(req.headers["x-signature"])
);Compare os digests em tempo constante, recuse um timestamp fora da sua janela de tolerância e trate X-Request-Id como chave de idempotência: as retentativas reutilizam o mesmo valor, então o mesmo evento chegando duas vezes é normal e não pode ser processado duas vezes.
Eventos de cobrança
Um pagamento percorre estados em vez de pular de não pago para pago, e cada transição é um webhook. Pagar a menos e pagar a mais são eventos próprios, não erros.
| Evento | O que aconteceu |
|---|---|
| invoice.created | A cobrança existe e o endereço de recebimento está sendo observado. |
| invoice.receiving | Uma transação de pagamento foi vista na rede, mas ainda não está confirmada. |
| invoice.confirming | O pagamento está confirmando e ainda não atingiu o limite da rede. |
| invoice.paid | Totalmente confirmado na profundidade exigida pela rede. Pode entregar. |
| invoice.underpaid | Chegou menos que o esperado. Pagamentos parciais se acumulam, então uma segunda transferência pode completar. |
| invoice.overpaid | Chegou mais que o esperado, registrado com exatidão em vez de arredondado. |
| invoice.expired | A janela fechou sem pagamento completo. |
Teste o fluxo inteiro de graça
Teste faturas, detecção, confirmações e webhooks sem fundos reais. Tokens de teste não têm valor monetário. Atividade testnet não é pagamento real.
Âmbito
- Ela nunca guarda fundos. Não existe endpoint de saldo para sacar, porque os pagamentos caem no seu endereço e ficam lá.
- Ela não converte nem liquida em moeda fiduciária. Os pagamentos chegam no ativo e na rede em que foram enviados.
- Ainda não há SDKs oficiais. Aqui é tudo HTTP puro, e publicamos exemplos em vez de pacotes que manteríamos mal.
Dúvidas de quem integra
Existe um sandbox?
Teste faturas, detecção, confirmações e webhooks sem fundos reais. Tokens de teste não têm valor monetário. Atividade testnet não é pagamento real.
Como evito processar o mesmo webhook duas vezes?
Use X-Request-Id como chave de idempotência. As retentativas reutilizam o mesmo valor, então registre-o e ignore a repetição. Retentativas são esperadas: uma entrega que falha é reenviada seguindo um cronograma em vez de ser descartada.
Preciso converter os valores para unidades base?
Não. Envie amountDecimal como uma pessoa escreveria e a API escala pelas casas decimais do ativo. A resposta devolve expectedAmount em unidades base, então as duas representações ficam explícitas e não podem divergir.
Exemplos verificados na API ao vivo em .
Construa primeiro na testnet
Crie uma chave, aponte para uma rede de testnet e percorra o fluxo inteiro antes que qualquer coisa real se mova.
Começar grátisPreços · O que você pode aceitar hoje. · Seu dinheiro não passa por nós.