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

Apple과 Google은 각자 스토어 단위로만 환불합니다. 크로스플랫폼 구독은 나머지 모든 곳에서 직접 접근을 끊어야 합니다

Apple이나 Google이 크로스플랫폼 구독을 환불해도 Android 앱, iPhone 앱, 웹사이트는 스스로 알지 못합니다. 각 스토어 구매를 하나의 계정에 연결하고, 올바른 이용 권한을 회수하고, 환불받은 사용자에게 드는 서비스 비용을 멈추는 방법을 정리했습니다.

책상 위에 나란히 놓인 iPhone, Android 휴대전화, 노트북. 모두 같은 크로스플랫폼 구독 계정에 로그인되어 있다

핵심 요약

  • Apple의 App Review Guideline 3.1.3(b)는 여러 플랫폼에서 운영되는 앱이 다른 플랫폼이나 개발자 웹사이트에서 획득한 콘텐츠와 구독에 사용자가 접근하도록 허용합니다. 단, 해당 항목이 앱 내에서도 인앱 구매로 제공되어야 합니다.
  • Apple과 Google은 자기 스토어에서 이루어진 구매만 환불합니다. 따라서 크로스플랫폼 구독에 대한 Apple의 환불은 고객의 Google Play 결제나 웹 결제에 영향을 주지 않습니다. 각 플랫폼에서 부여한 접근 권한은 개발자의 서버가 직접 회수해야 합니다.
  • Apple은 소모성, 비소모성, 비갱신 구독, 자동 갱신 구독을 환불할 때 App Store Server Notifications V2로 REFUND 알림을 보내며, 환불된 각 거래를 저장하고 모니터링하고 조치할 책임이 개발자에게 있다고 밝힙니다.
  • Apple의 appAccountToken은 개발자가 인앱 구매에 붙이는 UUID이며, App Store Server API의 Set App Account Token 엔드포인트를 사용하면 오퍼 코드 사용처럼 앱 밖에서 이루어진 구매에도 나중에 추가할 수 있습니다.
  • Google Play의 setObfuscatedAccountId는 구매를 개발자 앱의 계정에 연결합니다. 최대 64자로 제한되며, 이메일 같은 평문 개인정보가 들어 있으면 구매가 차단됩니다.
  • Google Play의 Voided Purchases API는 환불되거나 차지백된 구매를 orderId와 voidedSource와 함께 보고합니다. voidedSource는 0이 사용자, 1이 개발자, 2가 Google입니다.
  • 2026년 8월 3일 이후 접수된 Google Play 주문의 경우, 차지백이 확정되면 개발자는 Play 서비스 수수료를 뺀 구매 금액에 더해 은행의 차지백 수수료까지 부담합니다.

구독자가 Apple에 결제하고, 같은 날 오후 Android 앱을 열었고, 지금은 회사에서 웹사이트를 쓰고 있습니다. 그런데 Apple이 이 사람에게 환불을 해 줍니다. Google Play는 모릅니다. 웹 결제 시스템도 모릅니다. 여러분의 서버가 직접 접근을 끊지 않는 한, 환불된 크로스플랫폼 구독은 계정 데이터베이스를 읽는 모든 화면에서 계속 작동합니다. 스토어는 한 번에 한 매장씩만 환불하고, 구독 전체가 존재하는 곳은 여러분의 계정 시스템뿐입니다. 그래서 구독을 끝낼 수 있는 곳도 그곳뿐입니다.

한 스토어의 환불로 크로스플랫폼 구독이 끝나지 않는 이유

Apple은 이런 구조를 명시적으로 허용합니다. App Review Guideline 3.1.3(b), 즉 Multiplatform Services 조항은 여러 플랫폼에서 운영되는 앱이 다른 플랫폼이나 여러분의 웹사이트에서 획득한 콘텐츠, 구독, 기능에 사용자가 접근하도록 허용할 수 있다고 규정합니다. 단, 해당 항목이 앱 내에서도 인앱 구매로 제공되어야 합니다.

여러 앱에서 하나의 구독을 제공하는 방법에 관한 Apple의 가이드는 실제 작동 방식을 설명합니다. 통합 계정 데이터베이스를 갖춘 여러분의 서버가 접근 권한을 부여하고, 모든 앱이 그곳에서 데이터를 읽습니다. 같은 가이드는 구매가 다른 앱에 전파되지 않으면 사용자가 같은 서비스에 두 번 이상 결제하게 될 수 있다고 경고합니다.

