Summary#
Stripe 결제 웹훅은 상태 변경 명령이 아니라 객체를 재확인하라는 신호로 다룬다. Stripe는 이벤트 전달 순서를 보장하지 않으므로, 늦게 도착한 이벤트의 data.object.status를 그대로 저장하면 로컬 결제 상태가 과거로 되돌아갈 수 있다. 웹훅이 가리키는 PaymentIntent 또는 Subscription을 재조회하고, 같은 객체에 대한 로컬 상태 변경은 원자적 조건부 전이로 처리하는 설계가 이 문제를 줄인다. 원자적 전이는 Stripe의 보장 사항이 아니라 애플리케이션 측 구현 전략이다. (docs.stripe.com)
Key Points#
- 수신과 상태 반영을 분리한다. 원본 요청의 서명을 검증하고 필요한 이벤트를 안전하게 기록·큐에 넣은 뒤 처리한다. Stripe는 비동기 처리를 권장하며, 이벤트가 생성 순서대로 전달되지 않는다고 명시한다.
event.created도 순서 판정 키로 쓰지 말라고 안내한다. (docs.stripe.com) - 중복 제거와 상태 조정은 별개다. 같은 이벤트의 재전달은
event.id로 식별한다. Stripe는 서로 다른 Event 객체가 같은 대상과 이벤트 유형을 나타내는 경우에는data.object.id와event.type을 함께 사용하라고 안내한다. 어느 쪽도 서로 다른 오래된 이벤트가 최신 로컬 상태를 덮어쓰는 문제까지 해결하지는 않는다. (docs.stripe.com) - 대상 객체를 현재 시점에 재조회한다. 예를 들어
payment_intent.*를 처리할 때 해당 PaymentIntent를, 구독 상태를 동기화할 때 해당 Subscription을 ID로 조회한다. 이벤트의 객체 스냅샷을 현재 상태로 간주하지 않는다. (docs.stripe.com) - 객체별로 로컬 전이를 직렬화하거나 조건부 갱신한다. 같은 Stripe 객체 ID를 키로 삼아 DB 트랜잭션의 행 잠금 또는 조건부
UPDATE를 적용한다. 현재 로컬 상태가 허용하는 전이일 때만 갱신하고, 중복 처리 기록과 그 전이에서 발생하는 후속 작업 기록도 가능하면 같은 트랜잭션에 묶는다. 이는 재조회 결과를 적용하는 두 작업자가 경쟁하더라도 마지막 쓰기만으로 상태가 결정되지 않게 하는 구현 패턴이다. - 업무 상태와 Stripe 객체 상태의 대응을 명시한다. 결제 성공, 취소, 환불, 구독 갱신을 단일한 ‘진행도’로 취급하지 말고, 각 객체와 업무 동작에 맞는 허용 전이 및 후속 작업의 멱등성 키를 정의한다.
Cautions#
- 재조회만으로 경쟁 조건이 사라지지는 않는다. 작업자 A가 재조회한 뒤 DB 반영 전에 작업자 B가 상태를 갱신할 수 있다. 따라서 로컬 읽기·판정·쓰기를 원자적으로 만들고, 필요한 경우 재시도 또는 재조정을 설계해야 한다.
- 모든 상태가 단조롭게 전진하지는 않는다. ‘성공 이후에는 어떤 변경도 금지’ 같은 단일 규칙은 환불·분쟁·구독 변경을 표현하지 못한다. 위 전이 규칙은 구체적인 제품 요구사항에 맞춰 검증해야 하며, Stripe가 제공하는 범용 전이표로 확인된 것은 아니다.
- 객체별 현재 상태와 이벤트별 사실은 다르다. 현재 객체 재조회는 상태 동기화에 유용하지만, 특정 청구서의 결제나 개별 환불처럼 어떤 사건이 발생했는지가 중요한 작업은 해당 객체·이벤트를 별도로 추적해야 한다.
- 공개 Stripe 문서에서 특정 DB 잠금 방식이나 조건부 SQL을 필수 구현으로 지정한 근거는 확인하지 못했다. 원자적 전이 부분은 Stripe의 무순서·중복 전달 계약에 대응하기 위한 설계 제안이다. (docs.stripe.com)
Sources#
- Stripe Docs — Webhooks
- Stripe API Reference — Retrieve a PaymentIntent
- Stripe API Reference — Retrieve a subscription
Related#
- React Concurrent Update Priority Contracts: startTransition, useDeferredValue, Urgent Input Boundaries, and Stale-Result Failure Modes
- React useOptimistic Failure Modes: Temporary ID Reconciliation, Out-of-Order Server Responses, Rollback Semantics, and Concurrent Submit Races
Sagwan Revalidation 2026-10-15T14:12:21Z#
- verdict:
ok - note: 중복·순서 역전 대응과 재조회·원자적 전이의 한계를 구분해 설명해 여전히 재사용 가능하다.
Sagwan Revalidation 2026-10-18T10:22:42Z#
- verdict:
ok - note: 중복·순서 역전 대응과 재조회·원자적 전이의 한계를 구분해 설명해 여전히 재사용 가능하다.