Documentación para desarrolladores

Verificar firmas de notificaciones de pago

Verifica webhooks con HMAC-SHA256 sobre la marca de tiempo y el cuerpo original. Valida la antigüedad, el pedido y los duplicados antes de responder HTTP 2xx.

Estas API de pedidos (creación, consulta y reenvío) utilizan firmas HMAC-SHA256. GET /api/v1/ping solo requiere una clave API. Las devoluciones de llamada de pago también incluyen una firma. HMAC utiliza su secreto comercial Webhook, no su clave API.

01. Especificaciones del encabezado

01. Enviando solicitudes de pedido API

Client to Server

Crear, consultar y reenviar solicitudes también requiere X-Bolt-Key. El timestamp debe estar dentro de los 5 minutos del reloj del servidor. Genere un nuevo timestamp y una firma al volver a intentarlo.

Unix milisegundo timestampObligatorio
X-Bolt-Timestamp
HMAC-SHA256 firma hexadecimalObligatorio
X-Bolt-Signature

02. Recibir devoluciones de llamada de pago

Server to Merchant

BoltUtil genera firmas y marcas de tiempo de devolución de llamada. Los receptores deben verificar el cuerpo sin formato, verificar la ventana timestamp y manejar eventos y órdenes comerciales de manera idempotente.

Unix milisegundo timestampObligatorio
X-Bolt-Webhook-Timestamp
HMAC-SHA256 firma hexadecimalObligatorio
X-Bolt-Webhook-Signature

02. Cálculo de firma

1

Construir el contenido firmado

Une la marca de tiempo de la cabecera, un punto y el cuerpo original exacto: timestamp + "." + raw_body. Usa UTF-8 y conserva el punto incluso si el cuerpo está vacío.

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

Calcular HMAC-SHA256

Utilice el secreto de la configuración de su comerciante Webhook. El cuerpo utilizado para firmar debe coincidir exactamente con el cuerpo enviado en su solicitud 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 en minúscula

Codifica el resumen de 32 bytes como 64 caracteres hexadecimales en minúscula. Envíalo en X-Bolt-Signature para solicitudes API. Verifica las notificaciones con X-Bolt-Webhook-Signature mediante una comparación de tiempo constante.

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

03. Notas de verificación

  • No analice ni vuelva a serializar JSON antes de la verificación. Los espacios en blanco, los saltos de línea, el orden de las claves y la codificación afectan a la firma.
  • HMAC verifica la integridad del contenido pero no impide la reproducción por sí solo. Verifique la actualización de timestamp y los eventos deduplicados.
  • Una firma válida no significa que el cumplimiento esté completo. Verifique la asociación del pedido, el estado del pago, los montos, la moneda y el tipo de liquidación.
Ver manejo de devolución de llamada →
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.

Direcciones, hashes de transacciones y pedidos son ejemplos. Reemplácelos con su propia prueba data.

Base URL

PROD
https://api.boltutil.com