이 설계에는 흔히 놓치는 결과가 있습니다. 이용 권한은 여러분의 데이터베이스에 있지만, 각 스토어는 자기 영수증만 압니다. Apple은 iPhone 구매를 환불하고 여러분의 서버에 알릴 수는 있지만, Android 앱이나 웹사이트에는 아무것도 알릴 수 없습니다. 환불 처리 로직이 iOS 클라이언트만 갱신한다면, 고객은 돈을 돌려받고도 다른 모든 곳에서 구독을 계속 유지합니다.

결제한 곳환불을 결정하는 주체서버가 환불을 알게 되는 경로갱신을 중단할 수 있는 사람
App StoreAppleApp Store Server Notifications V2의 REFUND 알림고객 본인. App Store 구독 설정이나 앱이 여는 관리 화면에서
Google Play처음 48시간은 Google, 이후에는 여러분 또는 GoogleVoided Purchases API와 실시간 개발자 알림고객 본인, 또는 purchases.subscriptionsv2.cancel을 사용하는 여러분
자체 웹사이트여러분결제 대행사의 웹훅여러분

환불 후 모든 플랫폼에서 접근 권한을 회수하는 방법

모든 스토어 구매를 하나의 계정에 연결하기

어려운 부분은 환불을 특정 사람과 짝짓는 일입니다. 스토어마다 구매자를 식별하는 방식이 다르기 때문입니다. 두 스토어 모두 여러분의 계정 ID를 넣을 수 있는 필드를 제공합니다. 모든 구매에 이 필드를 사용하세요.

  • Apple에서는 구매를 시작할 때 appAccountToken을 설정합니다. 여러분이 생성하는 UUID입니다. App Store는 거래 정보와 갱신 정보에 같은 UUID를 돌려줍니다. Apple은 같은 고객에 속한 모든 거래에 하나의 값을 재사용해도 된다고 밝힙니다.
  • 고객이 앱 밖에서 구매했다면, 예를 들어 App Store에서 오퍼 코드를 사용했다면, 해당 거래에는 토큰이 없습니다. Set App Account Token 엔드포인트로 추가할 수 있습니다. 자동 갱신 구독의 경우 현재 갱신과 이후 갱신에만 적용되고 지난 거래에는 적용되지 않으며, 가족 공유로 공유된 구매에는 사용할 수 없습니다.
  • Google Play에서는 결제 흐름을 시작할 때 setObfuscatedAccountId로 난독화된 계정 ID를 전달합니다. 최대 64자로 제한됩니다. Google은 이메일 같은 평문 개인정보가 들어 있으면 구매가 차단된다고 밝히며, 암호화나 단방향 해시를 권장합니다.

두 스토어를 모두 수신하고, 하나의 이용 권한에 기록하기

Apple은 자동 갱신 구독을 포함해 모든 유형의 상품을 환불할 때 REFUND를 보냅니다. 고객이 제기한 이의 때문에 이미 승인한 환불을 취소할 때는 REFUND_REVERSED를 보냅니다. Google Play에서는 Voided Purchases API가 환불되거나 차지백된 구매를 나열하며, 각 항목에는 정확히 어느 구매나 갱신인지 식별하는 orderId가 붙습니다. 웹 결제 대행사도 자체 환불 이벤트를 보냅니다. 이 세 가지는 모두 같은 핸들러로 들어가 같은 레코드를 변경해야 합니다.

회수할 대상은 계정이 아니라 이용 권한

환불은 사람이 아니라 구매를 취소합니다. 환불된 구매로 생긴 접근 권한을 제거한 뒤, 그 계정에 남아 있는 권한을 다시 계산하세요. 고객이 다른 스토어에서도 활성 구독을 갖고 있다면 그 구독을 통해 접근 권한을 유지합니다. 그렇지 않다면 모든 클라이언트가 다음에 서버를 확인할 때 프리미엄 기능을 잃습니다.

같은 사람이 두 스토어에서 구독할 때

