본문으로 건너뛰기
App Store & Play Store Development

개발자를 위한 Apple CONSUMPTION_REQUEST 알림 처리 방법

구독 앱 개발자가 CONSUMPTION_REQUEST 알림을 활용해 Apple 환불 요청을 처리하고 정확한 고객 소비 데이터를 제공하는 방법을 알아보세요.

5 min read
개발자를 위한 Apple CONSUMPTION_REQUEST 알림 처리 방법

CONSUMPTION_REQUEST가 무엇인지 이해하는 데는 한 문단이면 충분합니다. 하지만 이를 안정적으로 처리하는 시스템을 구축하는 데는 훨씬 더 많은 것이 필요하며, 실제로 발목을 잡는 부분은 예상하는 곳이 아닙니다.

서명 검증이 그중 하나입니다. 동의도 마찬가지인데, 알림이 도착하기 전에 이미 확보되어 있어야 하기 때문입니다. 그리고 재시도 일정은 응답 기한과 맞물려 있어서, 대부분의 팀이 처음 자세히 들여다보면 놀라게 됩니다.

이 글에서는 요청이 엔드포인트에 도착하는 순간부터 처리를 마무리하는 권한(entitlement) 업데이트까지 핸들러 전체를 단계별로 살펴봅니다.

핵심 요약

• CONSUMPTION_REQUEST는 환불 심사 과정에서 정보를 요청하는 알림입니다. 결정은 여전히 Apple이 내립니다.

• 서명된 페이로드를 검증한 후에만 조치하세요. 검증되지 않은 알림은 절대 신뢰하지 마세요.

• 동의는 앱 안에서 미리 확보되어 있어야 합니다. 요청이 도착한 뒤에는 수집할 수 없습니다.

• Apple은 알림 후 12시간 이내 응답을 요구합니다.

• Apple은 전송 실패 시 정해진 일정에 따라 재시도하며, 두 번째 재시도는 응답 기한이 지난 뒤에 도착합니다.

• 결과를 추적하고 이후 권한을 업데이트하세요. 응답이 마지막 단계가 아닙니다.

Apple CONSUMPTION_REQUEST 알림이란?

Apple CONSUMPTION_REQUEST 알림은 고객이 환불을 요청했으며 Apple이 해당 구매에 대한 소비 정보를 보내 달라고 요청한다는 사실을 서버에 알려주는 App Store Server Notification입니다. 설정해 둔 알림 URL로 도착하고, 관련 트랜잭션 정보를 담고 있으며, 제한된 시간 안에 응답해야 합니다.

이것은 환불도 아니고 결정도 아닙니다. Apple은 심사 도중에 맥락을 수집하고 있는 것입니다. 개발자의 역할은 구매에 어떤 일이 있었는지 정확한 정보를 제공하는 것이고, 결정은 Apple의 역할입니다.

Apple은 왜 CONSUMPTION_REQUEST를 보낼까요?

Apple은 앱 내부를 볼 수 없기 때문입니다. 트랜잭션, 계정, 구매 이력은 알고 있지만 콘텐츠가 제공되었는지, 정상적으로 작동했는지, 고객이 얼마나 사용했는지는 알지 못합니다.

소비 정보가 그 공백을 채웁니다. 이는 Apple이 고려하는 여러 요소 중 하나일 뿐 결정적인 요소는 아니며, 소비율이 높다고 해서 환불이 거부되는 것도 아닙니다. 주장을 펼치는 것이 아니라 맥락을 제공하는 것이라고 생각하세요.

CONSUMPTION_REQUEST를 받으면 개발자는 무엇을 해야 할까요?

알림을 검증하고, 트랜잭션과 고객을 식별하고, 동의를 확인하고, 정확한 소비 데이터를 취합해 Apple의 기한 안에 전송한 다음, 어떤 일이 있었는지 기록합니다.

실무에서의 10단계:

1. 설정한 서버 엔드포인트에서 알림을 수신하고 즉시 저장합니다.

