모든 글
Playbook8분 소요

앱이 아직 App Store Server Notifications V1을 쓰고 있다면, Apple은 구독 환불에 대해 절대 묻지 않습니다

Apple은 2023년 6월 App Store Server Notifications V1을 지원 중단했고, V1에는 구독용 CONSUMPTION_REQUEST, REFUND_DECLINED, REFUND_REVERSED가 끝내 추가되지 않았습니다. V1 서버가 놓치는 것, 그로 인한 비용, 그리고 환불을 하나도 놓치지 않고 V2로 옮기는 방법을 정리했습니다.

뜯지 않은 편지가 넘쳐나는 낡은 우편함과 그 옆의 최신 서버 랙. App Store Server Notifications V1에서 사라지는 환불 신호를 나타낸다

핵심 요약

  • Apple은 2023년 6월 5일 App Store Server Notifications V1과 verifyReceipt 엔드포인트를 지원 중단했습니다. 둘 다 여전히 작동하지만 새 기능은 추가되지 않으며, 서비스 종료일도 발표되지 않았습니다.
  • Apple의 V1 문서는 소모성 인앱 구매에 대해서만 CONSUMPTION_REQUEST를 명시합니다. 자동 갱신 구독에 대한 소비 정보 요청은 2024년 4월 App Store Server Notifications V2에 추가되었습니다.
  • REFUND_DECLINED와 REFUND_REVERSED는 App Store Server Notifications V2에만 존재하므로, V1 서버는 Apple이 환불을 거절했거나 승인한 환불을 취소했다는 사실을 알 수 없습니다.
  • V1에서는 자동 갱신 구독에 대한 Apple의 환불이 CANCEL로 도착합니다. V2에서는 REFUND로 도착하며, 서명된 거래에 revocationDate와 revocationReason이 포함됩니다.
  • V2 알림 전송이 실패하면 Apple은 약 일주일에 걸쳐 1, 12, 24, 48, 72시간 후 총 다섯 번 재시도합니다. V1 알림이 실패하면 6, 24, 48시간 후 세 번만 재시도하며, Get Notification History로 복구할 수도 없습니다.
  • App Store Connect에서 앱을 V2로 전환하면 새 알림은 즉시 V2 형식으로 도착하지만, 이미 재시도 중인 V1 알림은 약 78시간 동안 계속 도착할 수 있습니다.

App Store Server Notifications Version 1은 지금도 환불을 알려 주지만, 구독 환불에 이의를 제기할 수 있게 해 주는 단 하나의 알림이 빠져 있습니다. Apple은 2023년 6월 5일 verifyReceipt 엔드포인트와 함께 V1을 지원 중단했고, 그 이후 추가된 환불 관련 기능은 모두 V2에만 들어갔습니다. App Store Connect 설정이 아직 Version 1로 되어 있다면, Apple은 서버에 CONSUMPTION_REQUEST를 한 번도 보내지 않고 구독 환불을 결정할 수 있습니다. 논쟁에서 지는 것이 아닙니다. 애초에 논쟁에 초대받지 못하는 것입니다.

Apple의 App Store Server Notifications V1 지원 중단이 의미하는 것

지원 중단은 서비스 종료가 아닙니다. 한 Apple 엔지니어는 2023년 6월 개발자 포럼에, verifyReceipt와 V1 알림은 서비스 종료일이 발표될 때까지 계속 작동하며, 그 날짜는 아직 정해지지 않았고, 개발자에게 미리 알릴 것이라고 썼습니다. 3년이 넘게 지난 지금도 App Store Connect는 서버 URL을 설정할 때 "Version 1 (deprecated)"를 선택지로 제공합니다.

지원 중단이 실제로 의미하는 것은 동결입니다. 2023년 6월 이후 Apple 알림 변경 내역에 오른 변경 사항은 모두 V2의 것입니다. 서명된 거래의 새 필드, 새 알림 유형, 그리고 2026년 4월에 추가된 12개월 약정 데이터까지. V1 서버는 그 어느 것도 보지 못합니다.

V1 서버가 절대 받지 못하는 환불 신호

Apple의 버전별 문서에 따르면, 같은 환불 이벤트가 V1 서버와 V2 서버에 각각 다음과 같이 도착합니다.

환불 이벤트Version 1Version 2
고객이 Apple에 소모성 항목 환불을 요청CONSUMPTION_REQUESTCONSUMPTION_REQUEST
고객이 Apple에 자동 갱신 구독 환불을 요청V1 문서에 명시되지 않음CONSUMPTION_REQUEST, 2024년 4월부터
Apple이 자동 갱신 구독을 환불CANCELREFUND
Apple이 소모성, 비소모성 또는 비갱신 구독을 환불REFUNDREFUND
고객이 앱에서 시작한 환불을 Apple이 거절제공되지 않음REFUND_DECLINED
Apple이 이미 승인한 환불을 취소제공되지 않음REFUND_REVERSED
장애 중 놓친 알림을 복구제공되지 않음Get Notification History