중복 구독은 이 문제의 나머지 절반입니다. Android에서 구독한 사람이 새 iPhone으로 바꾸고, 로그인하지 않은 채 다시 구독합니다. 이제 이 사람은 하나의 서비스에 두 번 결제하고 있고, 그중 한 건은 대개 환불 요청으로 이어집니다. Apple 커머스 팀은 Apple Developer Forums에서 한 개발자에게 답하며 이렇게 간단히 정리했습니다. 앱의 계정 시스템에는 다른 플랫폼에서의 중복 구매를 막는 로직이 있어야 한다고요.

페이월을 보여 주기 전에 모든 스토어를 확인하기

페이월 전에 사용자를 로그인시키고, 서버에서 그 사람의 활성 구매를 모두 조회한 뒤, 그중 하나라도 현재 플랫폼을 커버한다면 구매 제안을 건너뛰세요. 이 확인 하나로 대부분의 중복 결제를 사전에 막을 수 있습니다.

이미 중복 결제가 일어났다면 어느 구매를 환불해야 할까요?

여러분이 통제할 수 있는 쪽을 환불하세요. Google Play에서는 Play Console에서 직접 환불할 수 있고, DEVELOPER_REQUESTED_STOP_PAYMENTS를 지정한 purchases.subscriptionsv2.cancel로 다음 결제를 중단할 수 있습니다. 웹 구독은 전적으로 여러분이 환불할 수 있습니다. App Store 환불은 Apple이 결정하므로, 중복 구독이 iPhone 쪽에 있다면 고객이 Apple에 요청해야 하며, 앱에서 StoreKit의 환불 요청 API로 그 요청 화면을 열 수 있습니다.

한 플랫폼을 놓친 환불이 치르게 하는 비용

환불 금액은 첫 번째 손실일 뿐입니다. Apple 환불이 Android 앱이나 웹사이트에 전달되지 않은 고객은 여러분이 비용을 내고 운영하는 서비스를 계속 사용합니다. 세션마다 컴퓨팅 자원이 소모되고, AI 기능은 여러분에게 청구되는 서드파티 API를 계속 호출합니다. 파일은 계속 저장 공간을 차지하고, 앱이 조회 수나 사용량에 따라 크리에이터에게 정산한다면 그 지급도 계속 나갑니다. 연간 요금제라면 더 이상 한 푼도 내지 않는 계정을 위해 꼬박 1년 치 서비스 비용을 부담하게 될 수 있습니다.

은행을 통한 경로는 상황을 더 악화시킵니다. 2026년 8월 3일 이후 접수된 Google Play 주문에 대해 Google은 차지백이 확정되면 개발자가 Play 서비스 수수료를 뺀 구매 금액과 금융기관이 부과하는 차지백 수수료를 부담한다고 밝힙니다. 차지백은 은행 단계에서 최종 확정됩니다. 차지백을 하고도 접근 권한이 남아 있는 고객은 구매 금액, 수수료, 서비스 비용을 한꺼번에 여러분에게 떠넘깁니다.

회수 누락 후에도 계속 발생하는 것부담하는 사람
Android나 웹의 세션마다 드는 서버 컴퓨팅여러분
기능이 호출하는 서드파티 API여러분
사용자 파일과 기록을 위한 저장 공간여러분
크리에이터에게 사용량이나 조회 수에 따라 지급하는 정산금여러분
2026년 8월 3일 이후 Google Play 주문의 차지백 수수료여러분. 여기에 Play 서비스 수수료를 뺀 구매 금액까지
열려 있는 노트북 옆에서 손에 스마트폰을 들고 있고, 다른 휴대전화 한 대는 화면이 아래로 향하게 놓여 있다. 크로스플랫폼 구독 사용자의 일상적인 환경

크로스플랫폼 사용 기록도 증거가 됩니다

스토어가 여러분의 입장을 물을 때도 플랫폼을 아우르는 하나의 계정이 도움이 됩니다. Apple의 소비 정보는 고객이 소모성, 비소모성, 비갱신 구독 중 어느 정도를 소비했는지 묻습니다. 자동 갱신 구독은 비율을 보내지 않습니다. Apple이 경과 시간으로 계산하기 때문입니다. Google Play의 차지백 검토는 최대 1,000건의 소비 사용 이벤트를 받으며, 각 이벤트에 난독화된 계정 ID를 담을 수 있습니다. 어느 기기에서 발생했든 하나의 계정 ID 아래 기록된 사용 내역은 여러분이 제시할 수 있는 사용 내역입니다.

여러분의 입장을 묻지 않는 환불

