멱등키 (Idempotency-Key)
PIN 발급이나 쿠폰 발송처럼 상태를 변경하는 API 요청은 네트워크 오류로 응답을 받지 못할 수 있습니다. 이때 같은 요청을 다시 보내면 쿠폰이 중복 발급될 수 있습니다.
Idempotency-Key 헤더를 사용하면 같은 요청을 여러 번 보내더라도 최초 한 번만 처리됩니다. 두 번째부터는 실제 처리 없이 저장된 응답을 그대로 반환합니다.
orderId만으로도 중복 방지가 가능합니다
orderId를 전달하면 동일한 orderId로 재요청 시 409 에러가 발생하여 비즈니스 레벨에서 중복을 방지할 수 있습니다. 네트워크 오류 시 동일한 요청을 그대로 재시도하려면 멱등키를 함께 사용하세요. 자세한 내용은 주문 ID를 참고하세요.
사용 방법
요청 헤더에 고유한 키를 추가합니다. UUID를 사용하는 것을 권장합니다.
POST /v1/coupons/issued/pin HTTP/1.1
Authorization: Basic {base64(secretKey:)}
Content-Type: application/json
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
- cURL
- Node.js
- Python
curl -X POST https://api.aiconbiz.kr/v1/coupons/issued/pin \
-u "test_sk_abcdef123456:" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-d '{"couponId": "cpn_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a"}'
const secretKey = 'test_sk_abcdef123456';
const encoded = Buffer.from(`${secretKey}:`).toString('base64');
const response = await fetch('https://api.aiconbiz.kr/v1/coupons/issued/pin', {
method: 'POST',
headers: {
'Authorization': `Basic ${encoded}`,
'Content-Type': 'application/json',
'Idempotency-Key': '550e8400-e29b-41d4-a716-446655440000',
},
body: JSON.stringify({
couponId: 'cpn_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a',
}),
});
import base64
import requests
secret_key = "test_sk_abcdef123456"
encoded = base64.b64encode(f"{secret_key}:".encode()).decode()
response = requests.post(
"https://api.aiconbiz.kr/v1/coupons/issued/pin",
headers={
"Authorization": f"Basic {encoded}",
"Content-Type": "application/json",
"Idempotency-Key": "550e8400-e29b-41d4-a716-446655440000",
},
json={"couponId": "cpn_018d8f3a2b4c5d6e7f8a9b0c1d2e3f4a"},
)
멱등키는 선택입니다
Idempotency-Key 헤더가 없으면 매번 새로운 요청으로 처리됩니다. 중복 방지가 필요한 PIN 발급, 쿠폰 발송, 취소 등의 요청에 사용하세요. GET 요청에는 멱등키를 보내도 무시됩니다.
동작 방식
멱등키는 요청 본문과 함께 저장됩니다. 같은 키로 같은 요청을 보내면 저장된 응답을 반환하지만, 같은 키로 다른 요청을 보내면 에러가 발생합니다.
| 상황 | 결과 | 설명 |
|---|---|---|
| 첫 번째 요청 | 정상 처리 | 요청을 실행하고 응답을 저장합니다 |
| 같은 키 + 같은 요청 | 저장된 응답 반환 | 쿠폰을 다시 발급하지 않고 이전 응답을 그대로 돌려줍니다 |
| 같은 키 + 다른 요청 | 409 에러 | 키 하나에 하나의 요청만 대응합니다 |
| 24시간 경과 후 같은 키 | 새 요청으로 처리 | 멱등키는 24시간 동안만 유효합니다. 이후 같은 키를 새 요청에 사용할 수 있습니다 |
| 키 없이 요청 | 매번 새 요청으로 처리 | 중복 방지 없이 매번 실행됩니다 |
멱등키 하나에 요청 하나
같은 멱등키를 다른 요청에 재사용하면 409 에러가 발생합니다. 요청마다 새로운 UUID를 생성하세요.
키 형식 규칙
| 항목 | 값 |
|---|---|
| 헤더 이름 | Idempotency-Key (대소문자 무관) |
| 필수 여부 | 선택 |
| 권장 형식 | UUID v7 권장 (v4도 사용 가능) |
| 최소 길이 | 1 byte |
| 최대 길이 | 300 bytes (UTF-8 기준) |
| 허용 문자 | 인쇄 가능한 ASCII (! ~ 범위, 0x21-0x7E) |
| 금지 문자 | 공백, 탭, 콤마(,), 한글 등 비 ASCII 문자 |
| 유효 기간 | 24시간 (이후 같은 키를 새 요청에 사용 가능) |
| 범위 | 조직 + 환경 (TEST/LIVE) 단위로 분리 |
유효한 키와 무효한 키 예시입니다.
| 키 값 | 유효 여부 | 사유 |
|---|---|---|
550e8400-e29b-41d4-a716-446655440000 | O | UUID 형식 |
order-2026-03-19-001 | O | 영문, 숫자, 하이픈 조합 |
my key 123 | X | 공백 포함 |
key1,key2 | X | 콤마 포함 |
멱등키-001 | X | 한글 (비 ASCII) |
| (빈 문자열) | X | 최소 1 byte 필요 |
x × 301자 | X | 300 bytes 초과 |
에러 처리
| 코드 | HTTP | 원인 | 대응 |
|---|---|---|---|
COMMON_INVALID_IDEMPOTENCY_KEY | 400 | 키 형식이 올바르지 않음 (빈 값, 300바이트 초과, 허용되지 않는 문자) | 키 형식을 확인하세요. UUID를 사용하면 형식 에러가 발생하지 않습니다 |
COMMON_IDEMPOTENCY_KEY_IN_PROGRESS | 409 | 같은 키로 보낸 이전 요청이 아직 처리 중 | 잠시 후 재시도하세요. 이전 요청이 완료되면 저장된 응답을 받을 수 있습니다 |
COMMON_IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_REQUEST | 409 | 같은 키로 다른 요청 본문을 보냄 | 새로운 UUID로 멱등키를 교체하세요 |