모든 글
심층 분석8분 소요

Apple의 Retention Messaging API는 해지 화면에 당신의 문구를 띄워 주지만, 환불 요청은 그곳을 거치지 않습니다

Apple의 Retention Messaging API를 쓰면 구독자가 해지를 탭할 때 메시지, 요금제 변경 제안 또는 프로모션 혜택을 보여 줄 수 있습니다. 작동 방식과 운영 비용, 그리고 환불 요청이 그 화면을 전혀 거치지 않고 Apple에 도달하는 이유를 설명합니다.

카페 테이블에서 구독 설정 화면이 열린 iPhone을 들고 있는 사람. Apple의 Retention Messaging API가 겨냥하는 바로 그 순간

핵심 요약

  • Apple의 Retention Messaging API는 iPhone 구독자가 Cancel Subscription(구독 취소)을 탭한 뒤 보게 될 메시지를 개발자가 고르게 해 줍니다. 유형은 텍스트, 이미지가 포함된 텍스트, 요금제 변경 제안, 프로모션 혜택의 네 가지입니다.
  • Apple 문서는 여전히 Retention Messaging API를 개발자가 참여를 신청하는 사전 출시 기능으로 설명합니다. 버전 1.0은 2025년 7월 16일에, 버전 1.5는 2026년 4월 27일에 나왔습니다.
  • 실시간 흐름에서는 활성 구독자가 취소 버튼이 있는 구독 상세 페이지를 볼 때 Apple이 개발자의 Get Retention Message 엔드포인트를 호출합니다. 프로덕션에서는 엔드포인트가 700 ms 안에 응답해야 하며, 그렇지 못하면 Apple은 기본 메시지로 대체합니다.
  • 리텐션 메시지는 앞으로의 갱신에만 영향을 줍니다. 환불 요청은 reportaproblem.apple.com이나 앱 내 환불 시트를 통해 Apple로 가며, 리텐션 메시지가 표시되는 해지 화면은 그 경로에 포함되지 않습니다.
  • 고객이 앱 안에서 StoreKit의 환불 요청 API로 환불을 요청하면 Apple이 직접 자동 갱신을 끄고 하위 유형이 AUTO_RENEW_DISABLED인 DID_CHANGE_RENEWAL_STATUS를 보냅니다. 구독 설정 페이지에서 해지했을 때와 유형과 하위 유형이 똑같습니다.
  • Apple 환불에서 개발자가 의견을 낼 수 있는 유일한 통로는 CONSUMPTION_REQUEST입니다. 12시간 안에 Send Consumption Information으로 응답해야 하며, 고객이 해당 데이터 공유에 동의한 경우에만 가능합니다.
  • Google Play에는 개발자가 해지 화면 메시지를 고르는 기능에 해당하는, 문서화된 기능이 없습니다. 개발자는 사후에 SUBSCRIPTION_CANCELED 알림을 받고, userInitiatedCancellation 필드로 구독자가 떠난 이유를 알 수 있습니다.

iPhone에서 해지를 탭한 구독자에게 이제 확정하기 전에 당신이 고른 메시지, 더 저렴한 요금제, 또는 할인을 보여 줄 수 있습니다. 이것이 Apple의 Retention Messaging API이며, 개발자가 Apple의 자체 해지 화면에 목소리를 낼 수 있게 된 것은 처음입니다. 아직은 참여를 신청해야 하는 사전 출시 기능입니다. 그리고 환불에 관심이 있다면 중요한 분명한 경계가 있습니다. 이 API가 말을 거는 대상은 결제를 멈추려는 사람이지, 돈을 돌려받으려는 사람이 아닙니다. 그런 요청은 다른 길로 Apple에 갑니다.

Apple의 Retention Messaging API가 하는 일

Retention Messaging API는 서버 간 서비스입니다. 메시지 텍스트와 이미지를 미리 Apple에 업로드하면 Apple이 검토하고, 그다음 자동 갱신 구독을 해지하려는 구독자에게 승인된 메시지 중 어떤 것을 보여 줄지 고릅니다. Apple 문서에는 네 가지 메시지 유형이 나와 있습니다.

  • 텍스트 메시지. 글머리 기호를 포함할 수 있습니다.
  • 이미지가 포함된 텍스트 메시지.
  • 요금제 변경 메시지. 같은 구독 그룹 안의 다른 구독을 제안합니다.
  • 프로모션 혜택 메시지. 같은 등급이나 다른 등급에서 할인 가격을 제시하며, App Store Connect에서 설정하고 서버에서 서명한 프로모션 혜택을 사용합니다.