V1에서도 CONSUMPTION_REQUEST를 받을 수 있나요?

네, 소모성 항목이라면 받습니다. Apple의 V1 참조 문서는 CONSUMPTION_REQUEST를 고객이 소모성 인앱 구매에 대해 환불 요청을 시작할 때 전송되는 알림으로 설명합니다. 한 Apple 엔지니어도 2023년 포럼에서 해당 요건을 충족하는 환불에는 V1 소비 정보 요청이 전송된다고 확인했습니다. 빈틈은 구독입니다. Apple 변경 내역에 따르면 구독용 소비 정보 요청은 2024년 4월 11일 V2에 도입되었고, Send Consumption Information 문서에도 Apple이 이 요청을 V2 엔드포인트로 보낸다고 나와 있습니다.

V1의 CANCEL을 잘못 해석하기 쉬운 이유

V1에서는 Apple이 구독을 환불하면 알림 유형이 CANCEL이며, DID_CHANGE_RENEWAL_STATUS와 함께 오는 경우가 많습니다. 많은 서버가 모든 취소를 고객이 자동 갱신을 끈 것으로 처리하기 때문에, 이용 기간이 끝날 때까지 접근 권한이 유지됩니다. V2는 이런 모호함을 없앱니다. 환불은 REFUND로 도착하고, 고객이 갱신을 끈 경우에는 하위 유형 AUTO_RENEW_DISABLED가 붙은 DID_CHANGE_RENEWAL_STATUS로 도착합니다.

V1에 머무를 때 드는 금전적 비용

모든 App Store 환불은 Apple이 결정합니다. CONSUMPTION_REQUEST는 여러분의 사용 데이터가 그 결정에 반영될 수 있는 유일한 지점이며, Apple은 12시간 이내에 응답하라고 요구합니다. V1에서는 구독 환불이 이 단계를 건너뜁니다.

예시 수치로 구체적인 사례를 살펴보겠습니다. 앱에서 AI 이미지 생성이 포함된 월 $9.99 구독을 판매한다고 가정합시다. 한 구독자가 한 달 동안 400번 이미지를 생성했고, 매번 실제 모델 추론 비용이 발생했습니다. 그런 다음 이 구독자가 Apple에 환불을 요청합니다.

비용 항목V1 서버V2 서버
결제 금액 중 개발자 몫Apple이 승인하면 반환Apple이 승인하면 반환
그달에 사용된 컴퓨팅, API 호출, 스토리지이미 지불, 회수 불가이미 지불, 회수 불가
400번의 생성 기록을 Apple에 보여 줄 기회없음CONSUMPTION_REQUEST 1회, 12시간
Apple이 환불을 거절했음을 알기알 수 없음REFUND_DECLINED
환불이 취소되었음을 알기알 수 없음REFUND_REVERSED

잃는 금액은 판매가가 아니라 개발자 몫입니다. Apple은 구독자의 유료 서비스 첫해에는 구독 가격의 70%(해당 세금 제외)를, 그 이후 또는 App Store Small Business Program 회원에게는 85%를 지급합니다. 하지만 컴퓨팅 비용은 줄어들지 않습니다. 추론, 서드파티 API 호출, 파일 스토리지 비용은 고객이 사용한 시점에 이미 지불되었습니다.

빠져 있는 두 가지 결과 알림도 비용으로 이어집니다. REFUND_REVERSED가 없으면, 환불 시 접근 권한을 회수한 서버는 Apple이 환불을 취소해도 권한을 복구하지 않습니다. 그래서 결제 중인 고객이 계속 이용하지 못한 채 고객 지원에 문의하게 됩니다. REFUND_DECLINED가 없으면 아직 처리 중인 환불과 Apple이 거절한 환불을 구분할 수 없습니다.

열린 노트북 옆에서 개발자의 손이 네트워크 케이블을 오래된 패치 패널 포트에서 새 포트로 옮기는 모습

환불을 놓치지 않고 V1에서 V2로 마이그레이션하는 방법

V2로의 전환은 서버 변경과 설정 하나로 끝납니다. 2025년 12월 한 App Store Commerce 엔지니어가 포럼에 올린 Apple의 공식 안내에서 전환 당일 어떤 일이 일어나는지 설명합니다.

설정을 바꾸기 전에 V2 엔드포인트부터 구축하기

  • 본문에 signedPayload가 담긴 POST 요청을 받도록 합니다. V2 페이로드는 Apple이 서명한 JWS이므로, 안의 내용을 신뢰하기 전에 반드시 서명을 검증하세요. Apple의 App Store Server Library가 이 작업을 대신 처리해 줍니다.
  • 기존 CANCEL 처리 로직을 REFUND에 대응시키고, REFUND_DECLINED와 REFUND_REVERSED를 새로운 경우로 처리합니다.
  • 구독에 대한 CONSUMPTION_REQUEST에는 Send Consumption Information으로 응답하되, 고객이 Apple과의 데이터 공유에 동의한 경우에만 응답합니다. Apple은 동의가 없으면 응답하지 말아야 한다고 말합니다.
  • 성공 시 HTTP 200에서 206 사이를 반환합니다. 40x나 50x를 반환하면 Apple이 재시도합니다.

