같은 주문 알림이 다시 도착해도 주문 생성·재고 차감·고객 알림이 의도보다 여러 번 실행되지 않도록 설계해야 합니다. 핵심은 이벤트를 식별하고 안전하게 보관한 뒤, 업무 변경을 멱등하게 처리하며 실패한 작업을 복구할 수 있게 만드는 것입니다. ‘성공 응답을 보냈다’와 ‘주문 처리가 끝났다’를 서로 다른 상태로 관리하는 데서 시작하세요.
[01]웹훅은 왜 다시 도착하나요?
웹훅은 외부 서비스의 변경을 HTTP 요청으로 전달하는 방식입니다. 수신 측이 처리를 끝내도 응답이 전달되지 않으면 발신 측은 결과를 확신하지 못할 수 있습니다. Stripe는 중복 이벤트 수신 가능성과 전달 순서 미보장을 명시합니다. 다만 자동 재시도 여부·기간·응답 제한은 공급자마다 다르므로 연동별 계약을 확인해야 합니다.
- 이벤트 ID·전달 ID가 각각 무엇을 식별하는지 기록합니다.
- 자동 재시도, 수동 재전송, 전달 이력 조회 방법을 확인합니다.
- 같은 주문에 여러 이벤트가 생기는 경우와 순서 역전 가능성을 구분합니다.
[02]수신 성공과 업무 완료를 어떻게 나누나요?
GitHub는 10초 안에 2xx로 응답하고 필요하면 큐로 비동기 처리하도록 안내합니다. 이 제한을 모든 웹훅의 공통 규칙으로 적용하면 안 됩니다. 보이드가 제안하는 흐름은 ‘검증 → 복구 가능한 저장 → 수신 응답 → 별도 처리’입니다. 저장이나 내구성 있는 큐 등록에 실패했다면 수신 성공으로 응답하지 않도록 공급자 규칙에 맞춰 결정합니다.
서명 검증 방식은 공급자별로 구현하세요. 예를 들어 Stripe는 서명 검증에 변형되지 않은 요청 본문을 요구합니다. 검증되지 않은 요청을 업무 처리 큐에 넣지 않고, 허용한 이벤트 유형과 대상 계정을 확인하는 경계를 수신 단계에 둡니다.
[03]중복 확인만 하면 충분한가요?
멱등성은 같은 의도의 요청을 반복해도 추가 부작용을 만들지 않는 성질입니다. AWS는 요청 식별자 기록과 관련 상태 변경을 원자적으로 처리하는 중요성을 설명합니다. ‘처리 이력 조회 → 없으면 실행’만으로 구현하면 동시에 도착한 두 작업이 모두 통과할 수 있습니다.
관계형 데이터베이스에서는 계정·공급자·이벤트 식별자의 조합에 NOT NULL과 고유 제약을 적용하는 방안을 검토할 수 있습니다. PostgreSQL의 UNIQUE 제약은 한 열 또는 여러 열 조합의 중복을 제한합니다. 선점된 기록은 작업 상태와 함께 관리하고, 선점됐다는 이유만으로 완료 처리하지 마세요. 같은 데이터베이스의 업무 변경과 완료 기록은 하나의 트랜잭션으로 묶는 범위를 검토합니다.
이벤트 중복 방지와 업무 중복 방지는 별개입니다. 서로 다른 이벤트가 같은 주문의 동일 작업을 요청할 수 있다면, 그 업무의 고유 기준도 정해야 합니다. 주문 ID만으로 모든 이벤트를 막으면 정상적인 취소·변경까지 누락할 수 있으므로 ‘어떤 작업을 한 번만 실행할지’를 먼저 정의하세요.