메시지는 고객이 구독 상세 페이지에서 Cancel Subscription을 탭한 뒤에 나타납니다. 그다음 Apple은 Confirm Cancellation(취소 확인) 페이지를 보여 줍니다. 고객은 그래도 해지할 수 있고, Keep Subscription(구독 유지)을 탭하거나 당신이 제안한 혜택이나 요금제를 받아들일 수도 있습니다. 나가는 길을 숨길 수는 없으며, Apple은 개발자에게 오해의 소지가 있거나 부정확한 콘텐츠를 업로드하지 말라고 안내합니다.

기본 메시지와 실시간 흐름

운영 방식은 두 가지입니다. 간단한 쪽은 기본 메시지로, 제품과 로케일별로 지정하는 텍스트이며 이미지나 글머리 기호는 넣어도 되고 빼도 됩니다. 더 풍부한 쪽은 실시간 흐름으로, Apple이 당신의 서버에 있는 Get Retention Message 엔드포인트를 호출하면 메시지 ID로 응답합니다. 요금제 변경 메시지와 프로모션 혜택 메시지는 실시간 흐름에서만 보여 줄 수 있습니다.

실제로 기본 메시지는 선택 사항이 아닙니다. 실시간 호출이 실패할 때마다 Apple은 기본 메시지로 대체하며, 기본 메시지가 없는 로케일에서는 해당 제품에 리텐션 메시지를 아예 표시하지 않습니다.

항목Apple 문서의 내용
상태사전 출시, 개발자가 관심을 표명해 참여
대상 제품자동 갱신 구독
메시지 유형텍스트, 이미지가 포함된 텍스트, 요금제 변경, 프로모션 혜택
실시간 응답 제한프로덕션에서 700 ms
프로덕션 접근먼저 샌드박스 성능 테스트 통과 필요(약 700 ms)
제목 및 글머리 기호 텍스트각 66자, 글머리 기호는 최대 다섯 개
본문 텍스트144자
이미지 대체 텍스트150자
앱당 메시지 수2,000
검토새 메시지는 PENDING으로 시작하며 APPROVED가 되어야 표시
기기iOS 15.1, iPadOS 15.1, visionOS 1, macOS 14 이상

실시간 호출에서 Apple이 서버에 알려 주는 것

요청은 App Store가 서명한 JWS입니다. 디코딩하면 originalTransactionId, appAppleId, productId, userLocale, requestIdentifier UUID, 환경, signedDate가 들어 있습니다. Apple은 appAppleId가 당신의 앱과 일치하는지 확인하고, 일치하지 않으면 응답하지 말라고 안내합니다. 유용한 부분은 originalTransactionId입니다. 무슨 말을 할지 정하기 전에 이 구독자가 앱에서 실제로 무엇을 했는지 조회할 수 있기 때문입니다.

리텐션 메시지가 나타나는 곳과 나타나지 않는 곳

Apple은 메시지를 한 화면에만 띄웁니다. 고객이 Cancel Subscription을 탭한 뒤의 Confirm Cancellation 단계로, 예를 들어 Apple Account > Subscriptions나 App Store의 구독 페이지에서 들어가는 화면입니다. 이 화면이 다루는 것은 다음 갱신이 일어나느냐입니다. 이미 받은 돈에는 영향을 주지 않습니다.

환불 요청은 별개의 행위입니다. Apple 지원 페이지는 고객을 reportaproblem.apple.com으로 안내하고, 고객은 그곳에서 Request a refund(환불 요청)를 선택하고 사유와 항목을 고른 뒤 24시간에서 48시간 안에 진행 상황을 기다립니다. 앱 안에서는 StoreKit의 beginRefundRequest가 Apple의 환불 시트를 열며, Apple은 App Store가 승인 또는 거절하는 데 최대 48시간이 걸린다고 밝힙니다. 어느 경로도 Confirm Cancellation 화면을 거치지 않습니다.

순간일어나는 곳걸려 있는 것결정하는 쪽당신의 입력
해지구독 상세 페이지, 이어서 Confirm Cancellation앞으로의 갱신고객당신이 고른 리텐션 메시지(700 ms 안에 응답)
환불 요청reportaproblem.apple.com 또는 앱 내 환불 시트이미 지불된 돈Apple12시간 안에 보내는 CONSUMPTION_REQUEST 데이터(고객이 동의한 경우)

리텐션 메시지로 환불 요청을 막을 수 있나요?

없습니다. 환불 요청은 메시지가 있는 화면에 아예 도달하지 않습니다. Apple의 알림 문서에 이를 구체적으로 보여 주는 세부 사항이 있습니다. 고객이 앱에서 환불 요청 API로 환불을 요청하면 Apple이 스스로 자동 갱신을 끄고 하위 유형이 AUTO_RENEW_DISABLED인 DID_CHANGE_RENEWAL_STATUS를 보냅니다. 구독 설정 페이지에서 해지한 고객도 똑같은 유형과 하위 유형을 만듭니다. 서버는 전혀 다른 두 고객에 대해 같은 알림 하나를 받고, 그중 리텐션 메시지를 본 사람은 한 명뿐입니다.

