모든 글
실전 가이드9분 소요

환불 알림을 놓치면 이의를 제기할 수 있는 유일한 환불을 잃을 수 있지만, 제때 확인하면 두 스토어 모두 되찾을 수 있습니다

서버가 환불 알림을 놓치면, 증거를 요청하는 두 가지 환불 절차가 여러분 없이 마감됩니다. Apple과 Google Play가 어떻게 재시도하는지, 놓친 환불 알림을 얼마나 과거까지 복구할 수 있는지, 그리고 복구의 빈틈은 어디인지 정리했습니다.

밤의 서버 랙. 안정적인 초록 불빛 사이에 호박색 경고등 하나가 켜져 있고, 앞쪽 카트에는 노트북이 놓여 있다. 환불 알림을 놓치게 만드는 조용한 장애의 모습

핵심 요약

  • App Store Server Notifications V2 전송에 실패하면 Apple은 이전 시도로부터 1, 12, 24, 48, 72시간 후에 총 5번 재시도합니다. 따라서 두 번째 재시도는 첫 시도 후 약 13시간이 지나서야 도착합니다.
  • Apple은 CONSUMPTION_REQUEST를 받은 후 12시간 이내에 응답하라고 요구합니다. 첫 전송과 1시간 후의 재시도를 모두 놓친 서버는, 요청을 보게 될 때쯤이면 이미 응답 기한이 지났을 가능성이 큽니다.
  • Apple의 Get Notification History 엔드포인트는 프로덕션 환경에서 지난 180일 동안의 V2 알림을 페이지당 20건씩 반환합니다. onlyFailures 플래그를 쓰면 서버에 도달하지 못한 알림과 아직 재시도 중인 알림만 조회할 수 있습니다.
  • Google Play는 지불 거절 검토를 PendingRefundReviewNotification으로만 전달하며, 24시간 이내에 orders.reviewrefund를 호출하는 데 필요한 pendingRefundToken도 이 알림에 들어 있습니다. 대기 중인 검토를 조회하는 별도의 API는 Google 문서에 없습니다.
  • Google Cloud Pub/Sub는 확인되지 않은 메시지를 기본 7일, 최대 31일 동안 보관합니다. 만료 기간을 바꾸지 않으면 31일 동안 구독자 활동이 없는 구독은 삭제됩니다.
  • Google Play Voided Purchases API로 지난 30일 동안의 환불, 취소, 지불 거절을 복구할 수 있습니다. 할당량은 하루 6,000건, 30초당 30건입니다. 하지만 한 번도 응답하지 않은 지불 거절 검토는 복구할 수 없습니다.
  • Apple 샌드박스는 알림마다 한 번만 보내고 재시도하지 않습니다. 따라서 샌드박스에서만 돌려 본 복구 루틴은 Apple의 실제 재시도 일정으로 검증된 적이 없는 셈입니다.

환불 알림을 놓치는 것은 개발자가 의견을 낼 수 있는 단 두 가지 환불 결정을 조용히 잃는 방식입니다. Apple의 CONSUMPTION_REQUEST와 Google Play의 지불 거절 검토는 모두 알림으로 시작하고, 둘 다 짧은 기한 안에 마감됩니다. Apple은 12시간, Google은 24시간입니다. 메시지가 도착했을 때 서버가 다운되었거나 느리거나 설정이 잘못되어 있어도 스토어는 기다려 주지 않습니다. 이미 가진 정보만으로 결정합니다.

좋은 소식은 두 스토어 모두 첫 실패에서 메시지를 버리지 않는다는 점입니다. Apple은 재시도하고, 조회할 수 있는 180일치 기록을 남깁니다. Google은 Pub/Sub를 통해 게시하며, 확인되지 않은 메시지를 며칠 동안 보관합니다. 나쁜 소식은 재시도 시점이 응답 기한과 맞지 않고, 두 절차 중 하나에는 복구용 API가 아예 없다는 점입니다.

각 스토어가 환불 알림을 전달하는 방식

Apple은 App Store Server Notifications를 App Store Connect에서 설정한 HTTPS URL로 직접 보냅니다. Google은 서버를 직접 호출하지 않습니다. 실시간 개발자 알림을 Google Cloud Pub/Sub 주제에 게시하고, 그 주제의 구독이 알림을 엔드포인트로 푸시하거나 서버가 가져가기를 기다립니다.

