결제가 완료되고 고객은 상품을 받습니다. 그런데 3일 후 그 상품이 사라집니다. Google Play가 결제를 취소하고 권한(entitlement)을 회수하는데, 고객이 요청한 것도 아니고 지원팀 누군가가 버튼을 누른 것도 아닙니다. 서버가 처리 완료를 Google에 알리지 않았기 때문에 구매가 조용히 실패한 것입니다.
규칙은 이것뿐입니다. Google Play 구매는 3일 이내에 승인해야 하며, 그렇지 않으면 Google이 자동으로 환불하고 구매를 취소합니다. 예외 없이 매번 그렇습니다. 어느 스토어에서든 판매가 취소될 수 있는 여러 방식 중에서, 이것은 전적으로 여러분 자신의 연동(integration) 안에서 발생하는 극히 드문 경우이며, 그래서 가장 조용하게 매출을 갉아먹는 방식이기도 합니다.
이것은 부정 거래 검사도 아니고 정책 판단도 아닙니다. 발생하지 않은 콜백 때문입니다. 고치는 데 드는 노력은 작지만, 이를 건너뛰어서 잃는 돈은 작지 않습니다. 그러니 규칙이 정확히 무엇을 말하는지, 구매가 왜 이를 빠져나가는지, 그리고 사라진 판매 하나하나가 함께 끌고 내려가는 것이 무엇인지 정확히 알아둘 가치가 있습니다.
Google 공식 문서가 실제로 요구하는 것
Play Billing은 앱이 권한을 부여하고 사용자에게 구매가 완료되었음을 알린 후, 이를 Google에 알리도록 요구합니다. Google 공식 문서는 여기에 명확한 수치를 제시합니다. 이 알림은 "구매가 자동으로 환불되고 권한이 취소되지 않도록 3일 이내에 완료되어야 합니다." 1회성 상품 문서도 같은 내용을 에둘러 말하지 않고 그대로 반복합니다. 승인을 건너뛰면 "사용자는 자동으로 환불받게 되고, Google Play는 구매를 취소합니다." 구독의 최초 구매도 동일한 규칙을 따릅니다.
승인은 단순한 서류 작업이 아닙니다. 실제로 전달이 이루어졌다는 것을 Google이 알 수 있는 유일한 신호입니다. 신호가 없으면 Google은 아무것도 전달되지 않았다고 간주하고, 여러분과 상의 없이 구매자에게 전체 거래를 되돌려줍니다. 구매자는 예상치 못한 환불을 보게 됩니다. 여러분은 장부에서 사라진 판매를 보게 됩니다.
핵심 요약
판매를 72시간 동안 확인하지 않은 채로 두면 취소가 저절로 일어납니다. 구매자는 환불받고, 권한은 회수되며, 아무도 그 과정에 관여하지 않습니다. 구매자가 이를 유발한 것이 아닙니다. 여러분의 백엔드가 아무 말도 하지 않아서 벌어진 일이며, 같은 백엔드가 이를 막을 수도 있습니다.
카운트다운을 시작시키는 것은 PURCHASED 상태에 도달하는 순간이며, 따라서 결제 시점 자체는 기한과 무관합니다. PENDING 상태에 머물러 있는 것에는 타이머가 붙어 있지 않으며, 아직 승인 호출을 할 필요도 없습니다.
두 가지 호출 중 하나만 있으면 의무를 다한 것입니다. 소모성 상품에는 purchases.products.consume을 실행하고, 그렇지 않은 상품에는 purchases.products.acknowledge와 purchases.subscriptions.acknowledge를 사용합니다. Google은 둘 다 상품이 도착했다는 증거로 간주합니다.
구독은 가입 시점에 단 한 번만 이를 요구합니다. 그 이후의 모든 결제 주기는 Google이 직접 처리하여, 여러분의 코드가 손가락 하나 까딱하지 않아도 확인됨으로 표시됩니다.
7일 미만의 선불 요금제를 판매하고 있나요? 허용 기간은 요금제 지속 기간의 50퍼센트로 줄어듭니다. 상품이 짧을수록 퓨즈도 짧아집니다.
구매자에게 되돌아가는 것은 표시 가격뿐입니다. 컴퓨팅 시간, 모델 API 사용료, 스토리지 비용, 크리에이터 지급액은 모두 이미 처리 과정에서 여러분의 계정을 떠난 돈이며, 이 중 어느 것도 돌아오지 않습니다. 실제 피해는 환불 내역에 기록되는 숫자를 넘어섭니다.
iOS에서는 이런 방식으로 작동하는 것이 전혀 없습니다. StoreKit은 완료되지 않은 트랜잭션을 앱을 실행할 때마다 다시 제시하며 끈기 있게 기다릴 뿐, 결제를 취소하는 일은 결코 없습니다. 이 특정한 위험은 오직 Google Play에만 존재합니다.
기한은 결제 시점부터 시작되지 않습니다
"구매" 버튼을 누르는 것으로 타이머가 시작되지 않습니다. 구매 상태가 먼저 PURCHASED로 전환되어야 하며, 일부 구매는 그 전에 PENDING 상태에 머뭅니다. 현금 결제 방식이 그렇고, 느린 은행 이체와 부모 승인 요청도 마찬가지입니다. Google은 이를 직접적으로 명시합니다. "3일 승인 기간은 구매 상태가 PENDING에서 PURCHASED로 전환될 때만 시작됩니다."
이는 플로우를 설계하는 방식에 두 가지 의미를 갖습니다. 상태가 PURCHASED로 표시될 때만 권한을 부여하고, PENDING 상태에서는 절대 부여하지 마세요. 그렇지 않으면 실제로 들어오지 않을 수도 있는 돈을 받고 상품을 내주게 됩니다. 그리고 PENDING 상태의 구매는 승인하지도 마세요. 아직 승인할 대상이 없기 때문입니다. BillingClient를 설정할 때 enablePendingPurchases()를 호출하고, 상태 전환을 기다린 다음, PURCHASED에 도달했을 때만 카운트를 시작하세요.
PENDING은 "아직 판매되지 않음"으로 읽으세요. 아무것도 발생하지 않습니다. 권한도 없고, 승인도 없고, 매출로 기록되는 것도 없습니다. PURCHASED로 바뀌는 순간, 권한과 3일 카운트다운이 모두 여러분의 몫이 됩니다.
판매한 상품에 맞는 올바른 API 호출 선택하기
기한을 해결하는 API 경로는 두 가지이며, 어느 것을 적용할지는 무엇을 판매했는지에 따라 달라집니다. 둘 다 요구 사항을 동일하게 충족합니다. 둘을 구분하는 것은 그 이후 상품에 어떤 일이 일어나는가입니다.
소모성 상품은 소비(consume) 처리합니다. 보안 백엔드에서는 purchases.products.consume을, 클라이언트에서는 Play Billing Library의 consumeAsync()를 사용합니다. 소비 처리는 두 가지 역할을 동시에 합니다. 승인 요구 사항을 충족시키면서 해당 항목을 다시 구매 가능하게 만듭니다. 코인, 크레딧, 또는 고객이 반복해서 구매할 수 있는 일회성 생성물에는 이 방식이 적합합니다.
비소모성 상품과 구독은 대신 승인 처리를 합니다. purchases.products.acknowledge, purchases.subscriptions.acknowledge, 또는 클라이언트의 acknowledgePurchase()를 사용합니다. 이는 기한을 해결하지만 해당 항목을 다시 구매 가능하게 만들지는 않습니다.
각 상품 유형이 어떤 호출과 기한에 대응하는지는 다음과 같습니다.
For a 소모성 상품의 경우, purchases.products.consume 또는 consumeAsync()를 호출하세요. 이는 항목을 다시 구매 가능하게 만들며, 기한은 PURCHASED로부터 3일입니다.
For a 비소모성 상품의 경우, purchases.products.acknowledge 또는 acknowledgePurchase()를 호출하세요. 재구매 없이 권한이 확인되며, 기한은 PURCHASED로부터 3일입니다.
For the 구독의 최초 구매의 경우, purchases.subscriptions.acknowledge 또는 acknowledgePurchase()를 호출하세요. 이는 새 구독을 확인하며, 기한은 PURCHASED로부터 3일입니다.
For a 구독 갱신의 경우, 호출이 전혀 필요하지 않습니다. Google이 자체적으로 승인됨으로 표시하므로 기한도 없습니다.
For a 1주일보다 짧은 선불 요금제의 경우, 동일한 승인 호출을 사용하지만 기한은 요금제 기간의 절반으로 줄어듭니다.
의무는 첫 결제에서 끝납니다
구독 갱신은 승인이 전혀 필요하지 않습니다. Google은 이를 직접적으로 말합니다. "구독 갱신은 승인할 필요가 없습니다." Google이 각 갱신을 자체적으로 승인됨으로 표시합니다. 승인 대기 상태로 도착해 여러분이 해결하기 전까지 남아 있는 것은 구독의 바로 그 첫 구매뿐입니다. 조치를 취하기 전에 서버 측에서 승인 상태를 확인하거나, 클라이언트에서 isAcknowledged()를 사용하세요. 그러면 승인 호출을 중복으로 보내는 일이 없습니다.
단기 선불 요금제에는 더 짧은 시계가 적용됩니다
1주일 이상의 선불 요금제는 표준 3일 규칙을 따릅니다. 더 짧은 요금제는 그렇지 않습니다. Google 공식 문서는 "기간이 1주일보다 짧은 요금제는 요금제 기간의 절반 이내에 승인해야 한다"고 명시합니다. 3일짜리 선불 요금제라면 전체 기간이 아니라 하루 반나절만 주어집니다. 짧은 선불 충전 상품이 카탈로그에 포함되어 있다면, 승인 경로는 빠르고 서버 주도적이어야 하며, 고객이 앱을 다시 여는 것에 의존해서는 안 됩니다.
승인 호출이 대개 사라지는 지점
이 단계를 일부러 건너뛰는 사람은 없습니다. 승인 로직이 잘못된 트리거에 연결되어 있기 때문에 빠지는 것입니다. 흔한 안티패턴은 구매 플로우가 포그라운드로 돌아올 때만 승인하는 클라이언트입니다. 이는 구매를 마치고 곧바로 앱을 계속 사용하는 고객만 처리합니다. 그 외의 모든 사람은 처리되지 않습니다.
개발자들은 이 문제를 끊임없이 겪습니다. Google 자체 개발자 커뮤니티의 스레드들은 매번 같은 패턴을 반복합니다. 구매 후 3일 만에 사용자가 자동으로 환불받았다는 사례, 혹은 결제가 왜 3일째에 계속 스스로 취소되는지 알고 싶다는 호소입니다. 진단은 거의 변하지 않습니다. 승인 호출이 결코 일어나지 않은 사용자 행동에 연결되어 있었기 때문에 그저 한 번도 발생하지 않은 것입니다.
무료 체험판과 다시는 앱을 열지 않는 고객
가장 좋지 않은 경우는 무료 체험판이거나, 누군가 여러분의 앱을 마지막으로 닫기 직전 마지막 순간에 이루어진 구매입니다. 승인이 다음번 앱 실행을 기다리는데 그 다음번 앱 실행이 결코 오지 않으면, 구매는 그냥 기한을 넘겨 소멸합니다. Google은 3일째에 이를 환불하고 취소합니다. 전환될 예정이었던 체험판의 경우, 여러분은 결코 청구하지 못한 첫 결제를 잃고, 고객 권한도 그와 함께 조용히 사라집니다. 둘 다 지원 문의 대기열에는 나타나지 않습니다. 찾아보기만 한다면 둘 다 취소된 구매(voided purchase)로 나타납니다.
다음번 앱 실행에 의존하는 승인은, 고객이 3일 동안 돌아오지 않을 때마다 여러분이 잃는 판매입니다. 체험판과 원탭 구매야말로 고객이 돌아오지 않는 바로 그 순간입니다.
승인되지 않은 환불 뒤에 숨은 진짜 비용
환불 내역은 여러분이 실제로 잃은 것을 과소평가합니다. Google이 판매를 취소하고, 여러분은 가격을 돌려주며, 그것이 모두가 보는 숫자입니다. 하지만 그것이 전체 비용은 아닙니다.
누군가 구매하는 순간 실제 작업을 시작시키는 소모성 상품을 생각해 보세요. 일괄 이미지 생성, 모델 제공업체 API에 대한 일련의 호출, 비디오 내보내기, 크리에이터에게 지급해야 할 보수 등입니다. 여러분은 사용 시점에 그 컴퓨팅, API 호출, 스토리지, 지급액에 대해 이미 비용을 지불했습니다. 환불은 고객에게 판매 가격을 돌려줄 뿐, 여러분에게 제공업체 청구서를 돌려주지는 않습니다. 실제 비용은 이미 빠져나갔고 그에 대해 아무것도 돌아오지 않습니다.
구독과 체험판의 경우, 손실은 결코 받지 못한 첫 결제액과, 시작하기도 전에 끝난 고객 관계입니다. 그리고 이제 그 위험 부담은 더 커질 예정입니다. 2026년 8월 3일부터 Google Play는 그 날짜 이후에 이루어진 주문에 대해 지불거부(chargeback) 구매 가격과 은행 수수료를 개발자에게 전가합니다. 이는 피할 수 있는 누수라면 지금 당장 막아 두는 것을 가치 있게 만듭니다. 승인되지 않은 환불은 지불거부가 아니지만, 같은 교훈을 가르쳐 줍니다. 이미 지출한 돈이 자동으로 여러분의 것으로 남는 것은 아니라는 교훈입니다.
절대 놓칠 수 없도록 승인 단계 구축하기
믿을 수 있는 패턴은 앱을 완전히 핵심 경로에서 제외하는 것입니다. 누군가 화면을 다시 여는지가 아니라 알림에 의해 작동하도록, 백엔드에서 이를 실행하세요.
실시간 개발자 알림(real-time developer notifications)을 구독하세요. 1회성 상품 구매 이벤트나 구독 구매 이벤트는 앱이 실행 중인지 여부와 관계없이 Google이 판매를 등록하는 순간 서버에 도달합니다.
Play Developer API를 통해 구매 토큰을 검증하고 상태가 PENDING이 아니라 PURCHASED로 표시되는지 확인하세요.
해당 고객의 계정에 연결하여 권한을 여러분 자신의 시스템에 기록하세요.
지체 없이 소비 또는 승인 처리를 하세요. 소모성 상품은 소비 처리하고, 비소모성 상품과 최초 구독은 승인 처리합니다. 호출이 두 번 나가지 않도록 먼저 승인 상태를 확인하세요.
클라이언트 측 보완 장치도 유지하세요. onResume()에서 queryPurchasesAsync()를 호출하면 앱이 닫혀 있는 동안 처리된 모든 항목을 가져옵니다. 이는 주된 경로가 아니라 보험으로 취급하세요.
핵심은 승인이 여러분이 보장할 방법이 없는 사용자 행동이 아니라, Google이 건네주는 이벤트에 의해 발생한다는 점입니다. 한 번 구매하고 다시는 돌아오지 않는 사람도 여전히 완전히 처리됩니다. 구매가 성사되는 순간 여러분의 서버가 이미 그 작업을 끝냈기 때문입니다.
그래도 빠져나가는 것을 위한 최후의 안전망
파이프라인이 얼마나 잘 구축되었든, 그 아래에는 여전히 안전망이 필요합니다. Google의 Voided Purchases API는 환불, 취소, 또는 지불거부로 끝난 주문을 나열하며, 원인이 "개발자가 결코 승인하지 않아서 개발자의 기록에 존재하지 않을 수도 있는" 구매였던 특정 시나리오를 따로 표시합니다. 이를 주기적으로 조회하면 Google이 여러분 모르게 조용히 취소한 주문을 가진 사용자의 접근 권한을 제거할 수 있습니다. 다만 경계를 염두에 두세요. 가져올 수 있는 것은 최근 30일뿐이므로, 이는 분기마다 한 번씩 처리하는 일이 아니라 정기적으로 예약된 작업이어야 합니다.
iOS는 여러분에게 결코 이런 일을 벌이지 않습니다
App Store로 넘어가면 이 중 아무것도 적용되지 않습니다. Apple도 자체적인 마무리 단계인 트랜잭션 완료(finishing a transaction)를 만들었지만, 이를 건너뛸 때의 처벌은 정반대 방향으로 작동합니다. 완료되지 않은 트랜잭션은 Apple의 대기열에 그대로 남아 있습니다. 앱을 실행할 때마다, 그리고 observer가 연결될 때마다 다시 나타나서, 고객이 지불한 것을 전달할 기회를 반복해서 제공합니다. Apple은 이에 대해 어떤 취소 조치도 내리지 않습니다. 72시간 환불 트리거와 비슷한 것조차 그 플랫폼에는 존재하지 않습니다.
바로 그래서 하나의 사고방식을 두 스토어 모두에 똑같이 적용할 수 없는 것입니다. Android는 카운트다운과, 이를 놓치면 사라지는 판매를 건네줍니다. iOS는 지속적인 알림과 이에 응답할 무제한의 시간을 건네줍니다. iOS의 습관을 Android 코드베이스에 들여오면, 결국 팀의 누구도 설명할 수 없는 취소된 주문의 더미를 마주하게 됩니다.
그 간극을 메우는 것이 바로 Refund Sensor가 하는 일입니다. 확인은 스토어 알림이 도착하는 순간 바로 뒤이어 발생하며, 동시에 Voided Purchases API를 대상으로 한 상시 대조 작업이 Google이 여러분 모르게 이미 취소한 주문에 대해 접근 권한을 회수합니다. 놓칠 수도 있었던 카운트다운이, 확인할 생각을 하기도 전에 이미 체크된 항목이 됩니다.
이 규칙들이 문서화된 곳
자주 묻는 질문
서버가 제시간에 승인 호출을 보내지 않았기 때문입니다. 구매가 PURCHASED 상태에 도달한 후 3일이 지나도 승인되지 않으면, Google은 판매를 취소하고 권한을 자동으로 회수합니다. 이는 고객이 한 일도 아니고 Google이 부과한 처벌도 아닙니다. 승인 호출이 누락된 것이며, 스토어 알림을 받아 서버 측에서 승인하면 이 문제를 완전히 없앨 수 있습니다.
둘 다 3일 타이머를 멈추지만, 상품을 서로 다른 상태로 남겨둡니다. purchases.products.consume이나 consumeAsync()를 통한 소비 처리는 소모성 상품을 위한 것입니다. 이는 기한을 해결하고 해당 항목을 다시 판매 가능한 상태로 되돌립니다. purchases.products.acknowledge, purchases.subscriptions.acknowledge, 또는 acknowledgePurchase()를 통한 승인 처리는 비소모성 상품과 구독을 위한 것입니다. 이는 상품을 재구매 가능하게 만들지 않으면서 권한을 확인합니다.
아닙니다. 최초 구매만 승인하면 됩니다. Google은 갱신에 대해 승인을 요구하지 않으며 자동으로 승인됨으로 표시합니다. 승인 대기 상태로 도착해서 여러분이 해결하기 전까지 여러분의 책임으로 남는 것은 구독의 최초 구매뿐입니다.
아니요, PURCHASED 상태가 될 때까지 기다리세요. 현금 결제나 부모 승인 요청 같은 PENDING 상태의 구매는 3일 타이머가 아직 전혀 시작되지 않은 상태입니다. 상태가 실제로 PENDING에서 PURCHASED로 바뀐 후에만 권한을 부여하고 승인을 보내세요.
아니요, 그리고 Android와 iOS가 같은 방식으로 작동한다고 가정하기 전에 알아둘 가치가 있습니다. 완료되지 않은 StoreKit 트랜잭션은 완료할 때까지 앱을 실행할 때마다 그냥 다시 전달될 뿐입니다. Apple은 이를 결코 자동으로 환불하지 않습니다. 3일 자동 환불은 Google Play에만 있는 특유의 방식이므로, 두 플랫폼은 서로 다른 처리가 필요합니다.
환불 자체는 되돌릴 수 없습니다. 할 수 있는 것은 대조(reconcile) 작업입니다. Voided Purchases API는 지난 30일 동안 환불되거나 취소된 구매를 보여주며, 승인되지 않아서 취소된 경우를 특별히 표시해 주므로, 여러분이 부여했던 권한을 회수할 수 있습니다. 앞으로는 스토어 알림을 받아 승인하는 것이 다음번 구매가 빠져나가지 않도록 막아줍니다.



