보류 중인 구매는 판매처럼 보이지만 돈은 아직 도착하지 않았고, 미리 지급하면 제품을 공짜로 내주는 셈이다
App Store와 Google Play 모두 보류 중인 구매 상태를 가지고 있습니다. 스토어가 접수했지만 아직 청구하지 않은 주문을 말합니다. 결제가 확정되기 전에 잠금을 해제하면, 무산되는 주문 하나하나가 그대로 비용이 됩니다. 이 글에서는 보류 중인 구매가 각 스토어에서 어떻게 작동하는지, 잘못 지급하면 무엇을 치르는지, 그리고 손실 없이 처리하는 방법을 설명합니다.

핵심 요약
- 보류 중인 구매는 스토어가 접수했지만 아직 청구하지 않은 실제 주문입니다. 코드는 새 구매를 보지만 돈은 아직 도착하지 않았고, 영영 도착하지 않을 수도 있습니다.
- Google Play에서는 상태가 PURCHASED일 때, Apple에서는 트랜잭션이 완료되었을 때에만 권한을 지급하세요. PENDING 상태나 Apple의 보류 결과에서는 절대 잠금을 해제하지 마세요.
- Google Play에서는 매장 현금 결제, 계좌 이체, 일부 통신사 청구가 대역 외에서 정산되므로, 고객이 실제로 지불하기 전까지 구매는 PURCHASED가 아니라 PENDING으로 돌아옵니다.
- Apple에서 보류 중인 구매는 대개 Ask to Buy로, 가족 관리자가 승인해야 합니다. 승인에는 몇 시간에서 며칠이 걸릴 수 있으며, 완료된 트랜잭션은 나중에 Transaction.updates를 통해 도착합니다.
- 이후 취소되는 보류 주문에서 잠금을 해제하면, 확정되지 않은 청구를 위해 연산 자원, API 호출, 스토리지, 또는 소모성 아이템의 실제 지급을 써 버린 것이 됩니다. 환불과 달리 되찾을 돈이 없습니다. 애초에 한 번도 수금된 적이 없기 때문입니다.
- 보류 주문이 무산되면 스토어가 알려 줍니다. Google은 ONE_TIME_PRODUCT_CANCELED, 유형 2, 또는 SUBSCRIPTION_PENDING_PURCHASE_CANCELED, 유형 20을 보냅니다. Apple은 그저 완료된 트랜잭션을 전달하지 않습니다.
- 보류 주문은 앱이 닫혀 있는 동안 실제 판매로 바뀔 수 있으므로, 돌아왔을 때 다시 확인하세요. Google Play에서는 onResume()에서 queryPurchasesAsync()를 호출하고, Apple에서는 Transaction.updates를 계속 수신하세요.
누군가 당신의 앱에서 구매를 누릅니다. 로그에는 새 주문이 표시되고, 결제 리스너가 발동하며, 당신은 상품을 건넵니다. 대부분의 구매에서는 그것이 정확히 맞습니다. 하지만 보류 중인 구매에서는 실수입니다. 주문은 존재하지만 돈은 존재하지 않기 때문입니다. 고객은 나중에 정산되는 결제 수단을 골랐고, 스토어는 아직 입금을 기다리고 있으며, 당신은 결코 확정되지 않을지도 모르는 청구를 위해 유료 기능을 건네 버린 것입니다. 이것은 환불의 조용한 사촌입니다. 여기서는 아무것도 되돌려지지 않습니다. 애초에 아무것도 수금되지 않았기 때문입니다. 당신은 그저 제품을 공짜로 내준 것입니다.
보류 중인 구매는 아직 지불되지 않은 상태의 실제 주문이며, App Store와 Google Play 모두 이 상태를 가지고 있습니다. 두 스토어 모두 기다리라고 분명히 말합니다. 함정은 보류 주문이 코드상으로는 완료된 주문과 거의 똑같아 보인다는 점입니다. 그래서 모든 새 구매를 판매로 취급하는 통합은 스토어가 아직 수금하려 하고 있는 주문에서 상품을 내보냅니다. 제대로 처리하면 아무것도 잃지 않습니다. 잘못 처리하면 무산되는 모든 느린 결제가 당신의 부담으로 전달되는 순수한 비용이 됩니다.
보류 중인 구매란 실제로 무엇인가
보류 중인 구매는 스토어가 기록했지만 아직 청구하지 않은 주문입니다. 구매자는 흐름을 시작했고, 스토어는 그것을 접수했으며, 정산은 당신의 앱이 볼 수 없는 어딘가에서 진행되고 있습니다. Google Play는 이것을 PENDING 상태라고 부릅니다. Apple은 이를 보류 중인 트랜잭션, 또는 지연된 트랜잭션이라고 부릅니다. 이름은 다르지만 사실은 같습니다. 스토어는 입금을 기다리는 동안 주문을 열어 둔 채 유지하고 있으며, 그 주문을 돈으로 취급하지 말라고 당신에게 말했습니다.
Google Play: 결제는 다른 곳에서 일어나고 있다
일부 결제 수단은 대역 외에서 정산됩니다. 실제 매장의 현금, 계좌 이체, 일부 통신사 청구는 모두 누름과 청구 사이에 추가 단계를 거칩니다. 고객이 그중 하나를 고르면, Google은 구매를 PURCHASED가 아니라 PENDING 상태로 반환합니다. 현금 결제의 경우, 고객은 알림과 이메일로 코드를 받아, 그것을 참여 매장으로 가지고 가서, 계산원에게 지불합니다. 그 일이 일어나기 전까지 Google은 아무것도 수금하지 않았고, 당신도 마찬가지입니다. Google의 규칙은 한 줄입니다. getPurchaseState()를 사용하고, 상태가 PURCHASED일 때에만 권한을 지급하라는 것입니다. 또한 PENDING인 동안에는 구매를 확인 응답하지 말라고도 말합니다. 확인 응답은 지불된 주문에 속하는 것이지, 약속된 주문의 것이 아니기 때문입니다.
Apple: 이 구매는 다른 누군가의 누름을 기다리고 있다
Apple의 보류 상태는 트랜잭션이 완료되기 전에 외부 동작이 필요함을 뜻합니다. 가장 흔한 것은 Ask to Buy로, 아이가 구매를 시작하고 가족 관리자가 그것을 승인해야 합니다. StoreKit 2에서는 구매 호출이 Product.PurchaseResult.pending을 반환합니다. 더 오래된 StoreKit에서는 트랜잭션이 deferred로 보고됩니다. 어느 쪽이든 Apple은 누구에게도 청구하지 않았으며, 완료된 트랜잭션은, 만약 온다면, Transaction.updates를 통해 비동기로 도착합니다. 고객에게 대기 상태를 보여 주고, 완료된 트랜잭션이 도착할 때까지 아무것도 잠금 해제하지 마세요.
보류 중인 구매를 지급하면 왜 실제로 돈을 잃는가
여기서의 손실은 계상해 둔 돈이 도로 회수되는 환불 종류가 아닙니다. 한 가지 특정한 면에서 더 나쁩니다. 도로 회수할 돈이 없습니다. 애초에 한 번도 수금되지 않았기 때문입니다.
당신은 전달하지만, 스토어는 결코 수금하지 않는다
이후 취소되는 보류 주문에서 잠금을 해제하면, 당신은 이미 그것을 제공하느라 지출한 것입니다. 기능을 돌린 연산 자원, 당신이 요금을 낸 서드파티 API 호출, 당신이 할당한 스토리지, 그리고 소모성 아이템이라면 당신이 판 것의 실제 지급입니다. 그 모든 것이 수익을 내지 못한 주문을 위해 밖으로 나갑니다. 환불은 적어도 실제로 발생한 청구에서 시작합니다. 잘못 지급된 보류 중인 구매에는 애초에 청구가 전혀 없었으므로, 나가는 돈으로조차 표시되지 않습니다. 그것은 아무것도 표시되지 않습니다. 바로 그래서 놓치기 쉽고 되풀이하기 쉬운 것입니다.
취소 신호와 그 의미
보류 주문이 사라질 때 스토어는 분명히 그것을 알려 줍니다. Google Play에서는 무산된 일회성 상품이 ONE_TIME_PRODUCT_CANCELED 알림, 유형 2를 보내고, 보류 중이던 구독은 SUBSCRIPTION_PENDING_PURCHASE_CANCELED, 유형 20을 보냅니다. 같은 주문이 반대로 성사되면, ONE_TIME_PRODUCT_PURCHASED, 유형 1, 또는 SUBSCRIPTION_PURCHASED, 유형 4를 받습니다. Apple에는 잡아낼 취소 이벤트가 없습니다. 거절된 지연 트랜잭션은 그저 완료된 트랜잭션이 되지 않기 때문입니다. 일찍 잠금을 해제했다면, 그 침묵이 청구서입니다.
| 질문 | Google Play | Apple |
|---|---|---|
| 무엇이 유발하는가 | 현금, 계좌 이체, 일부 통신사 청구 | Ask to Buy 승인, 또는 그 밖의 필요한 동작 |
| 보이는 상태 | PurchaseState PENDING | 보류 결과, 또는 지연된 트랜잭션 |
| 언제 권한을 지급하는가 | 상태가 PURCHASED | 트랜잭션이 완료 |
| 성사된 경우 | ONE_TIME_PRODUCT_PURCHASED (1), SUBSCRIPTION_PURCHASED (4) | Transaction.updates를 통한 완료된 트랜잭션 |
| 무산된 경우 | ONE_TIME_PRODUCT_CANCELED (2), SUBSCRIPTION_PENDING_PURCHASE_CANCELED (20) | 완료된 트랜잭션이 결코 도착하지 않음 |
| 돈이 수금되었는가 | 아니요, PURCHASED가 되기 전까지는 | 아니요, 트랜잭션이 완료되기 전까지는 |
그 대기 시간, 그리고 누가 누구를 기다리는가
보류 중인 구매는 당신이 경주하고 있는 시계가 아닙니다. 당신 쪽에서 보면, 아직 움직이기 시작하지 않은 시계입니다.
Google Play는 고객에게 분이 아니라 며칠을 준다
현금 또는 계좌 이체 결제는 당신이 아니라 고객의 일정에 따라 정산됩니다. 주문은 고객이 지불하거나, 기한이 다 되어 Google이 취소할 때까지 PENDING에 머뭅니다. 확인 응답하지 않은 구매를 자동으로 환불하는 당신 자신의 3일 확인 응답 기한은, 구매가 PENDING에서 PURCHASED로 전환되기 전까지는 시작조차 하지 않습니다. 그러니 보류 주문을 제공하려고 서두를 이유는 없습니다. 있는 것은 오직 상태가 바뀌기를 기다리는 절제뿐입니다.
Apple의 승인은 가족 관리자의 전화기 안에 있다
Ask to Buy 요청은 관리자의 기기에 프롬프트로 도착하며, 그들은 여유가 생겼을 때 승인하거나 거절합니다. 그것은 몇 분 뒤일 수도, 몇 시간 뒤일 수도, 하루 뒤일 수도 있으며, 당신의 앱은 그것을 재촉할 수 없습니다. 유일하게 올바른 행동은 대기 상태를 반영하고, 승인이 온다면 그때 StoreKit이 완료된 트랜잭션을 건네주도록 맡기는 것입니다.

