API REST nativa

Abrir no ChatGPTAbrir no Claude

A API nativa é a interface REST própria da blockwallets: cobranças em centavos de dólar, um ref idempotente por pedido, contas de depósito estáticas que cobrem todas as redes e webhooks assinados com HMAC-SHA256. Ela cria as mesmas cobranças na mesma página de pagamento hospedada que a API compatível com a Cryptomus, com as mesmas taxas e o mesmo saldo.

Gere as suas chaves você mesmo no painel, em “Desenvolvedores › Integração e chaves”: uma chave Live e uma Test com as respectivas chaves de assinatura de webhook. Cada uma é mostrada uma única vez; a lista só mostra o prefixo. Se a sua conta tem a verificação em duas etapas ativa, gerar ou rotacionar uma chave Live pede um código. Ainda não tem conta de lojista? Solicite acesso. Já usa a Cryptomus? Veja a API compatível com a Cryptomus (como escolher).

Chaves e requisições

URL base https://blockwallets.io. Requisições e respostas são em JSON. Toda requisição leva:

Os erros retornam um status HTTP e {"error": {"code": "…", "message": "…"}}: 400 invalid_request (campo ausente ou malformado), 401 unauthorized (chave ausente, desconhecida ou desativada), 404 not_found, 409 conflict (a requisição conflita com o estado atual da cobrança), 422 currency_unsupported.

Endpoints

EndpointO que faz
GET /v1/networksRedes que você pode aceitar agora no modo desta chave: mínimo, confirmações, tempo típico de chegada e taxa estimada; as moedas cotadas incluem a cotação atual
POST /v1/invoicesCria uma cobrança (201), ou retorna a existente para o mesmo ref (200)
GET /v1/invoices?ref=…Consulta uma cobrança pelo seu ref
GET /v1/invoices/:idConsulta uma cobrança pelo id
POST /v1/invoices/:id/networkEscolha você mesmo a rede de uma cobrança (página de pagamento white-label): retorna o address e o pay_amount a exibir
POST /v1/invoices/:id/closeFecha uma cobrança pendente que não recebeu nenhuma transferência
POST /v1/deposit-accountsAbre (201) ou obtém (200) a conta de depósito de um cliente: um endereço permanente em cada rede
GET /v1/deposit-accounts?customer_ref=…Consulta uma conta de depósito pelo customer_ref
GET /v1/deposit-accounts/:idConsulta uma conta de depósito pelo id
GET /v1/depositsLista os depósitos de uma conta (account_id ou customer_ref, limit 1–200, padrão 50)
GET /v1/deposits/:idConsulta um depósito
GET /v1/eventsEntregas de webhook de uma cobrança ou depósito (invoice_id ou deposit_id)
POST /v1/events/:id/redeliverEnvia um webhook de novo (202)

Adicione ?probe=1 à consulta de uma cobrança ou conta de depósito para verificar a blockchain na hora (no máximo uma vez a cada 10 segundos); caso contrário você recebe o último estado do nosso scanner, que verifica a cada minuto.

Criar uma cobrança POST /v1/invoices

Chame POST /v1/invoices quando o cliente finalizar a compra e redirecione-o para a pay_url da resposta.

curl
curl -X POST https://blockwallets.io/v1/invoices \
  -H "Authorization: Bearer $BW_KEY" -H "Content-Type: application/json" \
  -d '{"ref":"order_1042","amount":4200,"title":"Order #1042",
       "return_url":"https://shop.example/cart","success_url":"https://shop.example/thanks?order=1042",
       "meta":{"user_id":42}}'
