개발자 문서

결제 알림 서명 검증

타임스탬프와 Webhook 요청 원문에 HMAC-SHA256을 적용해 서명을 검증하세요. 시각의 유효성, 주문과 결제 정보 및 중복을 확인하고 이벤트를 저장한 후 HTTP 2xx로 응답합니다.

이러한 주문 API(생성, 쿼리 및 재전송)는 HMAC-SHA256 서명을 사용합니다. GET /api/v1/ping에는 API 키만 필요합니다. 결제 콜백에는 서명도 포함됩니다. HMAC는 API 키가 아닌 판매자 Webhook 비밀번호를 사용합니다.

01. 헤더 사양

01. API 주문 요청 보내기

Client to Server

요청 생성, 쿼리 및 재전송에도 X-Bolt-Key가 필요합니다. timestamp는 서버 시계의 5분 이내여야 합니다. 재시도 시 새로운 timestamp 및 서명을 생성하세요.

Unix 밀리초 timestamp필수
X-Bolt-Timestamp
HMAC-SHA256 16진수 서명필수
X-Bolt-Signature

02. 결제 콜백 수신

Server to Merchant

BoltUtil는 콜백 타임스탬프와 서명을 생성합니다. 수신자는 원시 본문을 확인하고 timestamp 창을 확인하고 이벤트 및 비즈니스 주문을 멱등적으로 처리해야 합니다.

Unix 밀리초 timestamp필수
X-Bolt-Webhook-Timestamp
HMAC-SHA256 16진수 서명필수
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

소문자 16진수로 인코딩

32바이트 다이제스트를 소문자 16진수 64자로 변환합니다. API 요청의 X-Bolt-Signature에 넣으세요. 알림은 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