[04]주문 연동에서 무엇을 실패로 가정해야 하나요?
다음은 실제 고객 사례가 아닌 가상의 주문 연동 검수표입니다. ‘결제 완료 알림을 받아 주문 상태를 바꾸고 출고 작업을 만든다’는 흐름을 가정했습니다. 아래 결과는 보이드가 제안하는 완료 기준이며 공급자가 보장하는 기능 목록은 아닙니다.
| 주입할 상황 | 확인할 결과 |
|---|---|
| 동일 이벤트를 동시에 두 번 전달 | 활성 처리 주체와 업무 결과가 중복 생성되지 않음 |
| 저장 직전 서버 종료 | 수신 성공으로 기록하지 않고 재전송으로 복구 가능 |
| 수신 저장 후 작업자 중단 | 미완료 작업을 찾아 다시 처리할 수 있음 |
| 업무 반영 직후 응답 유실 | 재시도 시 기존 결과를 확인하고 같은 변경을 반복하지 않음 |
| 변경·취소 알림이 뒤바뀐 순서로 도착 | 유효한 상태 전이·버전 규칙으로 주문 상태가 잘못 되돌아가지 않음 |
처리 상태는 예를 들어 대기·진행·완료·실패로 나누고, 진행 상태가 오래 남았을 때의 복구 조건을 정하세요. 처리 중 임대나 잠금을 회수할 때는 이전 작업자가 여전히 외부 호출을 수행할 가능성까지 고려해야 합니다.
[05]외부 API 호출까지 한 번만 실행되나요?
내부 주문 상태를 저장하는 것과 택배 API·메일 서비스에 요청하는 것은 서로 다른 시스템의 변경입니다. 데이터베이스 트랜잭션만으로 두 시스템을 함께 확정할 수 있다고 가정하면 안 됩니다. AWS의 트랜잭셔널 아웃박스 패턴은 업무 데이터와 보낼 메시지를 같은 트랜잭션에 기록하고, 별도 처리기가 전송하는 방식으로 이중 쓰기 문제를 다룹니다.
아웃박스 전송도 반복될 수 있으므로 수신 측 멱등 처리가 필요합니다. 외부 API가 멱등 키를 지원하면 같은 업무 의도에 같은 키를 유지하고, 응답이 유실됐을 때 결과 조회 방법을 정하세요. 지원하지 않으면 재호출 전에 상태 조회·대사 또는 담당자 확인을 거치도록 업무 위험에 맞게 설계합니다.
[06]실패한 작업을 어떻게 복구하나요?
보이드가 제안하는 운영 기준은 재시도 횟수뿐 아니라 ‘무엇을 확인한 뒤 다시 실행할 수 있는가’를 정하는 것입니다. 일시적 네트워크 실패, 잘못된 데이터, 권한 문제, 결과 불명을 나눠 담당자와 다음 동작을 정하세요. 결과 불명인 외부 호출은 무조건 반복하기보다 완료 여부를 먼저 확인할 수 있어야 합니다.
- 이벤트·업무 식별자, 시도 시각, 처리 상태, 실패 사유를 연결해 조회합니다.
- 재처리 권한을 가진 담당자가 대상과 이유를 남기고 실행하도록 합니다.
- 미완료 건수와 가장 오래 대기한 작업을 보고 확인 주기를 정합니다.
- 원문 전체나 비밀 키를 그대로 로그에 남기지 않고 필요한 식별 정보만 보관합니다.

[07]개발 착수 전에 합의할 체크리스트
- 공급자별 서명 방식, 응답 기한, 재전송·조회 수단을 확인했나요?
- 이벤트 식별자와 한 번만 수행할 업무의 기준을 구분했나요?
- 동시 중복과 중간 장애를 실제로 주입하는 검수 시나리오가 있나요?
- 업무 변경·완료 기록의 트랜잭션 경계와 외부 전송의 복구 방법이 정해졌나요?
- 재처리 권한, 미완료 알림, 인계 문서와 운영 담당자를 정했나요?
연동 견적을 요청할 때는 API 이름만 나열하기보다 이벤트 예시, 업무 상태도, 외부 서비스의 재전송 규칙과 위 검수 결과를 인도물에 포함하세요. 처음부터 하나의 주문 흐름으로 범위를 좁히면 구현 범위와 운영 책임을 함께 논의하기 쉽습니다.
- 웹훅
- API 연동
- 멱등성
- 운영 안정성




