108 lines
11 KiB
Markdown
108 lines
11 KiB
Markdown
---
|
||
title: PayPal REST API — Idempotency (PayPal-Request-Id)
|
||
source_type: official-doc
|
||
url: https://developer.paypal.com/api/rest/reference/idempotency/
|
||
archive_url:
|
||
status: raw
|
||
confidence: medium
|
||
tags: [ca-idempotency, paypal, pair-scope, 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
|
||
---
|
||
|
||
# PayPal REST API — Idempotency (PayPal-Request-Id)
|
||
|
||
> Layer: `raw/official-docs/` — PayPal 공식 REST API 의 idempotency header (`PayPal-Request-Id`) 정의. Stripe `Idempotency-Key` 와 다른 헤더명, 다른 TTL 정책의 비교 reference.
|
||
|
||
## Parent / 활용 branch (필수)
|
||
|
||
| Branch | 이 자료가 정당화하는 결정 |
|
||
|---|---|
|
||
| [[raw/branch-notes/feature-rate-limit-idempotency-contract]] | `(request_id, API call type)` pair scope + 45일 TTL + in-flight "might fail" 모델의 비교 근거 |
|
||
| [[raw/branch-notes/feature-api-contract-baseline]] | 헤더명 차이 (vendor 마다 `Idempotency-Key` vs `PayPal-Request-Id` 등) 가 API surface 표준화 결정에 미치는 영향 |
|
||
| [[raw/project-notes/ca-skeleton-operational-contract]] | §13. API Contract Surface (Idempotency-Key) + §18. Control Plane Contract — 가장 긴 TTL 사례 reference |
|
||
|
||
## 컨텍스트
|
||
|
||
PayPal 의 `PayPal-Request-Id` 는 Stripe `Idempotency-Key` 와 다른 헤더명을 쓰지만 동일 개념. **scope 를 "request × API call type" 으로 정의**한다는 명시가 있어 ca-tmpl triple 과의 비교에 유리. 또한 결제 도메인에서 가장 긴 TTL (45일) 사례.
|
||
|
||
## 출처 / Source
|
||
|
||
- 원본 URL: https://developer.paypal.com/api/rest/reference/idempotency/
|
||
- 보조 URL: https://developer.paypal.com/api/rest/requests/ (API 요청 가이드)
|
||
- 아카이브 URL: (미수집)
|
||
- 저자 / 조직: PayPal Holdings, Inc. — Developer Documentation
|
||
- 발행일: rolling docs
|
||
- 마지막 확인일: 2026-05-27 (WebFetch 성공 — C2, C4, C5 는 verbatim 재확인 완료 → `official-vendor-doc` upgrade. C1 은 fragment 일치 + 후반부 ("to enforce idempotency on REST API POST calls") 미확인. C3 (45일 TTL) 은 페이지 개정으로 **NOT FOUND** — 현재 페이지는 "for a period of time" 만 언급, 45-day 수치 없음 → 계속 `needs-confirmation`)
|
||
|
||
## 핵심 인용 / Key quotes (verbatim)
|
||
|
||
> [§Idempotency, 2026-05-22 capture, 2026-05-27 partial verified — "unique user-generated ID that the server stores for a period of time" fragment 일치, 후반부 ("to enforce idempotency on REST API POST calls") 는 WebFetch 응답에 미포함] "The `PayPal-Request-Id` request header contains a unique user-generated ID that the server stores for a period of time to enforce idempotency on REST API POST calls."
|
||
|
||
> [§Idempotency, 2026-05-22 capture, 2026-05-27 verified verbatim] "The `PayPal-Request-Id` header value must be unique for both each request and an API call type. For example, authorize payment and capture authorized payment."
|
||
|
||
> needs-confirmation [§Idempotency, 2026-05-22 capture, 2026-05-27 NOT FOUND — 현재 페이지는 "for a period of time" 만 언급, 45-day 수치 없음] "PayPal stores your unique ID for up to 45 days. If you retry a call with the same `PayPal-Request-Id`, PayPal recognizes it as a duplicate and returns the result of the original call."
|
||
|
||
> [§Idempotency, 2026-05-22 capture, 2026-05-27 verified verbatim] "When you send two simultaneous API requests with same `PayPal-Request-Id` header, PayPal processes the first request and might fail the second request."
|
||
|
||
> [§Idempotency, 2026-05-22 capture, 2026-05-27 verified verbatim] "You can retry idempotent calls that fail with network timeouts or HTTP `5xx` status codes for as long as the server stores the ID."
|
||
|
||
> **2026-05-27 재검증 결과**: C2, C4, C5 verbatim 확인 (`official-vendor-doc` upgrade). C1 은 partial (fragment 일치). **C3 (45일 TTL) 은 NOT FOUND** — PayPal 이 페이지를 개정하여 구체 일수를 제거했을 가능성 (현재는 "for a period of time" 만 명시). ca-tmpl 24h TTL vs PayPal 45일 비교 분석을 사용하는 모든 downstream 문서는 PayPal 의 명시적 45-day 수치 출처를 다른 페이지/archive snapshot 으로 보강 필요.
|
||
|
||
## Claims Extracted / 추출된 주장
|
||
|
||
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
||
|---|---|---|---|---|---|
|
||
| PAYPAL-IDEMP-C1 | `PayPal-Request-Id` 는 client 가 생성한 unique ID 를 server 가 일정 기간 저장하여 REST API POST 호출의 idempotency 를 강제 | [§Idempotency, 2026-05-22 capture, 2026-05-27 partial verified — fragment 일치] "The `PayPal-Request-Id` request header contains a unique user-generated ID that the server stores for a period of time to enforce idempotency on REST API POST calls." | `needs-confirmation` (partial — fragment "unique user-generated ID that the server stores for a period of time" 만 verbatim 확인, 후반부 미확인) | PayPal REST API POST endpoint | Stripe `Idempotency-Key` 와 100% 동일 동작이라는 뜻은 아님 |
|
||
| PAYPAL-IDEMP-C2 | unique 성은 (request, API call type) 두 축 모두에 대해 요구 — authorize payment 과 capture authorized payment 가 별도 idempotency 단위 | [§Idempotency, 2026-05-22 capture, 2026-05-27 verified verbatim] "The `PayPal-Request-Id` header value must be unique for both each request and an API call type. For example, authorize payment and capture authorized payment." | `official-vendor-doc` | PayPal REST API 의 endpoint 간 분리 | 가맹점 (account) dimension 의 명시적 분리는 본 인용에 없음 — API 키 인증으로 implicit |
|
||
| PAYPAL-IDEMP-C3 | PayPal 은 unique ID 를 최대 45일까지 저장하며, 동일 ID 로 재시도 시 duplicate 으로 인식하여 original call 의 결과를 반환 | [§Idempotency, 2026-05-22 capture, 2026-05-27 NOT FOUND — 현재 페이지는 "for a period of time" 만 언급] "PayPal stores your unique ID for up to 45 days. If you retry a call with the same `PayPal-Request-Id`, PayPal recognizes it as a duplicate and returns the result of the original call." | `needs-confirmation` | PayPal idempotency store | 45일 수치 자체가 현재 페이지에 부재 — 페이지 개정 가능성, 다른 출처 보강 필요 |
|
||
| PAYPAL-IDEMP-C4 | 동일 `PayPal-Request-Id` 로 두 simultaneous request 를 보내면 PayPal 은 first 를 처리하고 second 는 fail 시킬 수 있다 ("might fail") | [§Idempotency, 2026-05-22 capture, 2026-05-27 verified verbatim] "When you send two simultaneous API requests with same `PayPal-Request-Id` header, PayPal processes the first request and might fail the second request." | `official-vendor-doc` | PayPal 의 in-flight 동시 요청 처리 | "might fail" 의 정확한 status code / error 형태는 본 인용에 없음. 항상 fail 한다는 뜻도 아님 (확률적 표현) |
|
||
| PAYPAL-IDEMP-C5 | network timeout 또는 5xx 로 실패한 idempotent call 은 server 가 ID 를 저장하는 기간 동안 재시도 가능 | [§Idempotency, 2026-05-22 capture, 2026-05-27 verified verbatim] "You can retry idempotent calls that fail with network timeouts or HTTP `5xx` status codes for as long as the server stores the ID." | `official-vendor-doc` | retry 정책 설계 | 4xx 실패에 대한 재시도 권장 여부는 본 인용 범위 밖 |
|
||
| PAYPAL-IDEMP-C6 | same key + different body (fingerprint mismatch) 의 처리 정책은 본 인용 범위 내에 **명시 없음** | (부재 자체가 claim) | `needs-confirmation` | body fingerprint mismatch 처리 | PayPal 이 body diff 를 무시한다는 뜻도, 거부한다는 뜻도 아님. 문서가 직접 다루지 않음 |
|
||
|
||
## Usage Boundaries / 적용 경계
|
||
|
||
- **이 자료가 직접 증명하는 것**:
|
||
- 2026-05-27 verbatim 확인 완료 (`official-vendor-doc`): `C2` (request × API call type scope), `C4` (simultaneous "might fail"), `C5` (5xx/timeout retry 허용)
|
||
- 2026-05-27 partial (fragment 일치): `C1` (header 의 unique user-generated ID 저장 메커니즘)
|
||
- 2026-05-27 NOT FOUND: `C3` (45일 TTL — 현재 페이지는 "for a period of time" 만 명시)
|
||
- **이 자료가 증명하지 않는 것**:
|
||
- `PAYPAL-IDEMP-C6`: same-key + different-body 시 동작 (body fingerprint 정책)
|
||
- 가맹점 dimension 의 명시적 분리 (인증으로 implicit 으로 추정)
|
||
- "might fail" 의 정확한 status code / 재시도 권장 backoff
|
||
- 저장소 backend (외부 관찰 불가)
|
||
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
|
||
- 2026-05-27 시점 페이지 재확인 (WebFetch 차단으로 본 migration 에서 미실행)
|
||
- ca-tmpl 의 `(principal, key, useCaseName)` triple 과 PayPal `(request_id, API call type)` pair 의 mapping (PayPal 은 가맹점 implicit)
|
||
- ca-tmpl 24h TTL 결정의 위험 (PayPal 45일 대비 매우 짧음 — 결제 분쟁 윈도우 손실 vs 저장 비용)
|
||
- ca-tmpl 200ms wait 동작이 PayPal "might fail" 보다 클라이언트 친화적이라는 해석의 정합성
|
||
|
||
## ca-tmpl 함의 (내 프로젝트 해석)
|
||
|
||
> 본 섹션은 자료 직접 인용이 아닌 ca-tmpl 결정 컨텍스트 해석. wiki 추출 시 source-summary 로 옮겨야 함.
|
||
|
||
- **key scope**: PayPal `(request_id, API call type)` ≈ ca-tmpl `(key, useCaseName)`. **principal dimension 은 PayPal 에선 인증으로 implicit**, ca-tmpl 은 explicit triple 로 박아둠 → ca-tmpl 이 멀티테넌시에서 더 명시적이고 안전.
|
||
- **TTL**: PayPal 45일 ≫ ca-tmpl 24h. ca-tmpl 이 훨씬 보수적 (저장 부하 낮음, retry 윈도우 짧음).
|
||
- **in-flight**: PayPal "might fail" (`C4`) vs ca-tmpl 200ms wait → ca-tmpl 이 결정적·사용자 친화적 (단, 표준 동작은 아님 — IETF draft 는 409 즉시 권장).
|
||
- **fingerprint**: PayPal 미명시 (`C6`) vs ca-tmpl 422 명시 → ca-tmpl 이 더 엄격.
|
||
|
||
## 메모 / Notes
|
||
|
||
- **2026-05-27 재검증 완료**: WebFetch 성공. C2/C4/C5 verbatim 일치 → `official-vendor-doc` upgrade. C1 partial. **C3 (45일 TTL) NOT FOUND** — PayPal 이 페이지에서 구체 일수를 제거했을 가능성 (현재는 "for a period of time" 만 명시).
|
||
- ca-tmpl 24h TTL vs PayPal 45일 비교 분석을 사용하는 모든 downstream claim 은 PayPal 의 45-day 출처를 다른 페이지/archive snapshot/changelog 으로 보강 필요. C3 인용을 그대로 외부 산출물에 사용 금지.
|
||
|
||
## Related / 관련
|
||
|
||
- 같은 주제 다른 raw:
|
||
- [[raw/official-docs/idempotency-stripe-api-ref]]
|
||
- [[raw/official-docs/idempotency-ietf-draft]]
|
||
- [[raw/company-tech-blogs/idempotency-toss-payments-techblog]]
|
||
- 인용하는 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 요약: (미작성)
|