질문App StoreGoogle Play
전송 경로지정한 URL로 HTTPS POSTCloud Pub/Sub 주제, 푸시 또는 풀
성공 기준HTTP 200~206Pub/Sub 메시지 확인, 또는 푸시 엔드포인트의 성공 코드
재시도V2는 5회, 이전 시도로부터 1, 12, 24, 48, 72시간 후확인되거나 보관 기간이 끝날 때까지 Pub/Sub가 재전송
놓친 메시지의 보관 기간Get Notification History에 180일구독에 기본 7일, 최대 31일
증거를 요청하는 환불CONSUMPTION_REQUEST, 12시간 이내 응답PendingRefundReviewNotification, 24시간 이내 응답
확정된 환불의 풀 방식 백업Get Notification History, Get Refund HistoryVoided Purchases API, 지난 30일
샌드박스 또는 테스트 동작한 번만 시도, 재시도 없음Play Console의 Send Test Message

Apple이 실패로 보는 경우

Apple 문서는 구체적입니다. 200에서 206 사이의 상태 코드를 반환하면 전송이 완료됩니다. 40x나 50x를 반환하면 Apple이 재시도합니다. 그 밖의 모든 코드도 실패로 간주합니다. 시도마다 sendAttemptResult가 기록되는데, 그 값은 실제 장애 체크리스트처럼 보입니다. TIMED_OUT, TLS_ISSUE, CIRCULAR_REDIRECT, NO_RESPONSE, PREMATURE_CLOSE, UNSUCCESSFUL_HTTP_RESPONSE_CODE 등이 있습니다. TIMED_OUT에 대해 Apple은 서버가 요청 안에서 메시지를 동기적으로 처리하고 있지 않은지 확인하라고 권합니다.

Google이 실패로 보는 경우

푸시 구독에서는 엔드포인트가 성공 응답 코드를 반환하는 것이 곧 확인입니다. 풀 구독에서는 서버가 가져온 메시지를 하나하나 확인해야 하며, 그렇지 않으면 Pub/Sub가 다시 전달합니다. 확인 기한은 기본 10초, 최대 600초입니다. Google의 RTDN 가이드에는 다시 강조할 만한 규칙이 하나 더 있습니다. 알림은 무언가가 바뀌었다는 사실만 알려 주므로, 전체 구매 상태는 여전히 Google Play Developer API를 호출해 가져와야 합니다.

Apple의 재시도 일정이 12시간 기한과 맞지 않는 이유

Apple의 재시도 간격은 첫 시도가 아니라 이전 시도를 기준으로 계산됩니다. 이를 합산하면, 서버가 계속 실패하는 V2 알림 하나는 다음과 같은 일정을 따릅니다.

시도이전 시도 후 대기 시간첫 시도 후 경과 시간
첫 전송없음0
재시도 11시간1
재시도 212시간13
재시도 324시간37
재시도 448시간85
재시도 572시간157

Apple은 CONSUMPTION_REQUEST를 받은 후 12시간 이내에 응답하라고 합니다. 첫 전송과 1시간 후의 재시도 때 서버가 모두 다운되어 있었다면, 다음 시도는 첫 전송 후 13시간이 지나서야 도착합니다. 재시도로 처음 받은 요청에 새로 12시간이 주어지는지는 Apple이 밝히지 않았습니다. 신중하게 해석하면 첫 시도를 기한의 시작점으로 봐야 하며, 이는 한 시간 넘게 놓친 요청은 재시도만으로는 살릴 수 없다는 뜻입니다.

HTTP 400을 반환한 뒤에도 Apple이 재시도하나요?

문서에 따르면 그렇습니다. Apple은 재시도를 유발하는 코드로 40x와 50x를 명시합니다. 2026년 3월, 한 개발자가 Apple 포럼에서 400 응답 후 재시도가 멈춘 것 같다고 보고했다가, 하루 이틀 뒤 전송이 재개되었다고 덧붙였고, Apple은 Feedback Assistant로 보고해 달라고 요청했습니다. 문서에 나온 동작을 규칙으로 삼고, 여러분의 모니터링을 그 증거로 삼으세요.

Get Notification History로 놓친 App Store 알림 복구하기

Get Notification History는 지정한 기간 동안 Apple이 서버로 보내려고 시도한 버전 2 알림을 반환합니다. 각 레코드에는 서명된 페이로드 전체가 들어 있으므로, 실시간 알림과 같은 핸들러에 그대로 넘길 수 있습니다. 각 레코드에는 최대 6개 항목의 sendAttempts 배열도 있으며, 첫 시도와 다섯 번의 재시도에 하나씩 대응합니다.

  • startDate와 endDate는 필수이며, startDate는 프로덕션에서는 지난 180일 이내, 샌드박스에서는 지난 30일 이내여야 합니다.
  • onlyFailures를 true로 설정하면 서버에 도달하지 못한 알림과 Apple이 아직 재시도 중인 알림만 받습니다.
  • CONSUMPTION_REQUEST나 REFUND 같은 notificationType 하나로 필터링하거나, 고객 한 명의 transactionId로 필터링할 수 있지만, 한 요청에서 둘을 함께 쓸 수는 없습니다.
  • 호출당 최대 20건을 반환합니다. hasMore가 true인 동안 paginationToken으로 계속 호출하고, 매번 같은 요청 본문을 보내세요.