CampoObrigatórioDescrição
refSimO número do seu pedido: 1–64 caracteres entre letras, dígitos e _ . : -. Único por modo; enviar o mesmo ref com os mesmos campos retorna a mesma cobrança, com campos diferentes retorna 409
amountSimValor em centavos de dólar, inteiro: 4200 = $42.00. Não pode ficar abaixo do mínimo da rede depois de escolhida
titleSimO que o cliente vê na página de pagamento, até 64 caracteres
return_urlSimPara onde vai o “Voltar” na página de pagamento; deve estar em um dos domínios do seu site
success_urlNãoPara onde o cliente vai depois de pagar; o padrão é return_url
networkNãoPré-seleciona um id de rede da tabela de redes; omita para o cliente escolher na página de pagamento
customer_refNãoO id do seu cliente, até 64 caracteres, devolvido como está
lifetimeNãoDuração em segundos, 600 – 43200, padrão 3600
amount_ruleNão"any" = credita o que chegar (recargas): paid assim que confirmar. Omita para usar a “Regra de valor” em “Configurações › Regras de recebimento e taxas” no painel
accuracy_percentNãoQuanto de pagamento a menos ainda conta como pago, 0 – 5 (por cento), padrão 0
subtract_percentNãoParte da taxa da plataforma paga pelo cliente, 0 – 100 (por cento), somada ao pay_amount; omita para usar o padrão do painel
payment_multipleNãoSe um pagamento insuficiente pode ser complementado no mesmo endereço, padrão do painel (ligado, a menos que você tenha mudado); false: a primeira transferência insuficiente termina como wrong_amount
metaNãoQualquer objeto JSON de até 2 KB, devolvido como está nas consultas e nos webhooks
currencyNãoSomente USD (o padrão); qualquer outro retorna 422

Toda URL deve estar em um dos domínios do seu site (painel → “Desenvolvedores › Integração e chaves”). A resposta é o objeto cobrança abaixo; network, address e pay_amount são preenchidos assim que uma rede é escolhida.

O objeto cobrança

Os ids começam com inv_. amount está em centavos de dólar; pay_amount e paid_amount são valores da moeda, em strings decimais, na rede escolhida.

json
{
  "id": "inv_01J8…",
  "ref": "order_1042",
  "mode": "live",
  "status": "pending",
  "amount": 4200,
  "currency": "USD",
  "title": "Order #1042",
  "meta": { "user_id": 42 },
  "network": null,
  "address": null,
  "pay_amount": null,
  "paid_amount": null,
  "payments": [],
  "pay_url": "https://blockwallets.io/pay/inv_01J8…",
  "return_url": "https://shop.example/cart",
  "success_url": "https://shop.example/thanks?order=1042",
  "created_at": "2026-11-03T08:00:00.000Z",
  "expires_at": "2026-11-03T09:00:00.000Z",
  "paid_at": null,
  "closed_at": null
}
statusSignificadoO que você faz
pendingAguardando pagamento—
confirmingUma transferência foi detectada e está confirmando, ou chegou incompleta e ainda pode ser complementada—
paidPagaEnvie / credite o pedido
paid_overPaga, com pagamento a maisO mesmo; o excedente fica no seu saldo
wrong_amountTerminou com menos que o valor total (na expiração, ou na primeira transferência insuficiente quando payment_multiple é false)Negócios de recarga podem creditar o que chegou (paid_amount; moedas com cotação também trazem paid_cents); lojas pedem ao cliente que pague o restante
closedExpirou sem receber nada, ou você a fechou— (o dinheiro que chegar depois ainda é creditado e notificado)

Outros campos: pay_url (a página de pagamento hospedada), payments (cada transferência com txid, amount, confirmations e confirmed), expires_at, paid_at, closed_at; BTC, LTC, DOGE, BCH e moedas nativas também trazem rate (dólares por moeda, travado por 30 minutos), rate_locked_until e paid_cents (o que já chegou, em centavos de dólar).

Redes

Passe o id como network. GET /v1/networks retorna as que estão abertas agora no seu modo; uma rede pode ser pausada, então prefira consultar a deixá-la fixa no código.

networkMoedaRedeMínimo
USDT_TRC20USDTTRON$1
USDT_BEP20USDTBNB Chain$1
USDC_BEP20USDCBNB Chain$1
USDT_ERC20USDTEthereum$5
USDC_ERC20USDCEthereum$5
USDC_BASEUSDCBase$1
USDT_POLYGONUSDTPolygon$1
USDC_POLYGONUSDCPolygon$1
USDT_ARBITRUMUSDTArbitrum$1
USDC_ARBITRUMUSDCArbitrum$1
USDT_OPTIMISMUSDTOptimism$1
USDC_OPTIMISMUSDCOptimism$1
USDT_AVALANCHEUSDTAvalanche$1
USDC_AVALANCHEUSDCAvalanche$1
USDT_XLAYERUSDTX Layer$1
USDC_XLAYERUSDCX Layer$1
USD1_BEP20USD1BNB Chain$1
FDUSD_BEP20FDUSDBNB Chain$1
DAI_ERC20DAIEthereum$5
DAI_ARBITRUMDAIArbitrum$1
DAI_BASEDAIBase$1
BTCBTCBitcoin$5
LTCLTCLitecoin$1
DOGEDOGEDogecoin$1
BCHBCHBitcoin Cash$1
TRXTRXTRON$1
BNBBNBBNB Chain$1
ETHETHEthereum$5
ETH_BASEETHBase$1
ETH_ARBITRUMETHArbitrum$1
ETH_OPTIMISMETHOptimism$1
POLPOLPolygon$1
AVAXAVAXAvalanche$1
OKBOKBX Layer$1
USDT_SOLUSDTSolana$1
USDC_SOLUSDCSolana$1
SOLSOLSolana$1
USDT_TONUSDTTON$1
TONTONTON$1