2. 어떤 필드든 실제 값으로 취급하기 전에 서명된 페이로드를 검증합니다.

3. 알림 유형을 읽고 라우팅합니다. 소비 요청은 환불 결과가 아닙니다.

4. 디코딩된 페이로드에서 관련 트랜잭션을 식별합니다.

5. 트랜잭션을 자체 시스템의 고객 계정과 연결합니다.

6. 해당 고객의 동의가 응답을 허용하는지 확인합니다.

7. 추정치가 아닌 실제 기록에서 제공 및 사용 데이터를 수집합니다.

8. 응답을 준비하고 필드 유효성 검사 규칙에 맞는지 확인합니다.

9. Apple의 소비 정보 엔드포인트에 제출하고 결과를 기록합니다.

10. 이어지는 환불 결과를 추적한 뒤 권한과 기록을 업데이트합니다.

CONSUMPTION_REQUEST는 어떻게 검증해야 할까요?

내용을 신뢰하기 전에 서명을 검증하세요. 알림은 서명된 JWS 페이로드로 도착하며, 자세한 내용은 Apple App Store Server Notifications 문서에서 확인할 수 있습니다. 핸들러는 Apple의 인증서 체인으로 서명을 확인하고 번들 ID가 자신의 앱과 일치하는지 확인해야 합니다.

이유는 간단합니다. 알림 URL은 공개 엔드포인트입니다. 도착하는 것을 무엇이든 파싱해서 그대로 처리하는 구현은, URL을 찾아낸 누구든 조작할 수 있는 구현입니다.

서명만큼 중요한 핸들러 세부 사항이 세 가지 있습니다:

올바른 상태 코드로 응답하세요. Apple은 HTTP 200부터 206까지를 성공으로 간주합니다. 40x나 50x는 App Store에 재시도하라고 알리는 것입니다. 처리를 모두 마쳤을 때가 아니라 알림을 저장한 시점에 성공을 반환하세요. 이 둘은 서로 다른 시점이며, 둘을 묶어 버리면 느린 다운스트림 작업 하나가 불필요한 재시도를 유발할 수 있습니다.

중복을 처리하세요. 재시도가 있다는 것은 같은 알림이 두 번 이상 도착할 수 있다는 뜻이며, 각 알림에는 중복 제거에 사용할 수 있는 알림 UUID가 담겨 있습니다. 반복 수신에 오류를 반환하지 말고 정상 수신으로 응답하세요. 실패 응답은 재시도 주기를 다시 시작시킬 뿐입니다.

샌드박스는 다르게 동작한다는 점을 기억하세요. 재시도는 프로덕션에만 적용됩니다. 샌드박스에서는 App Store가 한 번만 전송을 시도하므로, 테스트에서 문제없어 보이는 핸들러가 프로덕션에서는 이벤트를 놓치고 있을 수 있고, 그 반대도 마찬가지입니다.

응답하기 전에 무엇을 확인해야 할까요?

네 가지를 이 순서대로 확인합니다.

먼저 동의입니다. 모든 것을 멈출 수 있는 유일한 항목이기 때문입니다. Apple은 고객 데이터를 공유하기 전에 유효한 고객 동의를 요구하며, 동의를 얻는 것은 Apple이 아닌 개발자의 책임이고, 알림 자체에는 동의 플래그가 없습니다. Apple은 또한 App Tracking Transparency 프롬프트가 여기서 말하는 동의 수단이 아니라고 분명히 밝히고 있습니다. 동의가 없다면 응답하지 않는 것이 지침입니다.

두 번째는 트랜잭션 식별입니다. 이것이 어떤 구매이고 그 뒤에 어떤 계정이 있는지 알아야 합니다. 그 매핑이 바로 appAccountToken과 Apple 환불 대응에서 다루는 내용입니다. 트랜잭션과 계정을 잇는 안정적인 연결 고리가 없으면 마감 시간에 쫓기며 추측하게 됩니다.

