모바일 앱이 응답을 받기 전에 네트워크가 끊기면 사용자는 같은 결제나 주문 버튼을 다시 누를 수 있습니다. 서버가 첫 요청을 처리했는지 모르는 상태에서 재시도하면 중복 결제가 생깁니다. 멱등 키는 이 불확실성을 안전하게 다루는 계약입니다.
키의 범위를 거래 단위로 잡는다
같은 구매 의도를 재시도할 때는 같은 키를 쓰고, 사용자가 새 주문을 의도하면 새 키를 써야 합니다. 키를 고객과 엔드포인트 범위에서 관리하며 무한히 재사용하지 않습니다. 클라이언트가 버튼 클릭마다 새 키를 만들면 중복 방지 효과가 없습니다.
요청 내용도 함께 비교한다
같은 키로 금액이나 배송지가 다른 요청이 오면 기존 결과를 조용히 반환하면 안 됩니다. 핵심 입력의 정규화된 해시를 보관하고 다르면 충돌 오류로 돌려줍니다. 입력 정규화 기준은 API 버전과 함께 관리합니다.
처리 중 동시 요청을 막는다
두 서버가 같은 키를 거의 동시에 받으면 둘 다 '처음'이라고 판단할 수 있습니다. 데이터베이스의 고유 제약이나 원자적 잠금을 사용해 한 요청만 실행합니다. 나머지는 진행 중 상태 또는 완료된 결과를 일관되게 반환합니다.
외부 결제도 같은 경계를 이어 간다
내부 DB에서 한 번만 처리해도 외부 결제사 호출이 두 번이면 소용없습니다. 외부 API가 제공하는 멱등 기능을 연결하고, 결제 확정·주문 기록의 순서와 실패 복구를 설계합니다. 결제 결과를 모를 때는 새 결제를 시작하기 전에 먼저 조회합니다.
보관과 장애 복구를 시험한다
키와 결과를 얼마나 오래 보관할지는 재시도 가능 기간과 업무 위험에 따라 정합니다. 응답 전 서버 재시작, 두 번의 동시 클릭, 외부 응답 지연을 테스트합니다. 중복 방지가 고객에게 재시도 가능하다는 확신을 주어야 합니다.
현장에 적용할 때의 순서
- 구매 의도별 키 발급
- 키·입력 해시 원자적 저장
- 외부 호출 결과와 재시도 연결
주의할 실패: 재시도마다 새 키 생성
관찰할 지표: 중복 거래 수와 키 충돌 수
적용 전 체크리스트
- 같은 구매 의도에서 같은 키를 재사용하는가
- 같은 키·다른 내용은 충돌로 처리하는가
- 동시 요청과 외부 API 재시도를 테스트했는가
참고 자료
Stripe Idempotent requests. Stripe API의 멱등 요청 개념을 참고했습니다. 실제 보관 기간과 응답 계약은 해당 서비스의 API 정책으로 정해야 합니다.
이미지와 도식은 이해를 돕기 위한 개념 시각화입니다. 특정 고객의 실제 설비·데이터·화면을 재현한 것이 아닙니다.
#멱등성 #API설계 #결제시스템 #주문처리 #재시도 #중복방지 #백엔드 #분산시스템 #트랜잭션 #웹서비스