Documentação para desenvolvedores

Verificar assinaturas de notificações

Valide webhooks com HMAC-SHA256 sobre o timestamp e o corpo original. Confira a validade do horário, o pedido e os eventos duplicados antes de responder HTTP 2xx.

Essas APIs de pedidos (criar, consultar e reenviar) usam assinaturas HMAC-SHA256. GET /api/v1/ping requer apenas uma chave API. Os retornos de chamada de pagamento também incluem uma assinatura. HMAC usa seu segredo Webhook do comerciante, não sua chave API.

01. Especificações do cabeçalho

01. Enviando solicitações de pedido API

Client to Server

Criar, consultar e reenviar solicitações também exigem X-Bolt-Key. O timestamp deve estar dentro de 5 minutos do relógio do servidor. Gere um novo timestamp e uma assinatura ao tentar novamente.

Unix milissegundo timestampObrigatório
X-Bolt-Timestamp
Assinatura hexadecimal HMAC-SHA256Obrigatório
X-Bolt-Signature

02. Receber retornos de chamada de pagamento

Server to Merchant

BoltUtil gera carimbos de data/hora e assinaturas de retorno de chamada. Os destinatários devem verificar o corpo bruto, verificar a janela timestamp e tratar eventos e ordens comerciais de forma idempotente.

Unix milissegundo timestampObrigatório
X-Bolt-Webhook-Timestamp
Assinatura hexadecimal HMAC-SHA256Obrigatório
X-Bolt-Webhook-Signature

02. Cálculo de Assinatura

1

Construa o conteúdo assinado

Una o timestamp do cabeçalho, um ponto e o corpo original exato: timestamp + "." + raw_body. Use UTF-8 e mantenha o ponto mesmo se o corpo estiver vazio.

// 1. Construct payload: timestamp + "." + body
String payload = timestamp + "." + body;
2

Calcular HMAC-SHA256

Use o segredo da configuração Webhook do seu comerciante. O corpo usado para assinatura deve corresponder exatamente ao corpo enviado na sua solicitação API.

// JDK standard library: javax.crypto.Mac and SecretKeySpec
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] hash = mac.doFinal(payload.getBytes(StandardCharsets.UTF_8));
3

Codificar como hexadecimal minúsculo

Codifique o resumo de 32 bytes como 64 caracteres hexadecimais minúsculos. Envie-o em X-Bolt-Signature para requisições API. Verifique as notificações com X-Bolt-Webhook-Signature usando comparação em tempo constante.

// JDK 17+: java.util.HexFormat
String signature = HexFormat.of().formatHex(hash);

03. Notas de verificação

  • Não analise e serialize novamente JSON antes da verificação. Espaços em branco, quebras de linha, ordem de teclas e codificação afetam a assinatura.
  • HMAC verifica a integridade do conteúdo, mas não impede a reprodução por si só. Verifique a atualização de timestamp e desduplicar eventos.
  • Uma assinatura válida não significa que o cumprimento foi concluído. Verifique a associação do pedido, o status do pagamento, os valores, a moeda e o tipo de liquidação.
Ver tratamento de retorno de chamada →
signature / cURL
# Calculate a request signature without sending a request.
# BOLTUTIL_WEBHOOK_SECRET is your merchant Webhook secret, not API Key.
: "${BOLTUTIL_WEBHOOK_SECRET:?Set your Webhook secret}"
timestamp=$(python3 -c 'import time; print(int(time.time()*1000))')
body='{"externalOrderId":"INV-20260209-99281"}'
signature=$(printf '%s.%s' "$timestamp" "$body" | openssl dgst -sha256 -hmac "$BOLTUTIL_WEBHOOK_SECRET" | awk '{print $NF}')
printf 'X-Bolt-Timestamp: %s\nX-Bolt-Signature: %s\n' "$timestamp" "$signature"
# Send this SAME body with the above headers and X-Bolt-Key.
# Callback header names are X-Bolt-Webhook-Timestamp and
# X-Bolt-Webhook-Signature. Verify raw bytes before parsing JSON.

Endereços, hashes de transações e pedidos são exemplos. Substitua-os pelo seu próprio teste data.

Base URL

PROD
https://api.boltutil.com