---
title: "Android 인앱 구매, 4부: 결제 라이브러리 오류 코드 및 테스트를 망치지 않는 방법"
description: "이 사용 지침서에서는 Google Play 결제 라이브러리의 인앱 구매 관련 오류를 자세히 살펴보고 오류의 원인을 확인합니다"
url: "https://adapty.io/ko/blog/android-in-app-purchases-part-4-billing-library-error-codes-and-how-not-to-fail-testing/"
language: "ko"
slug: "android-in-app-purchases-part-4-billing-library-error-codes-and-how-not-to-fail-testing"
category: "adapty-updates"
date: "2021-09-29T00:00:00.000Z"
date_modified: "2021-09-29T00:00:00.000Z"
author: "Vlad Guriev"
---

# Android 인앱 구매, 4부: 결제 라이브러리 오류 코드 및 테스트를 망치지 않는 방법

오늘우리는[getResponseCode()](https://developer.android.com/reference/com/android/billingclient/api/BillingResult#getResponseCode%28))메소드에서결제 라이브러리를 통해 볼 수 있는[오류 코드](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode)에대해 알아보겠습니다.

콜백에오류를 전달한 방법의 예는[이 기사](https://adapty.io/blog/android-in-app-purchases-google-play-billing-library-part-2/)에서찾을 수 있습니다.우리는이미 이전 기사에서 사용자가 아무것도 구매하지 않고구매 대화 상자를 닫을 때 발생하는 오류 중 하나인[**USER_CANCELED**](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#USER_CANCELED)를살펴보았습니다.다른오류들을 알아 봅시다.

## ERROR와DEVELOPER_ERROR

처음살펴볼 오류는[**ERROR**](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ERROR)(responseCode 6)와[**DEVELOPER_ERROR**](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#DEVELOPER_ERROR)(responseCode 5)입니다.첫번째의 경우,Google은"Fatalerror during the API action” 문서를기록하고 두 번째의 경우 "Invalidarguments provided to the API”를기록합니다.예를들어,[querySkuDetailsAsync()](https://developer.android.com/reference/com/android/billingclient/api/SkuDetailsParams.Builder#setType%28java.lang.String))요청을위해[setType()](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#querySkuDetailsAsync%28com.android.billingclient.api.SkuDetailsParams,%20com.android.billingclient.api.SkuDetailsResponseListener))으로빈 문자열을 빌더에 전달했을 때 DEVELOPER_ERROR를얻을 수 있었습니다.

하지만그렇게 간단한 것은 아닙니다.계속진행하면서 [launchBillingFlow()](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#launchBillingFlow%28android.app.Activity,%20com.android.billingclient.api.BillingFlowParams))메소드에서수정된[SkuDetails](https://developer.android.com/reference/com/android/billingclient/api/SkuDetails)를사용했습니다.(실제제품의 SkuDetails에서json(json)을가져와서 productID를변경하고 새 SkuDetails제작자에게전달했습니다)사실,이것은근거 없는 주장이고,나는**DEVELOPER_ERROR** 를얻을 거라고 예상했지만 ...**ERROR** 를얻었습니다.

물론이것은 인위적인 예였습니다.구글이결제를 거부한 경우가 훨씬 현실적인 사례입니다.기사끝부분에서 알려드리겠지만,테스트카드로 구매를 테스트할 때 구매 대화 상자에서 "testcard, always declined”를선택하면 적절한 텍스트와 함께 **ERROR** 역시반환됩니다.

구독(subscription)변경을설명한[세 번째 기사](https://adapty.io/blog/android-in-app-purchases-part-3-retrieving-active-purchases-and-subscription-change/)에서,우리는비례 배분 방식 중 하나에 대해 연간 구독 가격을 거의3배나인상했는데,그렇게하지 않은 경우 발생했어야 하는 실수가 무엇인지에대해서는 말하지 않았습니다.개정중입니다.

잘못된비례 배분 모드가 지정된 것으로 밝혀졌기 때문에,논리적으로동일한 **DEVELOPER_ERROR** 을가져와야 합니다.그대신, [**SERVICE_UNAVAILABLE**](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#SERVICE_UNAVAILABLE)(responseCode 2)를얻었습니다.또한비례 배분 모드로 부적절한 숫자를 입력하고 (이것은enum이아니라 int입니다.아무도우리를 막을 수 없죠.)잘못된purchaseToken을지정하는 경우에도 이를 얻습니다.**SERVICE_UNAVAILABLE** 에대한 문서를 살펴보면 ...잠깐,이게뭐죠?!"Network connection is down."이표시됩니다.

동시에이상한 대화 상자도 표시됩니다.

![](https://adapty.io/wp-content/uploads/2023/03/615371cbae3a194fdd67617c_5n7uqaw9bx5dejwxgqh9sluv3r38yqwegbzbnzj5db9bullr12o2uraffoyko2jn4pjwhsy04xwdwrwxt37pkvgt3q1zgtblivzbagg-91v1ogagpaptqj-av1kdmoqhe96kwy4x3ds0-4.jpg)

**ERROR** 의경우 또 한 가지 흥미로운 것은 "확인"버튼을누르지 (즉,"뒤로가기"로해석되는 수단을 통하지)**않고** 대화 상자를 닫으면 **ERROR** 가[onPurchasesUpdated()](https://developer.android.com/reference/com/android/billingclient/api/PurchasesUpdatedListener#onPurchasesUpdated%28com.android.billingclient.api.BillingResult,%20java.util.List%3Ccom.android.billingclient.api.Purchase%3E))에발생하고,**SERVICE_UNAVAILABLE** 의경우 비슷한 상황에서 **USER_CANCELED** 가나타납니다.(그러나대화 상자에서 "OK"를클릭하면 예상할 수 있듯이 **SERVICE_UNAVAILABLE** 를받게 됩니다)

그리고인터넷 연결이 끊긴 경우에는 **SERVICE_UNAVAILABLE** 가실제로 나옵니다.

## 오류코드

다음은작은 주석이 달린 오류 코드들로,선외가작이라고 할만한 것들입니다.

- [BILLING_UNAVAILABLE](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#BILLING_UNAVAILABLE) (responseCode 3). Google은 "요청한 유형에 대해 Billing API 버전이 지원되지 않습니다"라고 설명합니다. Google 계정에서 로그아웃했을 때와 Google Play 서비스가 없는 Huawei 기기를 사용할 때 이 오류를 재현할 수 있었습니다. Google Play가 업데이트되지 않은 구형 휴대폰에서도 재현할 수 있습니다.
- [SERVICE_DISCONNECTED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#SERVICE_DISCONNECTED) (responseCode -1). 애플리케이션이 Google Play 서비스에서 연결이 끊기는 경우가 간혹 있습니다. Play Store가 예기치 않게 업데이트되는 경우 발생할 수 있습니다. 따라서 이전 기사에서와 같이, 안전하게 결제 라이브러리 메소드 호출 전에 연결하도록 권해드립니다. 또한 이 오류가 계속 응답하면 재시도 방책을 추가하도록[Google](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#SERVICE_DISCONNECTED)과 우리가 공통적으로 조언하고 있습니다.
- [SERVICE_TIMEOUT](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#SERVICE_TIMEOUT) (responseCode -3). 이름에서 알 수 있는 것처럼, Google Play의 응답을 너무 오랫동안 기다렸습니다.
- [FEATURE NOT SUPPORTED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#FEATURE_NOT_SUPPORTED). BillingClient 클래스에는 5가지[FeatureType](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.FeatureType) 상수가 있습니다. 이 기기에서의 가용성은 [BillingClient.isFeatureSupported(BillingClient.FeatureType.A_NECESSARY_FEATURE)](https://developer.android.com/reference/com/android/billingclient/api/BillingClient#isFeatureSupported%28java.lang.String)) 메소드를 사용해서 확인할 수 있습니다. 제 폰(Xiaomi Mi A2 Lite)에서는 **FEATURE_NOT_SUPPORTED** 가 **SUBSCRIPTIONS_ON_VR** 에 대해서만 반환되었습니다. 동시에 다른 모든 기능은 물론이고 **IN_APP_ITEMS_ON_VR** 에 대해서는 OK가 반환되었습니다.
- [ITEM_NOT_OWNED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_NOT_OWNED) (responseCode 8). 우리가 가지고 있지 않은 구매를 소비하려고 할 때 발생합니다. 어쩌면 성공적인 소비 후에도 반복적으로 나타날 수 있습니다.
- [ITEM_ALREADY_OWNED](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_ALREADY_OWNED) (responseCode 7). 그와는 반대로, 이미 가지고 있는 제품을 구매하려고 하다가 발생하는 오류입니다. 이 경우, UI를 업데이트하고 구매 버튼을 클릭할 수 없도록 하기만 하면 됩니다.

## ITEM_UNAVAILABLE

마지막으로인앱 구매 구현 경로의 출발점에서 분명 가장 많이발생하는 오류는 [**ITEM_UNAVAILABLE**](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.BillingResponseCode#ITEM_UNAVAILABLE)(responseCode 4)입니다.제품을구매할 수 없다고 나와 있지만,이유는설명하지 않습니다.이유는매우 다양할 수 있습니다.잘못된계정이나 기기에서 테스트하는 것부터 비활성 제품을구매하는 것까지입니다.

다음은테스트 중 이 오류를 방지하기 위해 확인해야 하는체크리스트입니다.

1. 결제라이브러리와 함께 앱을 테스트 트랙으로 보냅니다.이것은필수 조건입니다.동시에동일한 applicationId를사용하여 디버그 빌드에서 테스트할 수도 있지만,결제라이브러리와 함께 앱을 PlayConsole에최소 한 번은 업로드하는 것이 중요합니다.
2. 테스터의Google계정을이 테스트 트랙에 추가하는데,이는내부 테스트 또는 비공개 알파/베타에서특히 중요합니다.또한*테스터가테스트에 참여하는 방법* 섹션에 링크가 있는데,여기서테스터가 초대를 수락해야 합니다.
3. 활성화된제품만 구매할 수 있습니다.제품생성 후,Play Console에***activate***버튼이있습니다.제품생성 과정은 [첫 번째 기사](https://adapty.io/blog/android-in-app-subscriptions/)에서더 자세히 설명했습니다.
4. 기기상에서의 테스트가 테스터의 Google계정에서수행되는지 확인합니다 (즉,해당계정은 이 테스트 트랙에 테스터로 등록되어야 하고필요한 모든 기술 액세스 권한을 가져야 합니다).이점은 당연해 보이지만 문제는 생기기 마련이라,이런에러가 발생한다면 이 부분을 확인할 필요가 있습니다.
5. 구매테스트에 사용되는 빌드의 applicationId는PlayConsole의applicationId와완전히 일치해야 합니다.이것은디버그 빌드에 확장자를 추가한 사람들에게 특히중요합니다.
6. (애플리케이션이아니라)계정의왼쪽 메뉴에서 *Setup→ License Testing* 섹션에테스터의 이메일 주소를 추가하여,실제카드가 아닌 테스트 카드에서 무료로 제품을 구매합니다.또다른 이점은,이경우 구독에[테스트 기간](https://developer.android.com/google/play/billing/test#renewals)이있다는 것입니다.이오류와 관련이 없지만 유용한 지식입니다.

## 결론

오류는작업을 매우 복잡하게 만들 수 있으므로,오류가어떻게 발생할 수 있는지 이해하는 것이 항상 중요합니다.제품에액세스하기 위해 얼마나 많은 단계를 거쳐야 하는지생각해보면,가장쉬운 방법은 ITEM_UNAVAILABLE을잡는 것입니다.따라서,제체크리스트가 도움이 되기를 바랍니다.

[TheAdapty SDK](https://adapty.io/sdk/android/)는오류 처리를 용이하게 하고 많은 이점을 제공하는데,그중에는 기본 구독 분석,코호트분석 (cohortanalysis), 페이월(paywall)의간단한 테스트,분석서비스와의 통합 (integration),서버오류 검증 등이 있습니다.지금해보세요!