세 번째는 제품 유형입니다. 어떤 옵션을 사용할 수 있는지에 영향을 주기 때문입니다. 마지막으로, 실제로 사용할 수 있는 데이터를 보유하고 있는지입니다. 콘텐츠가 제공되었는지 시스템이 답할 수 없다면, 응답을 준비하기 전에 그 사실을 아는 것이 좋습니다.

개발자는 Apple에 어떤 소비 정보를 보낼 수 있을까요?

Apple의 현재 Send Consumption Information 문서에는 다섯 개의 필드가 정의되어 있습니다. 세 개는 필수, 두 개는 선택입니다.

필드

필수 여부

쉽게 말하면

customerConsented

고객이 이에 동의했는가? true여야 하며, 그렇지 않으면 요청이 거부됩니다.

deliveryStatus

앱이 실제로 정상 작동하는 구매 항목을 제공했는가? 아니라면 그 이유는 무엇인가?

sampleContentProvided

고객이 구매 전에 미리 사용해 볼 수 있었는가?

consumptionPercentage

아니요

얼마나 사용했는가? 단위는 밀리유닛으로, 절반은 50이 아니라 50000입니다.

refundPreference

아니요

개발자가 선호하는 처리 방식: 전액 승인, 거부, 또는 비례 배분(prorate).

사람들이 흔히 걸려 넘어지는 규칙이 두 가지 있습니다. 제공 상태가 '제공됨'이 아니라면 소비율은 반드시 0이어야 합니다. 그리고 환불 선호는 선호일 뿐 지시가 아닙니다. Apple은 다르게 결정할 수 있고 실제로 그렇게 합니다.

어떤 엔드포인트를 사용하고 있는지 확인해 볼 필요가 있습니다. Apple은 Apple의 ConsumptionRequestV1 문서도 제공하는데, 이는 12개 필드 본문을 사용하는 이전 버전으로 대부분의 서드파티 글이 여전히 설명하는 버전입니다. 해당 문서의 Apple 안내는 표준 인앱 구매를 현재 엔드포인트로 안내하고 V1은 Advanced Commerce API 구매로 범위를 한정하고 있습니다. 연동이 이 변경 이전에 구축되었다면 가장 먼저 확인해야 할 부분입니다.

CONSUMPTION_REQUEST에 응답할 시간은 얼마나 될까요?

Apple의 현재 문서는 알림 후 12시간 이내 응답을 요구합니다.

여기서 주목할 부분이 있습니다. Apple은 전송에 실패하면 이전 시도로부터 1, 12, 24, 48, 72시간 후에 총 다섯 번 재시도합니다. 이를 12시간 기한과 나란히 놓고 계산해 보면 불편한 결과가 나옵니다. 엔드포인트가 첫 전송을 놓치면 첫 재시도는 한 시간 뒤에 도착하므로 문제없습니다. 그마저 놓치면 다음 시도는 약 13시간 시점에 도착하는데, 이미 기한이 지난 뒤입니다.

따라서 여기서 엔드포인트 안정성은 일반적인 관리 차원의 문제가 아닙니다. 소비 요청에 한해서는 대략 한 시간의 다운타임은 복구 가능하지만 반나절은 그렇지 않습니다.

Apple은 기한을 놓치면 환불이 자동 승인된다고 명시하지 않으며, 그렇게 주장하는 것은 잘못입니다. 그저 개발자가 제공할 수 있었던 정보 없이 Apple이 결정을 내린다는 의미일 뿐입니다.

개발자가 응답한 후에는 어떻게 될까요?

Apple은 제공된 정보를 심사에 반영하고 다른 모든 요소와 함께 검토한 뒤 결정합니다. 결과는 별도의 알림으로 도착합니다: 승인, 거부, 또는 Apple이 승인했던 환불을 나중에 취소하는 경우의 번복입니다.

여기에는 서로 다른 세 가지가 일어나고 있으며, 이를 구분해 두면 도움이 됩니다. 개발자의 응답은 정보입니다. Apple의 결정은 결정입니다. 시스템 업데이트는 상태 변경입니다. 이 중 Apple의 몫은 가운데 것뿐이고, 세 번째는 직접 구축하지 않으면 일어나지 않습니다.