대부분의 환불은 여러분 없이 결정됩니다. Google Play는 자체 환불 절차를 통해 48시간 이내에 구매를 환불할 수 있습니다. 스토어 고객 지원 환불, 무효화된 구매, 그리고 여러분이 확인 처리하지 않은 구매를 Google이 약 72시간 후 자동 환불하는 경우는 모두 먼저 실행되고 나중에 보고됩니다. 이런 경우에는 앞에서 설명한 회수 로직이 해야 할 일의 전부입니다.

증거를 요구하는 절차는 두 가지뿐입니다. Apple의 CONSUMPTION_REQUEST는 소비 정보를 보낼 수 있도록 12시간을 줍니다. Google Play의 차지백 검토는 PendingRefundReviewNotification 시점부터 24시간 안에 orders.reviewrefund로 답하도록 하며, Google은 첫 번째 호출만 기록합니다. RefundHalt는 여러분이 이미 수집하고 있고 여러 앱에 걸쳐 같은 계정을 키로 삼는 사용 데이터를 활용해 두 가지 모두 기한 안에 답합니다.

크로스플랫폼 환불을 위한 짧은 체크리스트

  • Apple 구매에는 appAccountToken을, Google Play 구매에는 난독화된 계정 ID를 설정하세요.
  • 오퍼 코드 사용으로 누락된 Apple 토큰은 Set App Account Token으로 채우세요.
  • Apple의 REFUND와 REFUND_REVERSED, Google Play의 무효화된 구매, 웹 환불을 하나의 핸들러로 모으세요.
  • 각 구매를 출처와 함께 저장하고, 모든 활성 구매를 바탕으로 접근 권한을 산출하세요.
  • 어느 플랫폼에서든 페이월을 보여 주기 전에 모든 스토어의 구매를 확인하세요.

자주 묻는 질문

Android나 제 웹사이트에서 구매한 구독을 iPhone 사용자가 이용하게 해도 되나요?
네. Apple의 App Review Guideline 3.1.3(b)는 여러 플랫폼에서 운영되는 앱이 다른 플랫폼이나 여러분의 웹사이트에서 획득한 콘텐츠, 구독, 기능에 사용자가 접근하도록 허용합니다. 단, 해당 항목이 iPhone 앱 내에서도 인앱 구매로 제공되어야 합니다.
Apple이 구독자에게 환불하면 Google Play나 제 웹 결제 시스템도 알게 되나요?
아니요. Apple은 App Store Server Notifications V2의 REFUND 알림으로 여러분의 서버에만 알리고, 다른 곳에는 알리지 않습니다. 해당 구매가 Android, 웹, 그리고 그 계정이 로그인하는 다른 모든 곳에서 부여한 접근 권한은 여러분의 서버가 회수해야 합니다.
App Store 환불을 사용자 계정과 어떻게 연결하나요?
appAccountToken을 사용하세요. 앱이 구매에 붙이는 UUID로, App Store가 거래 정보에 담아 돌려줍니다. 오퍼 코드 사용처럼 앱 밖에서 이루어진 구매는 Apple의 Set App Account Token 엔드포인트로 토큰을 추가하거나 교체할 수 있습니다. 가족 공유 거래는 지원하지 않습니다.
한 고객이 App Store와 Google Play 양쪽에서 구독하고 있습니다. 어느 쪽을 환불해야 하나요?
여러분이 통제할 수 있는 쪽을 환불하세요. Google Play 주문은 Play Console에서 환불하고 purchases.subscriptionsv2.cancel로 다음 결제를 중단할 수 있습니다. App Store 환불은 Apple이 결정하므로 iPhone 쪽 중복 구독은 Apple의 환불 요청을 거쳐야 하며, 앱에서 StoreKit으로 그 요청을 열 수 있습니다.
웹사이트나 Android 앱에서의 사용 기록도 환불 검토에서 증거가 되나요?
하나의 계정 아래 기록된 사용 내역은 여러분의 답변을 뒷받침할 수 있습니다. Apple의 소비 정보는 소모성, 비소모성, 비갱신 구독이 어느 정도 소비되었는지 묻고, Google Play의 차지백 검토는 난독화된 계정 ID를 담을 수 있는 사용 이벤트를 최대 1,000건까지 받습니다.

출처 및 추가 자료

RefundHalt

App Store와 Google Play 환불 자동 처리

계속 읽기

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

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