웹훅 재시도 vs 수동 재실행: 더 안전한 복구 설계
UX와 지원 부담을 비교하고, 이중 청구와 중복 레코드를 방지하는 재실행 도구 패턴을 알아보세요.

웹훅이 실패하면 무엇이 깨지나
웹훅 실패는 흔히 "단순한 기술적 문제"가 아닙니다. 사용자 입장에서는 앱이 뭔가를 깜빡한 것처럼 보입니다: 주문이 "대기 중"으로 남아 있고, 구독이 열리지 않거나, 티켓이 "결제 완료"로 이동하지 않거나, 배송 상태가 틀리게 표시됩니다.
대부분의 사람은 웹훅 자체를 보지 않습니다. 그저 귀사의 서비스와 은행, 메일함, 대시보드가 서로 다른 상태를 보여주는 것을 봅니다. 돈이 오가는 경우라면 신뢰가 빠르게 무너집니다.
실패는 보통 지루한 이유로 발생합니다. 엔드포인트가 느려서 타임아웃이 나거나, 배포 중 서버가 500을 반환하거나, 네트워크 홉이 요청을 떨어뜨리거나, 실제로 작업이 끝났는데 응답을 너무 늦게 보내는 경우도 있습니다. 제공자는 이런 상황들을 "전달되지 않음"으로 보아서 재시도하거나 이벤트를 실패로 표시합니다.
복구 설계는 중요합니다. 웹훅 이벤트는 종종 되돌릴 수 없는 행동을 나타냅니다: 결제 완료, 환불 발행, 계정 생성, 비밀번호 재설정, 발송 등. 이벤트를 놓치면 데이터가 틀려지고, 두 번 처리하면 이중 청구나 중복 생성이 발생할 수 있습니다.
따라서 "웹훅 재시도 vs 수동 재실행"은 단순한 엔지니어링 선택이 아니라 제품 결정입니다. 두 가지 경로가 있습니다:
- 제공자 자동 재시도: 발신자가 성공 응답을 받을 때까지 일정한 스케줄로 다시 시도합니다.
- 귀사의 수동 재실행: 누군가(지원팀이나 관리자)가 문제가 의심될 때 재처리를 수동으로 트리거합니다.
사용자는 놀람 없이 신뢰성을 기대합니다. 시스템은 대부분의 경우 스스로 복구할 수 있어야 하고, 사람이 개입할 때는 어떤 일이 일어날지 명확해야 하며 두 번 눌러도 안전해야 합니다. 노코드 환경에서도 모든 웹훅을 "다시 도착할 수 있다"고 가정하세요.
자동 재시도: 어디에서 도움이 되고 어디에서 해가 되는가
자동 재시도는 웹훅의 기본 안전망입니다. 대부분의 제공자는 네트워크 오류와 타임아웃에 대해 백오프 전략으로(몇 분, 그다음 몇 시간) 재시도하고 보통 하루나 이틀 후에는 중단합니다. 위안이 되지만, 사용자 경험과 지원 이야기 둘 다를 바꿉니다.
사용자 측면에서는 재시도가 "결제 확인"의 깔끔한 순간을 어색한 지연으로 바꿀 수 있습니다. 고객은 제공자 페이지에서 성공을 보았지만 귀사의 앱은 다음 재시도까지 "대기 중"으로 남아 있을 수 있습니다. 반대 상황도 있습니다: 한 시간의 다운타임 후에 재시도가 폭주해서 오래된 이벤트들이 한꺼번에 "따라잡히는" 경우입니다.
지원 티켓은 재시도가 잘 동작하면 줄어들지만 남는 티켓은 더 어려워집니다. 하나의 명백한 실패 대신 여러 번의 전달, 다양한 응답 코드, 원래 액션과 최종 성공 사이의 긴 간극을 파헤쳐야 합니다. 그 간극은 설명하기 어렵습니다.
재시도는 다운타임이 지연된 전달의 급증을 유발하거나, 느린 핸들러가 작업은 끝났는데 계속 타임아웃이 나거나, 시스템이 멱등하지 않아 중복 생성이나 이중 청구를 유발할 때 실질적인 운영 고통을 초래합니다. 또한 불안정한 동작을 숨겨 패턴이 될 때까지 드러나지 않게 할 수 있습니다.
재시도는 실패 처리 로직이 단순할 때 보통 충분합니다: 비화폐적 업데이트, 두 번 적용해도 안전한 작업, 약간의 지연이 허용되는 이벤트 등. 이벤트가 금전 이동이나 영구 기록 생성과 관련되면 "재시도 vs 재실행" 문제는 편의성보다 통제에 관한 문제가 됩니다.
수동 재실행: 통제, 책임 소재, 그리고 트레이드오프
수동 재실행은 제공자의 재시도 스케줄 대신 사람이 웹훅 이벤트를 다시 처리하기로 결정하는 것입니다. 재실행 버튼을 누르는 사람은 지원 담당자, 고객사 관리자, 또는(저위험 사례에서는) 최종 사용자가 될 수 있습니다. 재실행은 속도보다 사람의 통제를 선호하는 방식입니다.
사용자 경험은 엇갈립니다. 금액이 큰 사건에서는 재실행 버튼이 짧은 시간 안에 하나의 사례를 고쳐주지만, 많은 문제는 누군가 인지하고 조치할 때까지 더 오래 방치됩니다.
지원 업무량은 보통 증가합니다. 재실행은 침묵하던 실패를 티켓과 후속 조치로 바꾸기 때문입니다. 반면 장점은 명확성입니다: 지원은 무엇이 재실행되었는지, 언제, 누가, 왜를 확인할 수 있습니다. 금전, 접근 권한, 법적 기록이 걸린 경우 그 감사 기록은 중요합니다.
보안은 까다롭습니다. 재실행 도구는 권한과 범위가 좁아야 합니다:
- 신뢰할 수 있는 역할만 재실행할 수 있게 하고, 특정 시스템에 대해서만 허용하세요.
- 재실행은 "모두 재실행"이 아니라 단일 이벤트 단위로 제한하세요.
- 모든 재실행은 이유, 작업자, 타임스탬프와 함께 기록하세요.
- UI에서 민감한 페이로드 데이터는 마스킹하세요.
- 남용과 실수로 인한 스팸을 방지하기 위한 속도 제한을 두세요.
수동 재실행은 청구서 생성, 계정 프로비저닝, 환불 등 이중 청구나 중복 생성의 위험이 큰 작업에 선호됩니다. 또한 "결제 확정 후 주문 생성"처럼 검토 단계가 필요한 팀에도 적절합니다.
재시도와 재실행 사이를 선택하는 방법
자동 재시도와 수동 재실행 사이를 고르는 규칙은 하나로 정할 수 없습니다. 가장 안전한 접근은 혼합입니다: 위험이 낮은 이벤트는 자동으로 재시도하고, 비용이 들거나 복잡한 중복을 초래할 수 있는 이벤트는 의도적인 재실행을 요구하세요.
먼저 각 웹훅 이벤트를 위험도별로 분류하세요. 배송 상태 업데이트는 지연되면 불편하지만 장기적 손해를 거의 주지 않습니다. 반면 payment_succeeded나 create_subscription 이벤트는 한 번 더 실행되면 이중 청구 또는 중복 생성의 위험이 있어 고위험입니다.
그다음 누가 복구를 트리거할 수 있는지 결정하세요. 시스템 자동 재시도는 작업이 안전하고 빠를 때 훌륭합니다. 민감한 이벤트는 지원이나 운영이 고객 계정과 제공자 대시보드를 확인한 후 재실행하도록 하는 것이 낫습니다. 최종 사용자가 재실행할 수 있게 하는 것은 저위험 작업에선 괜찮지만 반복 클릭으로 중복이 생길 위험이 있습니다.
시간 창도 중요합니다. 재시도는 보통 몇 분 내 혹은 몇 시간 내에 발생하도록 설계되어 일시적 문제를 치유합니다. 수동 재실행은 더 길게 허용할 수 있지만 무기한으로 두지는 마세요. 일반 규칙은 비즈니스 문맥이 여전히 유효한 기간(예: 주문 출하 전, 청구 기간 마감 전)을 허용하고 그 이후에는 더 신중한 조정 절차를 요구하는 것입니다.
간단한 체크리스트:
- 두 번 실행되면 최악의 상황은 무엇인가?
- 누구(시스템, 지원, 운영, 사용자)가 결과를 검증할 수 있는가?
- 얼마나 빨리 성공해야 하는가(초, 분, 일)?
- 허용 가능한 중복률은 얼마인가(금전의 경우 거의 0)?
- 사건 당 허용 가능한 지원 시간은 얼마인가?
예: create_invoice를 놓쳤다면 짧은 재시도 루프면 괜찮을 수 있습니다. charge_customer를 놓쳤다면 명확한 감사 기록과 멱등성 검사로 수동 재실행을 선호하세요.
노코드 도구(예: AppMaster)로 흐름을 구축한다면, 각 웹훅을 비즈니스 프로세스로 보고 복구 경로를 명시하세요: 안전한 단계는 자동 재시도, 고위험 단계는 확인이 필요하고 무엇이 일어날지 보여주는 별도 재실행 액션으로 처리하세요.
멱등성과 중복 제거 기본
멱등성은 같은 웹훅을 여러 번 처리해도 결과가 한 번 처리한 것과 같다는 뜻입니다. 제공자가 재시도하거나 지원 담당자가 재실행해도 최종 결과는 한 번 처리한 것과 같아야 합니다. 이것이 안전한 복구의 기초입니다.
신뢰할 수 있는 멱등성 키 선택하기
핵심은 "우리가 이미 적용했는가?"를 어떻게 판단하느냐입니다. 제공자가 무엇을 주는지에 따라 좋은 옵션이 달라집니다:
- 제공자의 이벤트 ID(안정적이고 고유하면 최선)
- 제공자의 전달 ID(재시도 진단에 유용하지만 항상 이벤트와 동일하지 않을 수 있음)
- 귀사 내부의 복합 키(예: 제공자 + 계정 + 객체 ID + 이벤트 타입)
- 원시 페이로드의 해시(다른 옵션이 없을 때, 단 공백이나 필드 순서에 주의)
- 제공자에게 반환하는 생성된 키(해당 API가 이를 지원할 때만 가능)
제공자가 고유 ID를 보장하지 않으면, 페이로드를 고유성의 기준으로 신뢰하지 말고 비즈니스 의미 기반의 복합 키를 만드세요. 결제의 경우 charge나 invoice ID와 이벤트 타입을 조합할 수 있습니다.
중복 제거를 어디에서 강제할지
한 레이어에만 의존하는 것은 위험합니다. 더 안전한 설계는 여러 지점을 확인합니다: 웹훅 엔드포인트(빠른 거부), 비즈니스 로직(상태 확인), 데이터베이스(강력한 보장). 데이터베이스는 최종 잠금 장치입니다: 처리된 키를 고유 제약이 있는 테이블에 저장해 두 워커가 동시에 동일 이벤트를 적용하지 못하게 하세요.
순서가 뒤바뀐 이벤트는 다른 문제입니다. 중복 제거는 중복을 막지만 오래된 업데이트가 최신 상태를 덮어쓰는 것을 막지 못합니다. 타임스탬프, 시퀀스 번호, 또는 "항상 앞으로만 이동" 규칙 같은 간단한 가드를 사용하세요. 예: 주문이 이미 Paid로 표시되어 있으면 나중에 들어온 "Pending" 업데이트는 무시합니다.
노코드 빌드에서는 processed_webhooks 같은 테이블을 모델링하고 멱등성 키에 고유 인덱스를 추가하세요. 그런 다음 비즈니스 프로세스가 먼저 레코드 생성을 시도하고 실패하면 처리를 중단하고 제공자에게 성공을 반환하도록 하세요.
단계별: 기본값으로 안전한 재실행 도구 설계
좋은 재실행 도구는 문제가 생겼을 때의 패닉을 줄입니다. 재실행은 동일한 안전한 처리 경로를 다시 실행하고 중복을 방지하는 가드레일을 제공할 때 가장 잘 작동합니다.
1) 먼저 캡처하고, 그다음에 행동하라
들어오는 각 웹훅을 감사 레코드로 취급하세요. 원시 바디를 받은 그대로 저장하고, 서명과 타임스탬프 같은 핵심 헤더와 전달 메타데이터(수신 시간, 제공자의 시도 번호 등)를 보관하세요. 정규화된 이벤트 식별자도 파생해서 저장하세요.
서명을 검증하되, 비즈니스 액션을 실행하기 전에 메시지를 영구 저장하세요. 처리 도중 크래시가 나더라도 원본 이벤트가 남아 있으면 무엇이 도착했는지 증명할 수 있습니다.
2) 핸들러를 멱등하게 만들기
프로세서는 두 번 실행되어도 동일한 최종 결과를 내야 합니다. 레코드 생성, 카드 청구, 접근 권한 부여 전에 이 이벤트(또는 이 비즈니스 작업)가 이미 성공했는지 확인해야 합니다.
핵심 규칙은 단순합니다: 하나의 이벤트 ID + 하나의 액션 = 하나의 성공 결과. 이전에 성공한 기록이 보이면 액션을 반복하지 말고 성공을 다시 반환하세요.
3) 사람이 사용할 수 있도록 결과를 기록하라
재실행 도구는 그 이력이 있어야 쓸모가 있습니다. 처리 상태와 지원이 이해할 수 있는 짧은 이유를 저장하세요:
- Success(생성된 레코드 ID 포함)
- Retryable failure(타임아웃, 일시적 업스트림 문제)
- Permanent failure(잘못된 서명, 필수 필드 누락)
- Ignored(중복 이벤트, 순서가 뒤바뀐 이벤트)
4) 재실행은 핸들러를 다시 실행하라, "재생성"하지 말라
재실행 버튼은 저장된 페이로드로 동일한 핸들러를 호출하는 작업을 큐에 넣어야 합니다. UI가 직접 "지금 주문 생성" 같은 쓰기를 수행하게 하지 마세요. 이는 중복 제거 로직을 우회합니다.
고위험 이벤트(결제, 환불, 요금제 변경 등)에 대해서는 미리보기 모드를 추가해 어떤 레코드가 생성/업데이트되고, 어떤 항목이 중복으로 건너뛰어질지 보여주세요.
노코드 도구에서는 재실행 액션을 항상 멱등성 로직을 거치는 단일 백엔드 엔드포인트나 비즈니스 프로세스로 유지하세요.
지원팀이 문제를 빠르게 해결할 수 있게 무엇을 저장할지
웹훅이 실패하면 지원은 기록이 명확한 만큼만 빠르게 도울 수 있습니다. 유일한 단서는 "500 에러"뿐이라면 다음 단계는 추측이 되고, 추측은 위험한 재실행으로 이어집니다.
좋은 저장 설계는 무서운 사고를 일상 점검으로 바꿉니다: 이벤트를 찾고, 무슨 일이 있었는지 보고, 안전하게 재실행하고, 무엇이 바뀌었는지 증명할 수 있어야 합니다.
들어오는 각 이벤트마다 작고 일관된 웹훅 전달 레코드를 저장하세요. 이 기록은 비즈니스 데이터(주문, 송장, 사용자)와 분리해 두어 실패를 조사할 때 프로덕션 상태를 건드리지 않게 하세요.
최소한 다음을 저장하세요:
- 제공자 이벤트 ID, 소스/시스템 이름, 엔드포인트 또는 핸들러 이름
- 수신 시간, 현재 상태(신규, 처리 중, 성공, 실패), 처리 소요 시간
- 시도 횟수, 다음 재시도 시간(있다면), 마지막 오류 메시지와 오류 타입/코드
- 이벤트를 귀사의 객체와 연결하는 상관 ID(user_id, order_id, invoice_id, ticket_id)와 제공자 ID
- 페이로드 처리 상세: 원시 페이로드(또는 암호화된 블롭), 페이로드 해시, 스키마/버전
상관 ID가 있으면 지원이 효과적입니다. 지원 담당자는 "Order 18431"을 검색하면 관련된 모든 웹훅(성공/실패 포함)을 즉시 볼 수 있어야 합니다.
수동 작업에 대한 감사도 유지하세요. 누군가 재실행하면 누가 언제 UI/API에서 했는지 결과와 함께 기록하세요. 또한 "invoice marked paid" 또는 "customer record created" 같은 한 줄 요약을 저장하면 분쟁 해결에 도움이 됩니다.
보존 기간도 중요합니다. 로그는 싸지만 무한정 보관하면 안 되고 페이로드에 개인 데이터가 포함될 수 있습니다. 명확한 규칙(예: 전체 페이로드는 7–30일, 메타데이터는 90일)과 보존 정책을 정하세요.
관리자 화면은 답을 쉽게 만들어야 합니다. 이벤트 ID와 상관 ID로 검색, 상태와 "주의 필요" 필터, 시도와 오류의 타임라인, 확인과 멱등성 키가 보이는 안전한 재실행 버튼, 내부 사고 노트용 내보내기 기능을 포함하면 좋습니다.
이중 청구와 중복 레코드 방지
"웹훅 재시도 vs 수동 재실행"에서 가장 큰 위험은 재시도 자체가 아니라 부작용을 반복하는 것입니다: 카드 이중 청구, 구독 중복 생성, 같은 주문의 중복 발송 등.
더 안전한 설계는 "금전 이동"과 "비즈니스 이행"을 분리합니다. 결제의 경우 결제 의도 생성(또는 인가), 캡처, 그다음 이행(주문을 결제 완료로 표시, 접근 해제, 발송)으로 나누세요. 웹훅이 두 번 도착하면 두 번째 실행은 "이미 캡처됨" 또는 "이미 이행됨"을 보고 중단해야 합니다.
청구를 생성할 때 제공자 측 멱등성 기능을 사용하세요. 대부분의 결제 제공자는 동일한 요청에 대해 같은 결과를 반환하도록 하는 멱등성 키를 지원합니다. 이 키를 내부 주문에 저장해 재시도 시 재사용하세요.
데이터베이스 내부에서도 레코드 생성을 멱등하게 만드세요. 가장 간단한 가드는 외부 이벤트 ID나 객체 ID(예: charge_id, payment_intent_id, subscription_id)에 대한 고유 제약입니다. 동일한 웹훅이 다시 들어오면 삽입이 실패하고 기존 레코드를 불러와 처리를 이어가면 됩니다.
상태 전환은 현재 상태가 기대치와 일치할 때만 앞으로 이동하도록 가드하세요. 예: 주문을 pending에서 paid로 옮길 때 이미 paid면 아무 것도 하지 마세요.
부분 실패는 흔합니다: 결제는 성공했지만 DB 쓰기가 실패한 경우 등. 이를 위해 먼저 영구적인 "수신 이벤트" 레코드를 저장한 후 처리하세요. 지원이 나중에 이벤트를 재실행하면 핸들러가 누락된 단계를 완료하면서 다시 청구하지 않습니다.
문제가 생겼을 때는 보상 조치(인가 취소, 환불, 이행 취소)를 정의하세요. 재실행 도구는 이러한 옵션을 명시적으로 보여줘 사람이 추측하지 않고 결과를 수정할 수 있게 해야 합니다.
흔한 실수와 함정
대부분의 복구 계획은 웹훅을 "다시 누를 수 있는 버튼"으로 취급해서 실패합니다. 첫 시도가 이미 무언가를 변경했다면 두 번째 시도는 카드 중복 청구나 중복 레코드 생성으로 이어질 수 있습니다.
흔한 함정은 원본 페이로드를 먼저 저장하지 않고 재실행하는 것입니다. 지원이 나중에 재실행을 클릭하면 오늘 재구성한 데이터가 전송될 수 있고, 이는 도착한 정확한 메시지가 아니어서 감사와 재현을 깨뜨립니다.
또 다른 함정은 타임스탬프를 멱등성 키로 사용하는 것입니다. 두 이벤트가 같은 초에 발생할 수 있고, 시계가 어긋나거나 재실행은 몇 시간 후에 발생할 수 있습니다. 멱등성 키는 제공자의 고유 이벤트 ID(또는 페이로드의 안정적인 유니크 해시)에 묶어야 합니다.
지원 티켓을 유발하는 레드 플래그:
- 상태 확인 없이 멱등하지 않은 액션을 재시도함(예: 이미 존재하는 송장을 또 생성함)
- 재시도 가능한 오류(타임아웃, 503)와 영구 오류(잘못된 서명, 필수 필드 누락)를 구분하지 않음
- 누구나 사용할 수 있는 재실행 버튼, 이유 필드 없음, 감사 기록 없음
- 실제 버그를 숨기고 다운스트림 시스템을 계속 때리는 자동 재시도 루프
- 시도 횟수를 제한하지 않거나 같은 이벤트가 계속 실패할 때 사람에게 알리지 않는 "발사하고 잊기"식 재시도
혼합 정책도 주의하세요. 팀이 두 시스템을 따로 활성화해 동일 이벤트를 두 번 재전송하는 경우가 있습니다.
간단한 시나리오: 결제 웹훅이 도착했을 때 귀사의 앱이 주문을 저장하는 중 타임아웃이 났습니다. 재시도가 들어와서 만약 재시도가 "고객에게 다시 과금"하는 식으로 설계되어 있으면 큰 문제가 생깁니다. 안전한 재실행 도구는 항상 현재 상태를 먼저 확인하고 누락된 단계만 적용합니다.
출시 전 빠른 체크리스트
복구를 부가 기능으로 보지 마세요. 항상 안전하게 다시 실행할 수 있어야 하고, 무슨 일이 있었는지 설명할 수 있어야 합니다.
실용적인 사전 출시 체크리스트:
- 비즈니스 로직 실행 전에 들어오는 모든 웹훅 이벤트를 영구 저장하세요. 원시 바디, 헤더, 수신 시간, 안정적인 외부 이벤트 ID를 보관하세요.
- 이벤트당 하나의 안정적인 멱등성 키를 사용하고 모든 재시도와 수동 재실행에 재사용하세요.
- 데이터베이스 수준에서 중복 제거를 강제하세요. 외부 ID(결제 ID, 송장 ID, 이벤트 ID)에 고유 제약을 두어 두 번째 실행이 두 번째 행을 만들지 못하게 하세요.
- 재실행은 명시적이고 예측 가능하게 만들고, 결제 캡처나 되돌릴 수 없는 프로비저닝 같은 위험한 동작은 확인을 요구하세요.
- 엔드투엔드 상태를 명확히 추적하세요: received, processing, succeeded, failed, ignored. 마지막 오류 메시지, 시도 횟수, 누가 재실행했는지 포함하세요.
끝내기 전에 지원 시나리오를 테스트하세요. 누군가 한 분 안에 대답할 수 있어야 합니다: 무슨 일이 있었고, 왜 실패했으며, 재실행 후 무엇이 바뀌었는가?
노코드로 이것을 만든다면 먼저 Data Designer에 이벤트 로그를 모델링하고, 멱등성을 확인하는 안전한 재실행 액션을 가진 작은 관리자 화면을 추가하세요. 이렇게 하면 "나중에 안전장치 추가"가 "재실행이 전혀 안전하지 않음"으로 이어지는 실수를 막을 수 있습니다.
예시: 결제 웹훅이 한 번 실패했다가 성공하는 경우
고객이 결제하고 결제 제공자가 payment_succeeded 웹훅을 보냅니다. 동시에 데이터베이스 부하로 쓰기가 타임아웃이 납니다. 제공자는 500 응답을 받아 같은 이벤트를 나중에 재시도합니다.
안전한 복구는 다음과 같습니다:
- 12:01 시도 #1이
evt_123이벤트 ID로 도착합니다. 핸들러가 시작되었지만 DBINSERT invoice에서 타임아웃으로 실패합니다. 500을 반환합니다. - 12:05 제공자가 같은 이벤트 ID
evt_123로 재시도합니다. 핸들러는 먼저 중복 테이블을 확인해 아직 적용되지 않았음을 보고 송장을 기록하고evt_123을 처리됨으로 표시한 뒤 200을 반환합니다.
중요한 부분은 두 번의 전달을 같은 이벤트로 취급해야 한다는 것입니다. 송장은 한 번만 생성되고, 주문은 한 번만 "Paid"로 이동하며, 고객은 한 장의 영수증만 받아야 합니다. 제공자가 성공 후에도 다시 재시도할 수 있는데(종종 발생), 핸들러는 evt_123이 이미 처리되었다고 읽고 아무 작업도 하지 않은 채 200을 반환해야 합니다.
로그는 지원을 불안하게 만드는 것이 아니라 확신을 주어야 합니다. 좋은 기록은 시도 #1은 "DB 타임아웃"으로 실패했고 시도 #2는 성공했고 최종 상태는 "적용됨"임을 보여줍니다.
지원 담당자가 evt_123에 대해 재실행 도구를 열면 지루해야 합니다: "이미 적용됨"을 보여주고 재실행 버튼을 누르면 안전 검사를 다시 실행할 뿐입니다. 송장 중복 생성도, 이메일 중복 발송도, 이중 청구도 발생하지 않아야 합니다.
다음 단계: 실용적인 복구 흐름 구축하기
받는 모든 웹훅 이벤트 타입을 적고 각 이벤트를 저위험/고위험으로 표시하세요. "사용자 가입"은 보통 저위험입니다. "결제 완료", "환불 발행", "구독 갱신"은 한 번의 실수가 금전 피해나 되돌리기 어려운 혼란을 낳기 때문에 고위험입니다.
그다음 최소한의 복구 흐름을 구축하세요: 들어오는 모든 이벤트를 저장하고, 멱등한 핸들러로 처리하고, 지원을 위한 최소한의 재실행 화면을 노출하세요. 목표는 화려한 대시보드가 아니라 다음 세 가지 질문에 안전하게 답하는 것입니다: "우리가 이벤트를 받았는가, 처리했는가, 그리고 그렇지 않다면 중복 없이 다시 시도할 수 있는가?"
간단한 첫 버전:
- 원시 페이로드와 제공자 이벤트 ID, 수신 시간, 현재 상태를 저장합니다.
- 동일 이벤트가 두 번 와도 두 번째가 두 번째 결제나 기록을 만들지 않도록 멱등성을 강제하세요.
- 단일 이벤트를 다시 실행하는 재실행 액션을 추가하세요.
- 마지막 오류와 마지막 처리 시도를 보여줘 지원이 무슨 일이 있었는지 알 수 있게 하세요.
이후 위험 수준에 맞춘 보호장치를 추가하세요. 고위험 이벤트는 더 엄격한 권한, 명확한 확인(예: "재실행하면 이행이 발생할 수 있습니다. 계속하시겠습니까?"), 누가 언제 재실행했는지의 완전한 감사 기록을 요구하세요.
노코드로 구현하려면 AppMaster는 이 패턴을 적용하기에 실용적입니다: 이벤트 로그를 Data Designer에 저장하고, 비즈니스 프로세스 편집기에서 멱등한 워크플로를 구현하며, UI 빌더로 내부 재실행 관리자 패널을 제공합니다.
배포 방식도 초기에 결정하세요. 클라우드든 자체 호스팅이든 지원팀이 로그와 재실행 화면에 안전하게 접근할 수 있어야 하고, 보존 정책이 요금 분쟁과 고객 문의를 해결할 만큼 충분한 기록을 유지하도록 하세요.