환불 요청이 진행되면 증거를 전달하는 통로는 CONSUMPTION_REQUEST입니다. Apple은 모든 제품 유형의 환불 요청에 대해 이를 보내며, 당신에게는 Send Consumption Information으로 응답할 시간이 12시간 있습니다. 응답은 고객이 동의한 경우에만 할 수 있습니다. 그 뒤 Apple의 결정은 REFUND 알림으로 도착하고, 고객이 앱에서 시작한 환불을 Apple이 거절하면 REFUND_DECLINED로 도착합니다.

Google Play에 해지 메시지 API가 있나요?

Google의 구독 수명 주기 문서에는 없습니다. Google Play 구독자는 Play 정기 결제 센터에서 해지하고, 현재 결제 주기가 끝날 때까지 이용 권한을 유지하며, 그 전에 Resubscribe(재구독)를 탭해 해지를 되돌릴 수 있습니다. Google은 이를 복원이라고 부릅니다. 당신은 사후에 SUBSCRIPTION_CANCELED 알림으로 알게 되고, 구독 리소스의 userInitiatedCancellation 필드가 사용자가 떠난 이유를 알려 줍니다. 일시중지는 Google에 따르면 모든 구독에서 기본으로 사용 설정되어 있으며, 자발적 이탈을 줄이는 주된 내장 수단입니다.

환불 쪽에서 Google Play에는 자체 증거 통로가 있습니다. 지불 거절에 개발자 검토가 필요하면 PendingRefundReviewNotification이 도착하고, orders.reviewrefund를 통해 응답할 시간이 24시간 있습니다. 2026년 8월 3일 이후에 이루어진 주문의 경우, 지불 거절이 확정되면 Google은 구매 가격에서 Play 서비스 수수료를 뺀 금액과 은행의 지불 거절 수수료를 개발자에게 넘깁니다.

해지 화면에 드는 돈

리텐션 메시지는 공짜처럼 보입니다. 그렇지 않으며, 청구서는 세 군데에서 나옵니다.

페이지 조회마다 드는 컴퓨팅

Apple은 해지할 때만이 아니라 활성 구독자가 취소 버튼이 있는 구독 상세 페이지를 볼 때 엔드포인트를 호출합니다. 방문할 때마다 서버는 700 ms 안에 인증하고 조회하고 응답해야 하며, 그러지 못하면 Apple은 기본 메시지로 대체합니다. 그래서 가끔 2초씩 걸리는 콜드 스타트 함수는 쓸 수 없습니다. 항상 웜 상태를 유지하는 용량에 비용을 내야 하고, 결정 로직이 요청마다 수행하는 데이터베이스 읽기와 유료 서드파티 API 호출 비용도 더해집니다.

책상에 앉은 개발자가 노트북과 iPhone 옆의 모니터에서 서버 응답 시간 그래프를 지켜보는 모습. Apple의 Retention Messaging API가 전제하는 상시 가동 엔드포인트

할인은 스스로 받지 않기로 한 매출

구독자를 붙잡은 프로모션 혜택은 실제로 지킨 돈입니다. 어차피 남았을 사람에게 간 혜택은 순전한 할인입니다. 다음은 벤치마크가 아니라 예시입니다. 월 $9.99 요금제를 3개월간 반값에 제공하면 혜택이 수락될 때마다 $14.99를 포기합니다. 수락한 사람 셋 중 한 명이 정가로도 남았을 사람이라면, 1,000건의 수락은 필요 없던 사람들에게 약 $5,000의 할인을 준 셈입니다. 장부의 반대편에는 정말로 떠나려던 구독자들이 있습니다.

거친 출구가 부르는 환불

Apple은 Cancel Subscription 버튼을 페이지에 그대로 두므로 누구도 가둘 수 없지만, 여전히 짜증을 유발할 수는 있습니다. 밀어붙여진다고 느낀 고객에게는 다른 선택지가 있습니다. 바로 Apple에 마지막 결제 금액을 돌려 달라고 하는 것입니다. 환불이 실제로 이루어지면 돈은 돌아가고, 그 구독자와 연결된 컴퓨팅, 스토리지, API 호출, 제휴 지급액은 이미 쓴 그대로 남습니다. 어떤 리텐션 메시지로도 되찾을 수 없는 비용입니다.

환불률을 올리지 않고 리텐션 메시지를 쓰는 법

