Tài liệu nhà phát triển

Xác minh chữ ký thông báo thanh toán

Xác minh Webhook bằng HMAC-SHA256 trên dấu thời gian và nội dung yêu cầu gốc. Kiểm tra thời gian, đơn hàng và chống xử lý trùng trước khi trả HTTP 2xx.

Các API đơn đặt hàng này (tạo, truy vấn và gửi lại) sử dụng chữ ký HMAC-SHA256. GET /api/v1/ping chỉ yêu cầu Khóa API. Lệnh gọi lại thanh toán cũng bao gồm chữ ký. HMAC sử dụng bí mật Webhook người bán của bạn chứ không phải Khóa API của bạn.

01. Thông số tiêu đề

01. Gửi yêu cầu đặt hàng API

Client to Server

Việc tạo, truy vấn và gửi lại yêu cầu cũng yêu cầu X-Bolt-Key. timestamp phải cách đồng hồ máy chủ trong vòng 5 phút. Tạo timestamp mới và chữ ký khi thử lại.

Unix mili giây timestampBắt buộc
X-Bolt-Timestamp
Chữ ký thập lục phân HMAC-SHA256Bắt buộc
X-Bolt-Signature

02. Nhận cuộc gọi lại thanh toán

Server to Merchant

BoltUtil tạo dấu thời gian và chữ ký gọi lại. Người nhận phải xác minh nội dung thô, kiểm tra cửa sổ timestamp và xử lý các sự kiện cũng như đơn đặt hàng kinh doanh một cách bình thường.

Unix mili giây timestampBắt buộc
X-Bolt-Webhook-Timestamp
Chữ ký thập lục phân HMAC-SHA256Bắt buộc
X-Bolt-Webhook-Signature

02. Tính toán chữ ký

1

Xây dựng nội dung đã ký

Ghép dấu thời gian từ tiêu đề, một dấu chấm và nguyên văn nội dung yêu cầu: timestamp + "." + raw_body. Dùng UTF-8 và giữ dấu chấm ngay cả khi nội dung trống.

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

Tính HMAC-SHA256

Sử dụng bí mật từ cấu hình Webhook người bán của bạn. Nội dung được sử dụng để ký phải khớp chính xác với nội dung được gửi trong yêu cầu API của bạn.

// 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

Mã hóa dưới dạng thập lục phân chữ thường

Mã hóa bản băm 32 byte thành 64 ký tự thập lục phân viết thường. Gửi qua X-Bolt-Signature cho yêu cầu API. Xác minh thông báo bằng X-Bolt-Webhook-Signature với phép so sánh thời gian cố định.

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

03. Ghi chú xác minh

  • Không phân tích cú pháp và sắp xếp lại JSON trước khi xác minh. Khoảng trắng, ngắt dòng, thứ tự khóa và mã hóa đều ảnh hưởng đến chữ ký.
  • HMAC xác minh tính toàn vẹn của nội dung nhưng không ngăn việc phát lại. Kiểm tra độ mới của timestamp và các sự kiện loại bỏ trùng lặp.
  • Chữ ký hợp lệ không có nghĩa là việc thực hiện đã hoàn tất. Kiểm tra liên kết đơn hàng, trạng thái thanh toán, số tiền, loại tiền tệ và hình thức thanh toán.
Xem xử lý gọi lại →
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.

Địa chỉ, băm giao dịch và đơn đặt hàng là ví dụ. Thay thế chúng bằng bài kiểm tra data của riêng bạn.

Base URL

PROD
https://api.boltutil.com