Contas de depósito (endereços estáticos) POST /v1/deposit-accounts

POST /v1/deposit-accounts com {"customer_ref": "user_42"} dá a esse cliente um endereço permanente em cada rede (todas as redes EVM compartilham um endereço). Tudo o que ele enviar é creditado em dólares americanos, com um webhook deposit.credited por transferência.

curl
curl -X POST https://blockwallets.io/v1/deposit-accounts \
  -H "Authorization: Bearer $BW_KEY" -H "Content-Type: application/json" \
  -d '{"customer_ref":"user_42"}'
json
{
  "id": "dac_01J8…",
  "mode": "live",
  "customer_ref": "user_42",
  "deposit_url": "https://blockwallets.io/deposit/dac_01J8…",
  "min_amount": 100,
  "currency": "USD",
  "networks": [
    { "id": "USDT_TRC20", "chain": "tron", "token": "USDT", "address": "TXy4…8kQ2", "min_amount": 100, "confirmations": 1, … },
    { "id": "USDC_BASE", "chain": "base", "token": "USDC", "address": "0x5aE1…", "min_amount": 100, "confirmations": 20, … }
  ]
}

Transferências abaixo do mínimo (geralmente $1, BTC $5) são registradas como below_min e não são creditadas automaticamente; fale com a gente para creditá-las.

Webhooks

Enviamos um POST com JSON para a URL de webhook do painel (“Desenvolvedores › Integração e chaves”; Live e Test têm cada um a sua URL e o seu secret). O corpo é o evento:

http
POST /your/webhook
X-BW-Event: ev_01J8…
X-BW-Delivery: 1
X-BW-Signature: t=1793693052,v1=5f0c9b…

{"id":"ev_01J8…","type":"invoice.paid","created_at":"2026-11-03T08:04:12.000Z","invoice":{"id":"inv_01J8…","ref":"order_1042","status":"paid","amount":4200,…}}
EventoQuando
invoice.paidA cobrança virou paid ou paid_over (inclusive dinheiro que chegou depois de expirar)
invoice.wrong_amountA cobrança terminou como wrong_amount
invoice.closedA cobrança expirou sem receber nada, ou você a fechou
deposit.creditedUma transferência para uma conta de depósito foi creditada

Verifique contra o corpo bruto antes de interpretá-lo, rejeite um t a mais de 300 segundos do seu relógio e compare em tempo constante. invoice / deposit no corpo é o mesmo objeto que uma consulta retorna.

Node.js
import crypto from "node:crypto";

// rawBody: the request body exactly as received (a string), header: X-BW-Signature
function verify(rawBody, header, secret) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > 300) return false;
  const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex");
  return typeof parts.v1 === "string" && parts.v1.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}

Uma resposta 2xx conta como entregue; caso contrário tentamos de novo após 1 minuto, 5 minutos, 30 minutos, 2 horas, 12 horas, 24 horas e 24 horas (8 tentativas no total).

Eventos e reenvio

GET /v1/events?invoice_id=inv_… (ou deposit_id=dep_…) lista os webhooks de uma cobrança ou depósito com state, attempts, last_status e last_error. POST /v1/events/ev_…/redeliver o coloca de novo na fila na hora, por exemplo depois de você corrigir o seu endpoint. “Desenvolvedores › Log de webhooks” no painel mostra cada tentativa com requisição e resposta.

Modo de teste

As cobranças criadas com uma chave bw_test_ rodam em testnets e nunca tocam dinheiro real. A página de pagamento hospedada mostra um botão “Simular pagamento” (total / metade / a mais), para você acompanhar status e webhooks sem moedas de testnet.