해지 화면은 영리하게 굴 곳이 아니라 정확해야 할 곳으로 여기세요. 몇 가지 규칙을 지키면 환불선의 안전한 쪽에 머물 수 있습니다.

  • 구독자별로 결정하세요. Apple 요청에 담긴 originalTransactionId로 최근 사용 내역을 조회합니다. 제품을 쓰는 사람에게는 할인이나 더 저렴한 요금제를 제안합니다. 몇 주째 열어 보지 않은 사람에게는 짧고 정직한 메시지를 보여 줍니다.
  • 응답을 빠르게 유지하세요. 사용 데이터가 바뀔 때 결정을 미리 계산해 두면, 요청 자체는 700 ms 안에 넉넉히 들어오는 한 번의 조회로 끝납니다.
  • 모든 제품과 로케일에 기본 메시지를 작성하세요. 기본 메시지가 없으면 호출이 실패했을 때 아무 메시지도 나오지 않습니다.
  • AUTO_RENEW_DISABLED를 주의 깊게 보세요. 같은 originalTransactionId에 대해 CONSUMPTION_REQUEST가 뒤따르면 그것은 해지가 아니라 환불 요청이며, 12시간 카운트다운이 이미 시작된 것입니다.
  • 응답이 허용된 CONSUMPTION_REQUEST에는 모두 응답하세요. RefundHalt는 12시간 안에 정확한 소비 데이터를 Apple에 보내고 Google Play의 지불 거절 검토에는 24시간 안에 응답합니다. 두 스토어가 당신 쪽의 이야기를 묻는 순간은 이 두 번뿐이기 때문입니다.

Apple에 이용 신청을 할 가치가 있을까요?

자동 갱신 구독을 판매하고 이미 App Store Server Notifications V2를 처리하고 있다면 아마 그렇습니다. 해지 화면은 구독자가 떠나기 전에 닿을 수 있는 마지막 장소이고, 요금제 변경은 구독자를 완전히 잃는 것보다 비용이 적게 듭니다. 다만 구독 페이지가 조회될 때마다 응답하는 엔드포인트에 예산을 잡아 두고, 환불 방어는 환불이 실제로 일어나는 곳에 두세요.

자주 묻는 질문

Apple의 Retention Messaging API란 무엇인가요?
개발자가 자동 갱신 구독에서 구독자가 Cancel Subscription을 탭한 뒤 보게 될 메시지를 고를 수 있게 해 주는 서버 간 API입니다. Apple은 텍스트, 이미지가 포함된 텍스트, 요금제 변경 제안, 프로모션 혜택의 네 가지 유형을 지원합니다. Apple 문서는 여전히 이를 개발자가 참여를 신청하는 사전 출시 기능으로 설명합니다.
Get Retention Message 엔드포인트는 얼마나 빨리 응답해야 하나요?
프로덕션에서 700 ms 안에 응답해야 합니다. 서버가 느리거나 실패하면 Apple은 해당 제품과 로케일에 설정된 기본 메시지를 보여 주고, 기본 메시지가 없으면 아무것도 보여 주지 않습니다. 또한 Apple이 프로덕션 URL 설정을 허용하기 전에 약 700 ms 기준의 샌드박스 성능 테스트를 통과해야 합니다.
고객이 환불을 요청할 때 리텐션 메시지가 나타나나요?
아니요. Apple은 고객이 Cancel Subscription을 탭한 뒤의 Confirm Cancellation 화면에서 리텐션 메시지를 보여 줍니다. 환불 요청은 reportaproblem.apple.com이나 beginRefundRequest로 열리는 앱 내 환불 시트를 거치며, 그곳에서 개발자가 할 수 있는 유일한 입력은 CONSUMPTION_REQUEST입니다. 고객이 동의한 경우 12시간 안에 응답합니다.
App Store Server Notifications에서 환불 요청과 해지를 어떻게 구분하나요?
갱신 알림만으로는 구분할 수 없습니다. 구독 설정 페이지에서의 해지와 앱을 통한 환불 요청 모두 하위 유형이 AUTO_RENEW_DISABLED인 DID_CHANGE_RENEWAL_STATUS를 만듭니다. 같은 거래에 대한 CONSUMPTION_REQUEST, 그리고 이후의 REFUND 또는 REFUND_DECLINED 알림이 환불 요청이 진행 중임을 보여 줍니다.
Google Play는 사용자가 해지할 때 개발자가 메시지를 보여 줄 수 있게 하나요?
Google의 구독 수명 주기 문서에는 그런 기능이 설명되어 있지 않습니다. 개발자는 사후에 SUBSCRIPTION_CANCELED 알림을 받고 userInitiatedCancellation 필드를 읽어 사용자가 해지한 이유를 확인할 수 있습니다. 모든 구독에서 기본으로 사용 설정된 일시중지가 자발적 이탈에 대응하는 Google Play의 주된 내장 도구입니다.

출처 및 추가 자료

RefundHalt

App Store와 Google Play 환불 자동 처리

계속 읽기

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

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