환불에 관해서는 주의할 점이 하나 있습니다. Apple에 따르면 기록의 레코드는 현재가 아니라 알림이 처음 전송된 시점의 구매 상태를 반영합니다. 따라서 복구한 REFUND는 과거의 사실입니다. 접근 권한을 회수하기 전에 거래 또는 구독 상태 엔드포인트로 현재 상태를 확인하세요.

V1 알림은 이 방법으로 복구할 수 없습니다

Get Notification History는 버전 2만 다룹니다. Apple은 V1 알림을 이전 시도로부터 6, 24, 48시간 후에 세 번 재시도하며, 모두 실패하면 다시 재생할 기록이 남지 않습니다. 아직 V1을 쓰는 앱을 V2로 옮겨야 할 이유가 하나 더 생기는 셈입니다.

놓친 Google Play 환불 알림 복구하기

Google의 안전망은 Pub/Sub 자체입니다. 구독이 존재하는 한, 아무도 확인하지 않은 메시지는 보관 기간 동안 그대로 남아 있습니다. 기본 7일이며, 늘리면 최대 31일입니다. 엔드포인트가 복구되면 전송도 다시 시작됩니다. 다만 두 가지 설정이 이 보호 장치를 조용히 무력화할 수 있습니다.

  • 데드 레터 주제는 정해진 횟수만큼 전송에 실패한 메시지를 구독 밖으로 옮깁니다. 기본값은 5회이며, 즉시 재전송하는 기본 재시도 정책에서는 다섯 번의 시도가 금방 지나갈 수 있습니다. 데드 레터 주제를 쓴다면 두 번째 받은편지함처럼 지켜보세요.
  • 열린 연결, 진행 중인 풀, 성공한 푸시 같은 구독자 활동이 없는 구독은 기본적으로 31일 후 만료됩니다. 한 달 동안 고장 난 채로 있는 엔드포인트는 구독 자체와 그 안에서 대기 중이던 모든 메시지를 잃을 수 있습니다.

무효화된 환불에는 30일 백업이 있습니다

이미 발생한 환불에는 Voided Purchases API가 풀 방식의 백업입니다. 지난 30일 동안 무효화된 구매를 페이지당 최대 1,000건씩 조회할 수 있으며, 할당량은 앱마다 하루 6,000건, 30초당 30건입니다. type 1을 전달하면 일회성 상품과 함께 구독도 포함됩니다. 매일 실행하면 알림 파이프라인이 놓친 환불을 잡아낼 수 있어, 이용 권한과 매출 수치를 정확하게 유지할 수 있습니다.

지불 거절 검토에는 백업이 없습니다

PendingRefundReviewNotification은 다릅니다. 이 알림에는 orders.reviewrefund에 전달해야 하는 pendingRefundToken이 들어 있으며, 알림을 받은 시점부터 24시간 안에 환불 선호 의견과 사용 증거를 보내야 합니다. Google은 첫 번째 호출만 기록하고 나머지는 무시합니다. 대기 중인 검토를 조회하는 엔드포인트는 Google 문서에 나와 있지 않으므로, 해당 Pub/Sub 메시지를 잃으면 그 지불 거절에 대한 증거도 함께 사라집니다.

환불 알림을 놓쳤을 때 드는 비용

이미 확정된 환불의 알림을 놓쳤다면, 그 비용은 장부 정리입니다. 나중에 Voided Purchases API나 Get Notification History에서 찾아내고, 정책에 따라 접근 권한을 회수하면 보고서도 따라잡습니다. 번거롭지만 비용은 적습니다.

이의를 제기할 수 있는 두 절차의 알림을 놓치면 실제로 돈을 잃습니다. 스토어가 여러분의 증거 없이 결정하기 때문입니다. Apple에서는 여러분의 소비 데이터 없이 환불 결정이 내려진다는 뜻입니다. Google Play에서는 2026년 8월 3일 이후 접수된 주문의 경우, 지불 거절에서 지면 구매 가격에서 Play 서비스 수수료를 뺀 금액에 구매자 은행이 부과하는 지불 거절 수수료까지 부담해야 합니다. Google은 자사 서비스 수수료만 부담합니다.