App Store Connect에서 설정 전환하기

App Store Connect에서 앱을 열고 "General" 아래의 "App Information"을 선택한 다음, App Store Server Notifications 항목에서 "Production Server URL"을 V2 엔드포인트로 설정하고 Version 2를 선택합니다. 먼저 테스트하고 싶다면 샌드박스 URL에 같은 설정을 하고, Request a Test Notification으로 서버가 응답하는지 확인하세요.

V1 핸들러는 약 3일 동안 유지하기

전환 후에는 신규, 기존 구독 모두에 대해 새 알림이 즉시 V2 형식으로 도착합니다. 이미 재시도 중인 V1 알림은 성공하거나 재시도 횟수를 모두 소진할 때까지 V1 형식으로 계속 도착합니다. Apple은 마지막 V1 재시도가 약 78시간 후, 즉 6 더하기 24 더하기 48이라고 설명합니다. 기존 핸들러는 그 시간이 지날 때까지 실행해 두었다가 제거하세요.

이참에 verifyReceipt도 교체하기

verifyReceipt도 같은 날 지원 중단되었습니다. 여전히 응답은 하지만, Apple은 서버가 대신 App Store Server API를 사용하도록 권장합니다. Get Transaction Info는 서명된 거래 한 건을, Get Transaction History는 고객의 거래 내역을 반환하며, Get Refund History는 고객의 환불된 구매를 모두 나열합니다. V2 알림과 함께 사용하면, 예전에 영수증에서 환불을 표시하던 cancellation_date 필드를 포함해 대부분의 서버가 영수증으로 하던 일을 모두 처리할 수 있습니다.

RefundHalt는 App Store Server Notifications V2에 연결되어, 앱이 이미 기록하고 있는 사용량을 바탕으로 모든 CONSUMPTION_REQUEST에 12시간 기한 안에 응답합니다. 아직 V1을 사용 중이라면, 전환이야말로 이 모든 것을 가능하게 하는 단계입니다.

자주 묻는 질문

App Store Server Notifications V1은 종료되나요?
아직은 아닙니다. Apple은 2023년 6월 5일 V1과 verifyReceipt를 지원 중단했지만 둘 다 여전히 작동합니다. Apple은 아직 서비스 종료일이 정해지지 않았으며 개발자에게 미리 알리겠다고 밝혔습니다. 그동안 V1에는 새 기능이 추가되지 않습니다.
V1에서 CONSUMPTION_REQUEST 알림을 받을 수 있나요?
Apple의 V1 문서에 따르면 소모성 항목에 대해서만 받을 수 있습니다. 자동 갱신 구독에 대한 소비 정보 요청은 2024년 4월 V2에 추가되었고, Apple은 이를 V2 엔드포인트로 보냅니다. 구독을 판매하면서 V1에 머무르면 이러한 환불 요청에 응답할 수 없습니다.
구독 환불은 V1과 V2에서 각각 어떻게 보이나요?
V1에서는 CANCEL로 도착하며, DID_CHANGE_RENEWAL_STATUS와 함께 오는 경우가 많습니다. V2에서는 REFUND로 도착하며, 서명된 거래에 revocationDate와 revocationReason이 포함됩니다. 또한 V2는 앱에서 시작된 환불을 Apple이 거절하면 REFUND_DECLINED를, Apple이 승인한 환불을 취소하면 REFUND_REVERSED를 보냅니다.
V1에서 V2로 전환하면 알림은 어떻게 되나요?
전환 직후부터 모든 구독의 새 알림이 V2 형식으로 도착합니다. 이미 재시도 중인 V1 알림은 성공하거나 재시도 횟수를 모두 소진할 때까지 V1 형식으로 계속 도착하며, Apple은 이 기간을 전환 후 약 78시간으로 봅니다. 그동안에는 두 핸들러를 모두 실행해 두세요.
V2로 전환한 뒤 다시 V1으로 돌아갈 수 있나요?
네, Apple의 기술 노트 TN3180에 설명된 대로 App Store Connect API의 Modify an App 엔드포인트를 통해 가능합니다. 다만 Apple은 이를 이례적인 경우로 보고 있으며 V1을 여전히 지원 중단 상태로 표시하므로, 되돌리면 구독 소비 정보 요청과 새로운 환불 알림을 포기하게 됩니다.

출처 및 추가 자료

RefundHalt

App Store와 Google Play 환불 자동 처리

계속 읽기

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

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