오랫동안 "Apple 환불 요청에 어떻게 대응해야 하나요?"라는 질문에 대한 솔직한 답은 "대응할 수 없다"였습니다. Apple이 결제를 받고, 요청을 받고, 결정을 내렸으며, 개발자가 이 사실을 처음 알게 되는 순간은 정산 금액이 줄어들었을 때였습니다. 하지만 2021년 이후로는 그렇지 않습니다. 물론 아직도 많은 사람들이 그렇게 생각하고 있지만요.
현재는 Apple이 결정을 내리기 전에 서버에 구매에 대해 알고 있는 정보를 요청하고, 약 12시간 동안 응답을 기다립니다. CONSUMPTION_REQUEST에 실제로 어떤 내용이 포함되는지에 대해서는 이미 다룬 글이 있으므로 페이로드 필드를 하나씩 다시 설명하지는 않겠습니다. 이 글에서는 요청이 도착했을 때 무엇을 해야 하는지를 다룹니다.
핵심 요약
Apple이 모든 앱 스토어 환불을 결정합니다. 여러분이 보내는 정보가 이 사실을 바꾸지는 못하지만, Apple이 결정을 내릴 때 알고 있는 정보를 바꿀 수 있습니다.
이 요청은 소비성 상품과 자동 갱신 구독에 대해서만 CONSUMPTION_REQUEST 알림 형태로 도착합니다.
Send Consumption Information 엔드포인트를 통해 응답할 수 있는 시간은 12시간이며, 현재는 5개의 필드를 요구합니다.
응답의 핵심은 대부분 세 가지 사실입니다: 전달되었는지, 얼마나 사용되었는지, 무료 체험을 먼저 제공받았는지 여부입니다. 여기에 여러분의 선호도(preference)가 더해집니다.
저희 경험상, 개발자가 놓치는 환불은 대부분 아무도 응답하지 않은 요청들입니다.
Apple 앱 스토어 환불 요청이란 무엇인가요?
Apple 앱 스토어 환불 요청은 고객이 앱 또는 인앱 구매에 대한 환불을 Apple에 요청하는 것입니다. 개발자에게 요청하는 것이 아닙니다. 고객은 reportaproblem.apple.com으로 이동하거나 인앱 환불 시트를 사용해 짧은 메뉴에서 이유를 선택하고, 구매 항목을 선택한 뒤 제출합니다. Apple 고객지원 페이지에서는 24~48시간 내에 답변을 받을 수 있다고 안내합니다.
구매가 소비성 상품이거나 자동 갱신 구독이었다면, Apple은 여러분의 서버에 신호를 보내 알고 있는 정보를 요청한 뒤, 여러분의 답변을 고객의 구매 및 환불 이력(이는 Apple이 여러분보다 훨씬 더 잘 알고 있는 정보입니다)과 결합하여 최종 결정을 내립니다. 여러분은 고객의 이름을 볼 수 없고, 거부권도 없습니다. 다만 사실을 제시할 수 있는 짧은 시간이 주어질 뿐입니다.
개발자를 위한 Apple 환불 프로세스 작동 방식
개발자를 위한 Apple 환불 프로세스는 4단계로 진행되며, 개발자가 직접 관여하는 단계는 그중 하나뿐입니다.
고객이 Apple에 환불을 요청하고 이유를 선택합니다.
Apple이 App Store Connect에 등록된 서버 URL로 CONSUMPTION_REQUEST를 전송합니다. 이는 소비성 상품과 자동 갱신 구독에만 발생합니다.
12시간 내에 Send Consumption Information 엔드포인트를 호출하여 데이터를 전송해야 합니다.
Apple이 결정을 내린 뒤, REFUND 알림 또는 REFUND_DECLINED 알림으로 결과를 알려줍니다.
App Store Server Notifications용 서버 URL을 한 번도 설정하지 않았다면, 2단계는 조용히 생략됩니다. Apple은 고객의 계정 정보만으로 판단을 내리며, 여러분은 판매 보고서를 확인하고 있는 경우에 한해 그 사실을 알게 됩니다.
고객이 환불을 요청한 후 어떤 일이 벌어지나요?
고객이 요청을 제출한 직후, 여러분의 엔드포인트는 notificationType이 CONSUMPTION_REQUEST인 서명된 JSON 페이로드를 받습니다. 그 안에는 서명된 트랜잭션, 제품 ID, 원본 트랜잭션 ID, 그리고 consumptionRequestReason이 포함되어 있습니다. Apple은 2024년에 이 reason 필드를 추가했으며, App Store 서버 API에 관한 WWDC24 세션에서 이를 설명했습니다. 가능한 값은 5가지로, UNINTENDED_PURCHASE, FULFILLMENT_ISSUE, UNSATISFIED_WITH_PURCHASE, LEGAL, OTHER입니다.
빠져 있는 것은 바로 '사람'입니다. 여러분의 기록으로 연결되는 유일한 실마리는 트랜잭션 ID뿐이며, 구매 시점에 appAccountToken을 첨부했다면 그것도 활용할 수 있습니다. 첨부하지 않았다면, 바로 이 순간 "첨부했어야 했는데"라는 생각이 들 것입니다.
결국 검토란 사실상 하나의 조회 작업입니다: 누가 이것을 구매했는지, 실제로 전달받았는지, 그 이후 어떻게 사용했는지를 확인하는 것입니다.
Apple 환불 요청에 대응하는 방법
Apple 환불 요청 알림에 대응하는 방법을 검색하는 사람들은 대부분 API 레퍼런스 문서를 찾게 됩니다. 아래는 순서대로 정리한 단계입니다.
1. 페이로드 검증하기
Apple은 모든 알림에 서명을 추가합니다. 내용을 신뢰하기 전에 먼저 서명을 확인하세요. Apple의 App Store Server Library는 Java, Python, Node, Swift에서 이를 처리해 줍니다.
2. 구매 내역 찾기
트랜잭션 ID나 appAccountToken을 사용해 자체 시스템에서 구매 내역을 조회하세요. 필요한 것은 사용자 정보, 전달(delivery) 기록, 그리고 그 이후 기록해 둔 사용 내역입니다.
3. 사유를 읽고 확인하기
FULFILLMENT_ISSUE는 고객이 결제한 것을 전혀 받지 못했다고 말하는 경우입니다. 먼저 전달 로그를 확인하세요. 고객의 말이 맞다면 이 환불은 승인되어야 합니다.
UNINTENDED_PURCHASE는 대개 자녀의 구매나 잘못된 터치로 인한 경우입니다.
UNSATISFIED_WITH_PURCHASE의 경우 사용 데이터가 실질적인 비중을 갖습니다. "마음에 들지 않았다"는 말도 2% 사용했을 때와 100% 사용했을 때는 전혀 다른 의미를 갖기 때문입니다.
4. 선호도(Preference) 선택하기
Apple은 GRANT_FULL, GRANT_PRORATED, DECLINE 중 하나를 받습니다. 데이터가 뒷받침하는 쪽을 선택하세요. 이는 어디까지나 '선호도'일 뿐이며, Apple은 개발자가 거부를 요청한 환불도 실제로 많이 승인해 왔습니다.
5. 전송하기
Send Consumption Information 엔드포인트를 호출하세요. 현재 요청 본문에는 5개의 필드가 있습니다: customerConsented, deliveryStatus, consumptionPercentage, sampleContentProvided, refundPreference입니다.
소비량(consumption)은 밀리유닛(milliunits) 단위로 표시되는데, 이 부분에서 혼란을 겪는 경우가 많습니다. 100000은 완전히 사용한 것을 의미하고, 45200은 45.2%를 의미합니다.
그리고 customerConsented는 true여야 하므로, 사용 데이터 공유에 대한 동의는 첫 요청이 도착하기 훨씬 전부터 이용약관에 포함되어 있어야 합니다.
6. 결과에 따라 조치하기
REFUND는 콘텐츠나 권한(entitlement)을 회수해야 한다는 의미이며, 가급적 1시간 이내에 처리하는 것이 이상적입니다. REFUND_DECLINED는 아무것도 바뀌지 않는다는 의미입니다. 어느 쪽이든 결과를 해당 케이스에 기록해 두세요.
예를 들어 누군가가 밤 11시에 500코인 팩을 구매하고, 밤사이 그중 470코인을 사용한 뒤 다음날 아침 UNSATISFIED_WITH_PURCHASE로 요청을 제출했다고 가정해 봅시다. 전달됨, 94% 소비됨, 체험 없음, 선호도는 DECLINE입니다. 이것이 완전한 Apple 환불 요청 응답입니다. 긴 글이 필요한 것이 아닙니다.
응답하기 전에 개발자가 확인해야 할 정보는 무엇인가요?
다섯 가지이며, 대부분은 이미 데이터베이스에 있어야 할 정보들입니다.
구매 기록
날짜, 제품, 가격, 그리고 이 계정이 이전에 구매한 적이 있는지 여부입니다. 기록이 부족하다면, Apple의 Get Transaction History 엔드포인트를 통해 트랜잭션 ID 하나만으로 해당 고객이 앱에서 구매한 모든 내역을 조회할 수 있습니다.
전달(Delivery)
서버가 실제로 코인을 지급했는지, 기능을 잠금 해제했는지, 구독을 시작했는지, 그리고 언제 그렇게 했는지 확인하세요. 해당 호출이 실패했다면 deliveryStatus는 UNDELIVERED 값 중 하나일 것이며, 이 경우 환불은 정당합니다. 자체 로그와 다투지 마세요.
이후 사용 내역
세션, 열어본 챕터, 사용한 코인 등 여러분의 제품에서 '사용'이 의미하는 모든 것입니다. Apple은 비율(percentage)만을 원하지만, 그 비율을 뒷받침할 근거 이벤트가 없다면 자신 있게 제시할 수 없습니다.
무료 체험을 먼저 제공받았는지 여부
무료 체험판, 미리보기 챕터, 또는 무료 등급(free tier)을 의미합니다. Apple은 이를 직접적으로 묻으며, 답이 '예'라면 "내가 무엇을 사는지 몰랐다"는 주장의 신빙성이 떨어집니다.
여러분 측의 계정 정보
계정의 생성 기간, 이전에 환불한 적이 있는지, 진행 중인 고객 지원 티켓이 있는지 등입니다. Apple은 이 이력 중 App Store 쪽의 절반만 볼 수 있습니다. 나머지 절반은 여러분만 볼 수 있습니다.
이 모든 것은 Apple의 트랜잭션 ID를 여러분 시스템의 사용자와 연결할 수 있느냐에 달려 있으며, 바로 이를 위해 appAccountToken이 존재합니다. 저희가 가장 자주 발견하는 공백이 바로 이 부분이며, 설정 방법이 궁금하다면 저희가 쓴 appAccountToken이 환불 방어에 중요한 이유 글도 참고해 보세요.
Apple 환불 요청과 관련해 개발자들이 자주 저지르는 실수
알림이 도착하지 않는 경우
App Store Connect에 서버 URL이 등록되어 있지 않거나, 등록되어 있더라도 3월에 누군가 폐기한 스테이징 서버를 가리키고 있는 경우입니다. Apple은 계속 알림을 보내지만, 받는 쪽은 아무도 없는 상태입니다.
늦게 응답하는 경우
12시간이면 충분해 보일 수 있지만, 일요일 새벽 2시에 요청이 도착하고, 이를 처리해야 할 담당자는 자고 있다가, 브런치를 먹고, 그제야 Slack 메시지를 어렴풋이 인지하는 상황이라면 이야기가 달라집니다. 업무 시간을 기준으로 설계된 프로세스는 구조적으로 상당수의 요청을 놓치게 됩니다.
제시할 정보가 아무것도 없는 경우
알림은 도착했지만 전달 로그도, 사용 이벤트도, appAccountToken도 없는 경우입니다. 결국 Apple은 고객의 말만으로 결정을 내리게 됩니다. 이 실수는 몇 달 전, 결제 시점에 이미 발생한 것입니다.
모든 요청에 거부를 요청하는 경우
저희는 개발자 자신의 로그에서 전달 실패가 확인된 경우까지 포함해 모든 요청에 DECLINE을 보내는 설정을 본 적이 있습니다. Apple은 이런 패턴을 파악할 수 있으며, 이는 정당한 사유가 있는 요청에서조차 신뢰도를 깎아먹는 결과를 낳습니다.
환불 승인 후 권한 회수를 잊는 경우
이 실수는 손해를 두 번 보게 만듭니다. 돈은 이미 환불됐는데 고객은 여전히 콘텐츠를 보유하고 있고, 일부 고객은 이 사실을 알아차립니다.
운영 환경에서 테스트하는 경우
Apple은 테스트 알림 엔드포인트와 샌드박스 환불 요청 기능을 제공합니다. 실제 요청이 불편한 시간에 처음 도착하기 전에 두 가지를 모두 활용해 테스트해 보세요.
Apple 환불 관리: 수동 방식 vs 자동화 방식
Apple 환불 관리는 12시간이라는 시간 내에 이루어지는 모든 작업을 포함합니다: 요청 수신, 데이터 조회, 선호도 선택, 응답 전송, 결과 기록, 필요 시 권한 회수까지입니다.
수동 방식
수동으로 처리한다면, 로그 접근 권한과 알림을 가진 한 사람이 담당하게 됩니다. 한 달에 몇 건 정도라면 이 방식도 잘 작동하지만, 그 담당자가 일주일이라도 휴가를 가지 않는다는 전제가 필요합니다.
주당 20건 정도가 되면 처리가 밀리기 시작합니다. 100건이 되면 이는 하나의 정식 업무가 되며, 누구도 맡고 싶어 하지 않는 업무입니다.
자동화 방식
자동화된 방식에서는 조회와 응답이 한 번 작성해 둔 규칙에 따라 처리됩니다. 완전히 소비된 상품에는 DECLINE이 적용되고, 전달이 실패한 FULFILLMENT_ISSUE에는 GRANT_FULL이 적용되며, 애매한 경우는 사람이 검토하도록 플래그가 지정됩니다.
응답은 몇 분 안에 전송되며, 오후 2시든 새벽 2시든 동일하게 안정적으로 처리됩니다.
단, 함정이 있습니다. 자동화는 그 기반이 되는 데이터의 품질만큼만 유효합니다. 전달 및 사용 기록이 부실하면, '알 수 없음'이라는 결과만 더 빨리 보내는 셈이 됩니다.
개발자는 언제 Apple 환불 관리 소프트웨어 도입을 고려해야 할까요?
솔직히 말하면, 처음부터 필요한 것은 아닙니다. 한 달에 두세 건 정도라면 체크리스트와 알림 설정만으로 충분히 처리할 수 있으며, 몇 건을 직접 처리해 보는 경험 자체가 많은 것을 알려줍니다.
요청이 한 사람이 시간 내에 처리할 수 있는 속도보다 빠르게 들어오거나, 아무도 깨어 있지 않은 시간에 도착하기 시작하면 도입을 고려할 만합니다. 여러 앱을 운영하거나 Apple과 Google Play를 함께 운영하면서 세 개의 목록이 아니라 하나의 목록으로 관리하고 싶을 때도 유용합니다.
Apple 환불 관리 소프트웨어는 수동 프로세스가 요청을 놓치기 시작하는 순간부터 그 가치를 입증합니다. 그 시점은 쉽게 알 수 있습니다. 바로 연속으로 세 건을 놓치고, 정산 내역을 보고서야 그 사실을 알게 되는 그 주입니다.
Apple 환불 방어 소프트웨어: 개발자는 무엇을 확인해야 할까요?
Apple 환불 방어 소프트웨어를 비교하고 있다면, 가장 먼저 기본 구조를 확인하세요. CONSUMPTION_REQUEST를 직접 수신하고, 사람의 개입 없이 일반적인 케이스에 응답할 수 있나요? 속도는 얼마나 빠른가요? 야간이나 주말을 포함해서요. 정답은 '몇 분 이내'여야 하며, 실제 타임스탬프를 확인해 보라고 요청하세요.
근거 데이터
전달 및 사용 데이터를 가져오거나 수신할 수 있나요, 아니면 단순히 선호도만 첨부해 알림을 그대로 되돌려 보내는 수준인가요? 후자라면 큰 가치가 없습니다.
또한 이메일을 파싱하는 방식이 아니라 App Store Server API와 Server Notifications V2를 기반으로 구축되어 있어야 합니다.
가시성
요청이 도착했을 때, 응답이 전송됐을 때, 그리고 Apple이 결정을 내렸을 때 알림을 받을 수 있는지.
요청별로 응답과 결과를 한곳에서 확인할 수 있는 케이스 단위 관리 기능.
앱별, 제품별 환불률, 승인률, 사유에 대한 리포팅 기능.
누가 또는 무엇이 언제 어떤 응답을 보냈는지에 대한 감사 기록(audit trail).
직접 제어할 수 있는 규칙으로, 로직을 변경할 때 별도의 배포가 필요 없는지.
가격 정책
가격 정책도 다양합니다. 고정 월 요금, 요청당 과금, 회수 금액에 대한 비율 과금 모델 등은 각각 처리량에 따라 적합한 경우가 다릅니다.
단, 어떤 솔루션도 할 수 없는 것이 하나 있습니다. 환불 요청 자체를 막거나, Apple의 결정 결과를 보장하는 것은 불가능합니다. 그렇게 할 수 있다고 주장하는 업체가 있다면, 뭔가를 팔기 위한 말일 뿐입니다.
Apple 환불 요청에 대응하기 위한 모범 사례
온콜(on-call) 일정표 옆에 이 내용을 붙여 두세요.
App Store Server Notifications V2용 운영 서버 URL을 등록하고, 알림이 끊기면 경고가 발생하도록 설정하세요.
모든 구매에 appAccountToken을 설정하세요. 예외 없이 모든 구매에요.
전달 여부를 타임스탬프와 결과와 함께 기록하고, "실제로 사용했다"는 것을 의미하는 몇 가지 사용 이벤트도 함께 기록하세요.
사용 데이터 공유에 대한 동의를 지금 바로 이용약관에 추가하세요.
"승인하겠다"는 응답을 포함해, 모든 요청에 12시간 내로 응답하세요.
데이터가 뒷받침할 때만 DECLINE을 요청하세요. Apple은 패턴을 파악합니다.
모든 REFUND 알림에 대해 같은 날 즉시 접근 권한을 회수하세요.
한 달에 한 번, 실제로 응답한 요청의 비율을 확인하세요. 이 수치는 다른 어떤 요소보다 환불률에 큰 영향을 미칩니다.
Apple 환불 관리 소프트웨어는 사용할 만한 가치가 있을까요?
요청량이 적다면 아마 그렇지 않을 것입니다. 하지만 요청이 한 사람이 안정적으로 처리할 수 있는 수준을 넘어서거나, 업무 시간 외에도 도착하기 시작하면, 자동으로 응답하는 소프트웨어는 대개 그 비용 이상의 가치를 돌려줍니다.
이 모든 내용에서 단 하나의 습관을 가져가야 한다면, 그것은 시간이 다 되기 전에 모든 요청에 실제 데이터로 응답하는 것입니다. 구독형 오디오 앱인 Dipsea는 응답을 시작한 지 약 2주 만에 환불률이 3%에서 1.9%로 떨어졌으며, Apple에 거부를 요청한 적은 한 번도 없었습니다. 응답하지 않고 침묵하는 앱들은 자신이 지킬 수 있었던 것이 무엇인지 끝내 알지 못합니다.
자주 묻는 질문
고객이 보통 reportaproblem.apple.com을 통해 앱이나 인앱 구매에 대한 환불을 Apple에 요청하는 것입니다. Apple은 고객에게 24~48시간 내에 답변을 받을 수 있다고 안내합니다. 소비성 상품과 구독의 경우, Apple은 먼저 개발자에게 정보를 요청합니다.
알림을 검증하고, 자체 기록에서 구매 내역을 찾고, 전달 및 사용 여부를 확인한 뒤 선호도를 선택하고, 12시간 내에 Apple의 Send Consumption Information 엔드포인트를 호출하세요. 그런 다음 Apple의 결정에 따라 조치를 취하면 됩니다.
아니요. Apple에 거부를 선호한다고 알리고 이를 뒷받침하는 데이터를 보낼 수는 있지만, 최종 결정은 여전히 Apple이 내립니다. 개발자가 거부를 요청한 환불이라도 Apple이 승인하는 경우가 실제로 있습니다.
다섯 가지입니다: 고객이 데이터 공유에 동의했는지 여부, 구매가 전달되었는지 여부, 얼마나 소비되었는지, 무료 샘플이나 체험을 받았는지 여부, 그리고 환불 선호도입니다. 이것이 현재 요청 본문의 전체 내용입니다.
CONSUMPTION_REQUEST를 받은 후 12시간입니다. Apple은 결정에 자신의 데이터를 반영하고자 한다면 이 시간 내에 응답해야 한다고 안내합니다.