게다가 구매한 것을 제공하는 데 쓴 돈은 분쟁이 시작되기 전에 이미 나갔습니다.

  • 컴퓨팅: 구매자가 이미 사용한 생성, 렌더링, 모델 응답 하나하나에 들어간 GPU와 서버 시간.
  • API 호출: 호출하는 순간 과금되는 외부 서비스 요청. 대개 호출마다 과금됩니다.
  • 스토리지: 구매자가 만든 파일과 미디어. 여전히 호스팅 요금에 포함되어 있습니다.
  • 지급금: 해당 판매에 대해 크리에이터, 제휴사, 파트너에게 이미 지급한 수익 배분.

환불이 처리되면 이 중 어느 것도 돌아오지 않습니다. 그 12시간 또는 24시간 안에 보내는 증거가 여러분이 쓸 수 있는 유일한 수단이며, 알림을 놓치면 그 수단이 사라집니다.

믿을 수 있는 복구 루틴

  • 먼저 확인하세요. 원본 페이로드를 저장하고, 성공 코드를 반환한 다음, 큐에서 처리합니다.
  • 몇 분마다 onlyFailures를 켜고 Apple의 Get Notification History에서 CONSUMPTION_REQUEST를 폴링해, 장애가 나도 12시간 기한 중 몇 분만 잃도록 합니다.
  • 매일 onlyFailures를 켜고 지난 며칠 동안의 모든 유형에 대해 Get Notification History를 훑어보고, 찾은 알림을 재생합니다.
  • Google Play 앱마다 매일 type 1로 Voided Purchases API를 호출하고, 이미 기록한 환불과 대조합니다.
  • Pub/Sub에서는 메시지 보관 기간을 7일 이상으로 유지하고, 데드 레터 주제가 있다면 알림을 설정하고, 전송되지 않은 메시지가 쌓일 때도 알림을 받도록 하세요.
  • 프로덕션에서도 전체 경로를 테스트하세요. Apple 샌드박스는 알림마다 한 번만 보내고 재시도하지 않지만, Request a Test Notification과 Get Test Notification Status를 함께 쓰면 서버가 어떻게 응답했는지 정확히 확인할 수 있습니다.
이른 아침 햇살 아래 책상 위에 화면이 위로 향한 스마트폰이 커피 머그와 노트 옆에 놓여 있다. 놓친 환불 알림을 확인하는 하루 점검의 차분한 시작

RefundHalt가 두 스토어의 알림을 대신 받아 CONSUMPTION_REQUEST와 지불 거절 검토에 기한 안에 자동으로 응답하므로, 여러분이 시계를 지켜볼 필요가 없습니다.

자주 묻는 질문

실패한 App Store 서버 알림을 Apple은 얼마나 오래 재시도하나요?
버전 2는 약 6일 반입니다. Apple은 이전 시도로부터 1, 12, 24, 48, 72시간 후에 다섯 번 재시도하므로, 마지막 재시도는 첫 전송 후 157시간에 이뤄집니다. 버전 1 알림은 이전 시도로부터 6, 24, 48시간 후에 세 번 재시도됩니다.
놓친 App Store 서버 알림은 얼마나 과거까지 복구할 수 있나요?
프로덕션에서는 180일입니다. Apple의 Get Notification History 엔드포인트는 지난 180일, 샌드박스에서는 지난 30일 동안의 버전 2 알림을 호출당 20건씩 반환하며, onlyFailures 플래그로 서버에 도달하지 못한 알림만 조회할 수 있습니다.
서버가 HTTP 400을 반환하면 Apple이 알림을 재시도하나요?
Apple 문서에 따르면 그렇습니다. 서버가 40x 또는 50x 상태를 반환하면 Apple이 재시도하며, 200에서 206까지를 성공으로 봅니다. 그 밖의 상태도 모두 실패로 간주됩니다.
놓친 Google Play 지불 거절 검토를 복구할 수 있나요?
Pub/Sub 메시지가 아직 남아 있는 동안에만 가능합니다. orders.reviewrefund에 필요한 pendingRefundToken은 PendingRefundReviewNotification으로 전달되고, 대기 중인 검토를 조회하는 API는 Google 문서에 없습니다. 따라서 기본 7일 동안 보관되는 구독의 미확인 메시지가 유일한 사본입니다.
서버가 놓친 Google Play 환불은 어떻게 찾나요?
Voided Purchases API를 호출하세요. 환불, 취소, 지불 거절을 포함해 지난 30일 동안 무효화된 구매를 페이지당 최대 1,000건씩 반환하며, 할당량은 앱마다 하루 6,000건입니다. type 1을 전달하면 구독도 포함됩니다.

출처 및 추가 자료

RefundHalt

App Store와 Google Play 환불 자동 처리

계속 읽기

다음 환불 요청은 이미 오고 있습니다.

이의를 제기하지 못한 환불에 관한 지원 이메일을 하나 더 읽는 시간이면 RefundHalt 설정을 마칠 수 있습니다.