--- title: 토스페이먼츠 — 멱등키 가이드 (Using API / Idempotency-Key) source_type: official-doc url: https://docs.tosspayments.com/guides/using-api/idempotency-key archive_url: status: raw confidence: high tags: [ca-idempotency, toss-payments, korean-fintech, payment-domain] related_projects: [ca-skeleton-operational-contract] related_branches: [feature-rate-limit-idempotency-contract, feature-api-contract-baseline] created: 2026-05-22 last_reviewed: 2026-05-27 --- # 토스페이먼츠 — 멱등키 가이드 > Layer: `raw/company-tech-blogs/` (디렉토리 정정 후보: 토스페이먼츠 공식 개발자 가이드이므로 `raw/official-docs/` 로 이관 적절. 본 migration 에서는 자동 mv 금지 규칙에 따라 위치 유지 — 후속 정리 권고). > 한국 결제 도메인 표준 구현. ca-tmpl 의 idempotency contract 비교 기준. > 검증된 요약은 `/ingest` 후 `wiki/concepts/`에 별도 작성. ## Parent / 활용 branch (필수) > 이 자료가 정당화하는 결정 매핑. | Branch | 이 자료가 정당화하는 결정 | | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | [[raw/branch-notes/feature-rate-limit-idempotency-contract]] | Idempotency contract 의 key scope 4-tuple vs 3-tuple 비교 + TTL 정책 (15일) 비교 + in-flight 충돌 처리 (409 vs wait) 비교 근거 | | [[raw/branch-notes/feature-api-contract-baseline]] | API contract surface 에 `Idempotency-Key` 헤더 노출 표준 정립 시 vendor 표준 사례로 인용 | | [[raw/project-notes/ca-skeleton-operational-contract]] | §13. API Contract Surface (Idempotency-Key) + §18. Control Plane Contract (Rate Limit/Idempotency) 의 한국 결제망 reference | ## 출처 / Source - 원본 URL: https://docs.tosspayments.com/guides/using-api/idempotency-key - 보조: https://docs.tosspayments.com/blog/what-is-idempotency (개념 설명 블로그) - 참고: astor-dev "결제 도메인에서의 멱등성 보장" (개인 블로그, 사례 분석) - 아카이브 URL: (미수집) - 저자 / 조직: 토스페이먼츠 (TossPayments) Developer Documentation - 발행일: rolling docs (페이지 자체에 명시 없음) - 마지막 확인일: 2026-05-27 ## 왜 저장했는지 / Why archived 한국 결제 도메인의 vendor 표준 구현. ca-tmpl 이 한국 환경에서 운영된다면 토스의 정책 (4-tuple scope, 15일 TTL, 409 in-flight) 이 직접 비교 대상. ## 핵심 인용 / Key quotes (verbatim) > [§Idempotency-Key 사용] "요청 헤더에 `Idempotency-Key`를 추가하면 멱등한 요청을 보낼 수 있습니다" > [§Idempotency-Key 사용] "멱등키는 UUID(/resources/glossary/uuid)와 같이 충분히 무작위적인 고유 값으로 생성해주세요" > [§멱등성 보장 메커니즘] "토스페이먼츠 서버는 상점에서 API 요청 헤더로 보낸 멱등키와 API 키, API 주소, HTTP 메서드 조합이 같은 요청이 있는지 확인해서 멱등성을 보장합니다" > [§TTL] "멱등키는 처음 요청에 사용한 날부터 15일간 유효합니다" > [§에러] "HTTP `400 - INVALID_IDEMPOTENCY_KEY`" > [§에러] "HTTP `409 - IDEMPOTENT_REQUEST_PROCESSING`" > [§주의] "멱등한 요청에서 에러가 반환되었을 때 멱등키를 변경해서 동일한 요청을 재시도하는 것은 위험이 있습니다" ## Claims Extracted / 추출된 주장 | Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove | |---|---|---|---|---|---| | TOSS-IDEMP-C1 | 모든 POST API 에 `Idempotency-Key` 헤더를 추가하여 멱등 요청 가능, 값은 UUID 등 충분히 무작위 고유 값 권장 | [§Idempotency-Key 사용] "요청 헤더에 `Idempotency-Key`를 추가하면 멱등한 요청을 보낼 수 있습니다" + "멱등키는 UUID(/resources/glossary/uuid)와 같이 충분히 무작위적인 고유 값으로 생성해주세요" | `official-vendor-doc` | TossPayments API 의 POST endpoint | UUID 외 다른 형식 (예: 비즈니스 키, hash) 사용 시 충돌 위험은 별도 — 본 인용은 권장만 | | TOSS-IDEMP-C2 | 멱등성 보장 범위는 **(멱등키, API 키, API 주소, HTTP 메서드) 4-tuple** 조합 | [§멱등성 보장 메커니즘] "토스페이먼츠 서버는 상점에서 API 요청 헤더로 보낸 멱등키와 API 키, API 주소, HTTP 메서드 조합이 같은 요청이 있는지 확인해서 멱등성을 보장합니다" | `official-vendor-doc` | TossPayments 가맹점 × endpoint × method 단위 | request body 가 다를 때의 처리 정책은 인용 범위에 없음 — body fingerprint 정책 부재 | | TOSS-IDEMP-C3 | 멱등키 유효 기간은 첫 요청일로부터 **15일** | [§TTL] "멱등키는 처음 요청에 사용한 날부터 15일간 유효합니다" | `official-vendor-doc` | TossPayments idempotency store | 15일 정책이 모든 결제 도메인의 표준이라는 뜻은 아님. Stripe v1 24h / v2 30일과 다른 vendor-specific 결정 | | TOSS-IDEMP-C4 | 잘못된 멱등키 형식 (예: 300자 초과 등) 은 `400 - INVALID_IDEMPOTENCY_KEY`, in-flight 동일 요청은 `409 - IDEMPOTENT_REQUEST_PROCESSING` | [§에러] "HTTP `400 - INVALID_IDEMPOTENCY_KEY`" + "HTTP `409 - IDEMPOTENT_REQUEST_PROCESSING`" | `official-vendor-doc` | TossPayments 의 표준 에러 매핑 | 409 가 즉시 반환되므로 클라이언트가 backoff 책임. wait/poll 동작 안 함 | | TOSS-IDEMP-C5 | 멱등 요청 에러 시 키 변경 후 재시도는 위험이 있다 (공식적으로 권장 안 됨) | [§주의] "멱등한 요청에서 에러가 반환되었을 때 멱등키를 변경해서 동일한 요청을 재시도하는 것은 위험이 있습니다" | `official-vendor-doc` | retry 로직 설계 | 동일 키로 재시도해야 하는 정확한 조건 / 결과 코드별 분기는 본 인용에 없음 — 별도 가이드 확인 필요 | | TOSS-IDEMP-C6 | 동일 키 + 동일 4-tuple + 다른 body 의 처리 정책은 본 인용 범위 내에 **명시 없음** | (부재 자체가 claim) | `needs-confirmation` | body fingerprint mismatch 처리 | 토스가 body diff 를 무시한다는 뜻도, 거부한다는 뜻도 아님. 문서가 직접 다루지 않음 | ## Usage Boundaries / 적용 경계 - **이 자료가 직접 증명하는 것**: - `TOSS-IDEMP-C1` ~ `C5`: TossPayments idempotency API 의 헤더 사용법, key scope 4-tuple, TTL 15일, 에러 매핑, retry 위험 안내 - **이 자료가 증명하지 않는 것**: - `TOSS-IDEMP-C6`: same-key + different-body 시 동작 (body fingerprint 정책) - idempotency store 의 backend (DB vs Redis vs 그 외) — 외부 관찰 불가 - 다른 한국 결제사 (KG이니시스, 카카오페이 등) 도 동일 정책을 사용하는지 - in-flight 409 가 race condition 의 짧은 window 도 흡수하는지 (즉시 거부이므로 클라이언트 backoff 필수로 추정) - **내 프로젝트에 적용하려면 추가 확인이 필요한 것**: - ca-tmpl 의 3-tuple `(principal, key, useCaseName)` 과 토스의 4-tuple `(account, key, URL, method)` 매핑 시 `useCaseName` 이 URL+method 역할을 충분히 대체하는지 (비즈니스 식별자 일관성) - ca-tmpl 의 15일이 아닌 24h TTL 결정의 위험 (긴 retry window 손실 vs 저장소 부하) ## 메모 / Notes > 검증되지 않은 내 해석은 여기에 두지 말 것 — wiki source-summary 단계에서. - **key scope**: 4-tuple = `(API 키 = 가맹점, idempotency-key, API 주소, HTTP 메서드)`. ca-tmpl 의 3-tuple `(principal, key, useCaseName)` 와 유사하나 토스는 method 까지 명시. - **TTL**: 15일 (Stripe v1 24h 보다 길고, v2 30일보다 짧음). - **저장소**: 명시 안됨 — 외부에서 알 수 없음. 결제 도메인 특성상 영속 저장 추정 (검증 불가). - **duplicate 처리**: - 완료 후 동일 키 재요청 → first 응답 그대로 replay (`C2` 의 일반적 동작). - in-flight 동일 키 재요청 → `409 IDEMPOTENT_REQUEST_PROCESSING` (즉시 거부, ca-tmpl 처럼 wait 안 함). - **fingerprint (same key, different body)**: 공식 문서에 명시 없음 (`C6` 참조). - **장점 (추론)**: 가맹점 × endpoint × method 까지 분리되어 사고 범위가 좁음. 15일 긴 TTL. - **단점 (추론)**: body fingerprint 정책 부재. in-flight 409 → 클라이언트 backoff 책임. - **ca-tmpl 과의 차이 (대안 비교 후보, wiki/projects 추출 시 활용)**: - 토스 4-tuple ↔ ca-tmpl 3-tuple. `useCaseName` 이 URL+method 역할 통합. 동일 사상. - TTL: 토스 15일 ≫ ca-tmpl 24h. ca-tmpl 이 더 짧고 보수적. - in-flight: 토스 즉시 409 vs ca-tmpl 200ms wait → ca-tmpl 이 클라이언트 친화적. - fingerprint: 토스 미명시 vs ca-tmpl 명시적 422 → ca-tmpl 이 더 엄격. ## Related / 관련 - 같은 주제 다른 raw: - [[raw/company-tech-blogs/idempotency-brandur-stripe-postgres]] - [[raw/company-tech-blogs/idempotency-redis-vs-db-storage]] - 인용하는 branch: - [[raw/branch-notes/feature-rate-limit-idempotency-contract]] - [[raw/branch-notes/feature-api-contract-baseline]] - 인용하는 project: - [[raw/project-notes/ca-skeleton-operational-contract]] (§13, §18) - 인용한 wiki 요약: (미작성)