응답 이후 Apple 환불을 처리하는 방법

결과가 도착하면 작업은 다시 개발자에게 넘어옵니다.

트랜잭션과 고객에 대해 결과를 기록하세요. 환불된 기간은 보통 구독을 계속 유지하기보다 종료시키므로 구독 상태를 업데이트하세요. 환불이 승인되면 권한을 회수하고, 번복되면 복원하며, 트랜잭션의 일부만 회수되는 비례 배분 케이스도 처리하세요.

그런 다음 금액을 올바른 보고 기간에 맞춰 정산하고 환불을 조회 가능한 이력으로 보관하세요. 이 이력이 있어야 나중에 특정 제품이나 가격대가 과도한 비중을 차지하는지 알 수 있고, 고객이 자신의 이용 권한에 무슨 일이 생겼는지 물을 때 지원팀에도 꼭 필요합니다.

CONSUMPTION_REQUEST 처리 시 흔한 실수는 무엇일까요?

반복적으로 나타나는 실수들입니다:

• 알림을 환불로 간주하고 즉시 접근 권한을 회수하는 것. 아직 아무것도 결정되지 않았습니다.

• 테스트에서 페이로드가 멀쩡해 보인다는 이유로 서명 검증을 건너뛰는 것.

• 응답해야 할 순간에야 동의 절차가 없다는 사실을 발견하는 것.

• 실제 수치 대신 추정 소비 수치를 보내는 것.

• 요청을 보내고 성공 여부를 확인하지 않는 것. 제출이 실패해도 나중에 보면 성공한 것과 똑같아 보입니다.

• 취소와 환불을 혼동하는 것. 둘은 서로 다른 이벤트이며 접근 권한에 미치는 영향도 다릅니다.

• 승인과 거부 결과는 처리하면서 번복 케이스를 빠뜨리는 것. 그러면 결제한 고객이 접근하지 못하게 됩니다.

• 12시간 시계가 돌아가는 상황에서 누군가 알림을 수동으로 알아차리기를 기대하는 것.

CONSUMPTION_REQUEST 처리를 자동화할 수 있을까요?

예, 그리고 거의 전부 자동화해야 합니다. 거의 모든 단계가 결정론적이기 때문입니다.

자동화는 알림 모니터링과 검증, 트랜잭션 조회, 동의 확인, 소비 데이터 준비, 제출, 응답 로깅, 결과 추적, 내부 알림, 리포팅을 담당합니다. 이 중 어느 것도 그 순간의 판단을 필요로 하지 않습니다.

사람의 몫으로 남는 것은 그 이전 단계입니다. 앱 안의 동의 절차를 설계하는 것, 그리고 환불 선호 정책을 어떻게 가져갈지 정하는 것입니다. 그리고 일부 툴이 어떻게 암시하든, 자동화는 Apple의 결정에 아무런 영향을 주지 않습니다.

RefundSensor가 Apple 환불 워크플로 처리를 돕는 방법

App Store 환불 관리가 이 카테고리이며, RefundSensor는 그중 개발자 측을 담당합니다: Apple 환불 워크플로 모니터링, 소비 요청에 대한 공식 지원 응답 경로 처리, 환불 이벤트와 결과 추적, 그리고 반복적인 작업을 사람 손에서 덜어내는 것입니다.

실제로는 새벽 3시에 누군가 dashboard를 지켜보지 않아도 응답이 기한 안에 나가고, 볼륨이 늘어나도 환불 기록이 정확하게 유지됩니다. 환불을 막아 주지는 않으며 Apple의 결정에 영향을 줄 수도 없습니다. 수동 모니터링과 놓치는 단계를 없애 줄 뿐입니다.

이 규칙들이 문서화된 곳

Send Consumption Information — 현재 엔드포인트. 동의 요건, 12시간 기한, 다섯 개의 요청 필드. 표준 인앱 구매는 이 문서를 기준으로 구축하세요.

