Документация разработчика

Проверить подпись платёжного уведомления

Проверьте HMAC-SHA256 от временной метки и исходного тела Webhook. Убедитесь в актуальности времени, сверьте заказ и исключите повторную выдачу перед ответом HTTP 2xx.

Эти API заказов (создание, запрос и повторная отправка) используют подписи HMAC-SHA256. GET /api/v1/ping требует только ключ API. Обратные платежи также включают подпись. HMAC использует секрет вашего продавца Webhook, а не ваш ключ API.

01. Характеристики заголовка

01. Отправка запросов API

Client to Server

Запросы на создание, запрос и повторную отправку также требуют X-Bolt-Key. timestamp должен быть в пределах 5 минут от часов сервера. Создайте новый timestamp и подпись при повторной попытке.

Unix миллисекунда timestampОбязательно
X-Bolt-Timestamp
HMAC-SHA256 шестнадцатеричная подписьОбязательно
X-Bolt-Signature

02. Получение обратных вызовов по платежам

Server to Merchant

BoltUtil генерирует временные метки и подписи обратного вызова. Получатели должны проверить необработанное тело, проверить окно timestamp и идемпотентно обрабатывать события и бизнес-заказы.

Unix миллисекунда timestampОбязательно
X-Bolt-Webhook-Timestamp
HMAC-SHA256 шестнадцатеричная подписьОбязательно
X-Bolt-Webhook-Signature

02. Расчет подписи

1

Создать подписанный контент

Соедините метку времени из заголовка, точку и точное исходное тело: timestamp + "." + raw_body. Используйте UTF-8 и сохраняйте точку даже при пустом теле.

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

Вычислить HMAC-SHA256

Используйте секрет из конфигурации вашего продавца Webhook. Тело, используемое для подписи, должно точно совпадать с телом, отправленным в вашем запросе 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

Кодировать в шестнадцатеричном формате строчными буквами

Представьте дайджест длиной 32 байта в виде 64 строчных шестнадцатеричных символов. Передавайте его в X-Bolt-Signature для запросов API. Проверяйте уведомления по X-Bolt-Webhook-Signature сравнением за постоянное время.

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

03. Примечания к проверке

  • Не анализируйте и не сериализуйте JSON перед проверкой. Пробелы, разрывы строк, порядок ключей и кодировка влияют на подпись.
  • HMAC проверяет целостность содержимого, но не предотвращает воспроизведение самостоятельно. Проверьте актуальность timestamp и дедуплицируйте события.
  • Действительная подпись не означает, что выполнение завершено. Проверьте связь заказа, статус платежа, суммы, валюту и тип расчета.
Просмотр обработки обратного вызова →
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.

Примерами являются адреса, хеши транзакций и заказы. Замените их собственным тестом data.

Base URL

PROD
https://api.boltutil.com