손실 없이 보류 중인 구매를 처리하는 방법
전체 작업은 네 가지 습관으로 귀결됩니다. 그 어느 것도 어렵지 않으며, 그중 하나라도 건너뛰면 바로 그곳이 돈이 새는 지점입니다.
지불된 상태에서 지급하고, 보류 상태에서는 결코 지급하지 않는다
Google Play에서는 getPurchaseState()를 확인하고 PURCHASED일 때에만 지급하며, PENDING인 동안에는 구매를 확인 응답하지 마세요. Apple에서는 완료된 트랜잭션에서만 잠금을 해제하고 보류 결과에서는 결코 하지 마세요. 이 한 가지 규칙이 누수 전체를 막습니다. 나머지는 전부, 지불된 상태가 도착할 때 당신이 실제로 알아차리도록 만드는 일입니다.
앱이 돌아오면 다시 확인한다
보류에서 지불로의 전환은 당신의 앱이 실행되고 있지 않을 때 일어나는 경우가 많습니다. Google Play에서는 onResume() 핸들러에서 queryPurchasesAsync()를 호출해 백그라운드에서 PURCHASED가 된 주문을 집어내고, Real-time Developer Notifications 리스너를 서버 측의 신뢰할 수 있는 원천으로 유지하세요. Apple에서는 승인된 트랜잭션이 원래 구매 호출이 반환된 뒤 한참 지나서 도착할 수 있으므로, 앱의 전체 수명 동안 Transaction.updates를 수신하세요.
보류 지원을 활성화하고 양쪽 결말을 테스트한다
Google은 BillingClient를 만들 때 enablePendingPurchases()를 호출하도록 요구하며, 일회성 상품에 대해 보류 트랜잭션을 지원하는 것은 선택이 아니라 필수입니다. 출시하기 전에 테스트하세요. 라이선스 테스터는 지연 형태의 결제를 위한 두 가지 추가 테스트 수단을 받는데, 여기서는 결제가 몇 분 뒤 자동으로 완료되거나 자동으로 취소되므로, 지불 경로와 무산 경로를 처음부터 끝까지 지켜볼 수 있습니다.
주문이 아직 끝나지 않았음을 고객에게 알린다
보류 중인 구매자는 구매 도중에 있는 실제 고객이지 실패가 아닙니다. 주문이 그들의 결제나 승인을 기다리고 있음을 보여 주고, 그것을 끝내러 돌아올 수 있는 명확한 길을 주세요. 침묵하는 보류 상태는 제대로 표시하면 되찾을 수 있는 판매를 잃습니다. 이런 구매자 대부분은 여전히 그것을 원하며 단지 한 단계만 남아 있기 때문입니다.
RefundHalt가 환불과 지불 거절을 위해 이미 읽고 있는 그 동일한 Real-time Developer Notifications와 App Store Server Notifications 피드는 이 신호들도 실어 나릅니다. 보류 주문이 마침내 확정되었다고 알리는 구매 알림과, 그렇지 않다고 알리는 취소 알림은, 당신의 대시보드에서 나머지 수익 이벤트 옆에 도착합니다. 그래서 무산된 보류 주문은 당신이 실수로 값을 치른 것이 아니라 눈으로 볼 수 있는 것이 됩니다.
요약하면
보류 중인 구매는 결제가 없는 주문이며, 두 스토어 모두 당신이 기다려야 한다고 분명히 말합니다. Google Play는 현금, 계좌 이체, 일부 통신사 청구 주문을 PENDING 상태로 반환하고 PURCHASED일 때에만 권한을 지급하라고 말합니다. Apple은 Ask to Buy와 그 밖의 필요한 동작에 대해 보류 또는 지연된 트랜잭션을 반환하고, 완료된 트랜잭션을 나중에 Transaction.updates를 통해 전달합니다. 지불된 상태에서 잠금을 해제하고, 앱이 재개되면 다시 확인하고, 보류 지원을 활성화하고 테스트하며, 대기 중인 주문을 고객을 위해 표시하세요. 그렇게 하면 보류 중인 구매는 아무 비용도 들지 않습니다. 그것을 건너뛰면 결코 오지 않은 청구를 위해 유료 제품을 전달하게 되는데, 그것은 가리킬 영수증이 없는 유일한 손실입니다.
자주 묻는 질문
- 보류 중인 구매란 무엇인가요?
- 보류 중인 구매는 스토어가 접수했지만 아직 청구하지 않은 주문입니다. Google Play에서는 PENDING 구매 상태로, 현금, 계좌 이체, 일부 통신사 청구처럼 나중에 정산되는 결제 수단에 쓰입니다. Apple에서는 보류 또는 지연된 트랜잭션으로, 가장 흔한 것은 가족 관리자의 승인을 기다리는 Ask to Buy 구매입니다. 두 경우 모두 아직 돈이 수금되지 않았으므로 접근 권한을 지급해서는 안 됩니다.
- 구매가 보류 중인 동안 접근 권한을 지급해야 하나요?
- 아니요. Google Play에서는 상태가 PURCHASED일 때, Apple에서는 트랜잭션이 완료되었을 때에만 권한을 지급하세요. 주문이 아직 보류 중인데 기능의 잠금을 해제했고 결제가 끝내 확정되지 않으면, 당신은 제품을 무료로 전달한 것이며, 되돌릴 청구도 없습니다. 애초에 한 번도 이루어지지 않았기 때문입니다.
- Google Play에서 어떤 결제 수단이 보류 중인 구매를 일으키나요?
- 대역 외에서 정산되는 결제 수단입니다. 실제 매장의 현금 결제, 계좌 이체, 일부 통신사 청구 옵션은 누름과 청구 사이에 추가 단계를 필요로 하므로, Google은 구매를 PURCHASED가 아니라 PENDING 상태로 반환합니다. 현금 결제의 경우 고객은 알림과 이메일로 코드를 받은 뒤 참여 매장에서 지불합니다.
- Ask to Buy란 무엇이며, 보류 중인 구매와 어떤 관련이 있나요?
- Ask to Buy는 아이가 가족 관리자가 승인해야 하는 구매를 요청할 수 있게 해 주는 Apple의 Family Sharing 기능입니다. 요청이 대기하는 동안 구매는 Apple의 보류 상태에 있으며, StoreKit 2에서는 Product.PurchaseResult.pending으로, 더 오래된 StoreKit에서는 지연된 트랜잭션으로 반환됩니다. 완료된 트랜잭션은 관리자가 승인할 때에만 Transaction.updates를 통해 도착합니다.
- 보류 중인 구매가 끝내 지불되지 않으면 어떻게 되나요?
- 주문은 취소되고 돈은 오가지 않습니다. Google Play에서는 일회성 상품에 대해 ONE_TIME_PRODUCT_CANCELED 알림, 유형 2를, 구독에 대해 SUBSCRIPTION_PENDING_PURCHASE_CANCELED, 유형 20을 받습니다. Apple에서는 지연된 트랜잭션이 그저 완료된 트랜잭션이 되지 않습니다. 이미 접근 권한을 지급했다면, 바로 그 순간 손실이 현실이 됩니다.
- 보류 중인 구매는 환불과 같은 것인가요?
- 아니요. 환불은 실제로 수금된 결제를 되돌립니다. 무산된 보류 중인 구매는 애초에 한 번도 청구되지 않았으므로, 되돌릴 것도 없고 환불 보고서에도 아무것도 나타나지 않습니다. 일찍 잠금을 해제했다면, 그 비용은 수익을 내지 못한 주문을 제공하느라 쓴 연산 자원, API 호출, 스토리지, 또는 소모성 아이템입니다.
출처 및 추가 자료
- Android Developers: Integrate the Google Play Billing Library (PENDING purchase state, grant entitlement only on PURCHASED, enablePendingPurchases, queryPurchasesAsync, cash payment code flow, three-day acknowledgement window begins on transition to PURCHASED)
- Android Developers: Real-time developer notifications reference (OneTimeProductNotification ONE_TIME_PRODUCT_PURCHASED=1 and ONE_TIME_PRODUCT_CANCELED=2; SubscriptionNotification SUBSCRIPTION_PURCHASED=4 and SUBSCRIPTION_PENDING_PURCHASE_CANCELED=20)
- Android Developers: Test Google Play Billing (license testers get delayed-payment test instruments that auto-complete or auto-cancel for testing pending transactions)
- Apple Developer: Product.PurchaseResult (the pending case, returned when a purchase needs action such as Ask to Buy approval before it completes)
- Apple Developer: SKPaymentTransactionState.deferred (a transaction whose final status is pending an external action such as Ask to Buy)
- Apple Developer: Transaction.updates (StoreKit delivers transaction updates, including ones approved later, asynchronously)
RefundHalt
App Store와 Google Play 환불 자동 처리
계속 읽기
고객이 해지하는 것보다 갱신 실패가 더 자주 일어나며, 그 비자발적 이탈은 아직 되찾을 수 있는 수익입니다
많은 구독을 끝내는 것은 해지 탭이 아니라 거절된 카드이며, 스토어는 몇 주 동안 계속 결제를 시도합니다. App Store와 Google Play에서 결제 유예 기간, 결제 재시도, 계정 보류가 어떻게 작동하는지, 그리고 비자발적 이탈이 실제로 당신에게 얼마의 비용을 치르게 하는지 설명합니다.
아이가 저지른 무단 인앱 결제는 거의 매번 부모에게 환불되고, 그 비용은 개발자가 떠안습니다
아이가 부모의 휴대폰에서 코인 팩을 구매하면 Apple과 Google 모두 그것을 환불하며, 어느 쪽도 먼저 개발자에게 묻지 않습니다. 규제 당국이 그렇게 만들도록 했기 때문입니다. 이러한 무단 인앱 결제 환불이 각 스토어에서 어떻게 처리되는지, 돈이 오가는 15분의 창, 그리고 실제로 얼마의 손실이 되는지 설명합니다.