Send Consumption Information V1 — 12개 필드 본문을 사용하는 이전 엔드포인트. 연동이 어떤 버전을 호출하는지 파악하거나 Advanced Commerce API 구매를 처리할 때 유용합니다.

App Store Server Notifications — 알림 전송, 서명된 페이로드 형식, 기대되는 응답 코드, 재시도 일정.

아직 수동으로 처리하고 있다면

12시간 기한, 그보다 길어질 수 있는 재시도 일정, 그리고 한밤중에 도착하는 알림은 수동 모니터링과 어울리지 않습니다. RefundSensor는 이 워크플로의 개발자 측을 담당합니다. 알림을 검증하고, 기한 안에 응답을 준비해 제출하며, 권한 기록까지 결과를 추적합니다.

자주 묻는 질문

고객이 환불을 요청했으며 Apple이 해당 구매에 대한 소비 정보를 보내 달라고 요청한다는 사실을 서버에 알려주는 App Store Server Notification입니다. 환불 알림도 아니고 결정도 아닙니다. Apple은 별도로 결정을 내리며, 개발자의 응답은 여러 요소 중 하나로만 반영됩니다.

Apple은 앱 내부에서 무슨 일이 있었는지 볼 수 없기 때문입니다. 트랜잭션과 계정 이력은 알지만, 콘텐츠가 제공되었는지, 정상 작동했는지, 고객이 얼마나 사용했는지는 알지 못합니다. 그 맥락은 개발자의 시스템에 있으므로 Apple이 심사 과정에서 이를 요청하는 것입니다.

서명된 알림을 검증하고, 트랜잭션과 그 뒤의 고객을 식별하고, 동의가 있는지 확인하고, 자체 기록에서 실제 제공 및 사용 데이터를 수집한 다음, 기한 안에 Apple의 소비 정보 엔드포인트에 제출합니다. 호출이 성공했다고 가정하지 말고 응답 결과를 기록하세요.

현재 엔드포인트에는 다섯 개의 필드가 있습니다. 필수 세 개: 고객 동의, 제공 상태, 샘플 콘텐츠 제공 여부. 선택 두 개: 소비율과 환불 선호. 이전 V1 엔드포인트는 12개 필드를 요구했기 때문에 오래된 가이드에서는 더 긴 목록을 설명합니다.

Apple의 현재 문서는 이전 문서보다 넓은 범위로, 모든 제품 유형의 환불 요청과 관련해 이 알림을 설명합니다. Apple은 모든 경우에 알림이 온다고 보장하지 않으므로, 항상 온다고 가정하는 로직보다는 요청이 도착했을 때 응답하는 핸들러를 구축하세요.

Apple은 알림 후 12시간 이내 응답을 요구합니다. 참고로 전송 실패에 대한 Apple의 재시도 일정은 1, 12, 24, 48, 72시간이므로, 첫 재시도 이후까지 다운된 엔드포인트는 기한이 이미 지난 뒤에야 알림을 받을 수 있습니다.

Apple은 다른 요소와 함께 이를 검토하고 결정합니다. 결과는 환불이 승인, 거부, 또는 이후 번복되었음을 알리는 별도의 알림으로 도착합니다. 그 이후에는 새로운 트랜잭션 상태에 맞춰 권한, 구독 상태, 매출 기록을 업데이트하는 것이 개발자의 몫입니다.

예. 검증, 트랜잭션 조회, 동의 확인, 데이터 준비, 제출, 로깅, 결과 추적은 모두 결정론적입니다. 사람의 몫으로 남는 것은 동의 절차 설계와 환불 선호 정책 수립입니다. 자동화는 Apple의 환불 결정에 아무런 영향을 주지 않습니다.

#Apple refunds#Subscription apps#App Store#iOS development#CONSUMPTION_REQUEST#Apple StoreKit
Refund SensorRefund Sensor TeamRefund defense for App Store and Google Play developers