Save the date! Android Dev Summit is coming to Sunnyvale, CA on Oct 23-24, 2019.

In-app Billing API

In-app Billing Version 3 API를 사용하면 인앱 결제를 애플리케이션에 더 쉽게 통합할 수 있습니다. 이 버전의 특징으로는 동기식 구매 흐름, 소비성 상품의 소유권을 쉽게 추적할 수 있게 해주는 API, 인앱 구매 데이터의 로컬 캐싱 등이 포함됩니다.

상품 유형

Google Play Developer Console을 사용하여 상품 유형, SKU, 가격, 상품 설명을 포함하여 상품을 정의합니다. 자세한 내용은 인앱 결제 관리를 참조하세요. Version 3 API는 관리되는 인앱 상품과 구독을 지원합니다.

관리되는 인앱 상품

관리되는 인앱 상품은 Google Play가 소유권 정보를 추적하고 관리하는 아이템입니다. 사용자가 관리되는 인앱 아이템을 구매하면 Google Play가 각 사용자별로 각 아이템에 대한 구매 정보를 저장합니다. 따라서 다음에 언제든 Google Play에 쿼리하여 특정 사용자가 구매한 아이템의 상태를 복원할 수 있습니다. 사용자가 애플리케이션을 제거하거나 기기를 바꾸더라도 이 정보는 Google Play 서버에 영구 저장됩니다.

Version 3 API를 사용 중이라면 애플리케이션 내에서 관리되는 아이템을 소비할 수도 있습니다. 보통은 여러 번 구매할 수 있는 아이템(예: 게임 머니, 연료, 마법의 주문 등)에 대한 소비를 구현할 겁니다. 일단 구매한 후 관리되는 아이템은 Google Play로 소비 요청을 보내어 소비해야 다시 구매할 수 있습니다. 인앱 상품 소비에 대한 자세한 내용은 아이템 소비를 참조하세요.

구독

구독은 매달 또는 매년 되풀이되는 결제로 앱 내에서 사용자들에게 콘텐츠, 서비스 또는 기능을 판매할 수 있도록 인앱 결제에서 제공되는 상품 유형입니다. 모든 유형의 앱이나 게임에서 거의 모든 유형의 디지털 콘텐츠에 대한 구독 서비스를 판매할 수 있습니다. 구독의 작동 방식을 이해하려면 인앱 결제 구독을 참조하세요.

Version 3 API를 사용할 경우, 인앱 상품에서 사용하는 것과 동일하게 구독 서비스를 구매하고 구독 구매 정보를 검색하는 구매 흐름을 사용할 수 있습니다. 코드 예시는 구독 구현을 참조하세요.

중요: 인앱 상품과는 달리, 구독은 소비할 수 있는 상품이 아닙니다.

아이템 구매

그림 1. 구매 요청의 기본 시퀀스.

Version 3 API를 사용하는 일반적인 구매 흐름은 다음과 같습니다.

  1. 애플리케이션에서는 사용 중인 In-app Billing API의 대상 버전이 지원되는 버전인지 확인하기 위해 Google Play로 isBillingSupported 요청을 보냅니다.
  2. 애플리케이션이 시작되거나 사용자가 로그인할 때 사용자가 어떤 아이템을 소유하고 있는지 확인하기 위해 Google Play로 검사하는 것이 좋은 방법입니다. 사용자의 인앱 구매를 쿼리하려면 getPurchases 요청을 보내세요. 요청에 성공하면 Google Play는 구매한 아이템의 상품 ID 목록, 개별 구매 세부정보 목록, 구매를 위한 서명 목록이 포함된 Bundle을 반환합니다.
  3. 보통은 구매할 수 있는 상품을 사용자에게 알려주고 싶을 것입니다. Google Play에서 정의한 인앱 상품의 세부정보를 쿼리하기 위해, 애플리케이션이 getSkuDetails 요청을 보낼 수 있습니다. 쿼리 요청에 상품 ID 목록을 지정해야 합니다. 요청에 성공하면 Google Play는 상품의 가격, 제목, 설명, 구매 유형을 비롯한 상품 세부정보가 포함된 Bundle을 반환합니다.
  4. 사용자가 인앱 상품을 소유하고 있지 않으면 상품 구매를 시작할 수 있습니다. 구매 요청을 시작하기 위해, 애플리케이션은 다른 매개변수와 함께 구매할 아이템의 상품 ID를 지정하는 getBuyIntent 요청을 보냅니다. Developer Console에서 새 인앱 상품을 만들 때 상품 ID를 기록해야 합니다.
    1. Google Play는 애플리케이션이 구매를 위한 결제 UI를 시작하기 위해 사용하는 PendingIntent가 포함된 Bundle을 반환합니다.
    2. 애플리케이션은 startIntentSenderForResult 메서드를 호출하여 보류 중인 인텐트를 시작합니다.
    3. 결제 흐름이 완료되면(즉, 사용자가 아이템 구매에 성공하거나 구매를 취소하면) Google Play는 응답 IntentonActivityResult 메서드로 보냅니다. onActivityResult의 결과 코드에는 구매의 성공 또는 취소 여부를 나타내는 결과 코드가 있습니다. 응답 Intent에는 이 구매 트랜잭션을 고유하게 식별하기 위해 Google Play에서 생성되는 purchaseToken String을 포함하여, 구매 아이템에 대한 정보가 들어 있습니다. Intent에는 개인 개발자 키로 서명하는 구매 서명도 포함됩니다.

Version 3 API 호출과 서버 응답에 대한 자세한 내용은 인앱 결제 참조를 확인해 보세요.

인앱 상품 소비

인앱 상품에 대한 사용자 소유권을 추적하는 소비 메커니즘을 사용할 수 있습니다.

Version 3에서는 모든 인앱 상품이 관리됩니다. 즉, Google Play에서 모든 인앱 아이템 구매에 대한 소유권이 유지 관리되고, 필요할 경우 애플리케이션이 사용자의 구매 정보를 쿼리할 수 있다는 뜻입니다. 사용자가 인앱 상품 구매에 성공하면 Google Play에 구매 내역이 기록됩니다. 일단 인앱 상품에 대한 구매가 이루어지면 해당 상품은 "소유된" 상태로 간주됩니다. "소유된" 상태의 인앱 상품은 Google Play에서 구매할 수 없습니다. "소유된" 인앱 상품에 대한 소비 요청을 보내야 Google Play에서 해당 상품을 다시 구매할 수 있는 상태가 됩니다. 인앱 상품을 소비하면 상품이 "소유되지 않은" 상태로 되돌아가고, 이전의 구매 데이터가 삭제됩니다.

그림 2. 소비 요청의 기본 시퀀스.

사용자가 소유한 제품의 목록을 검색하기 위해 애플리케이션이 Google Play로 getPurchases 호출을 보냅니다. 애플리케이션은 consumePurchase 호출을 보내서 소비 요청을 수행할 수 있습니다. 인앱 상품 구매 시 Google Play에서 받은 상품의 고유 purchaseToken String을 요청 인수에 지정해야 합니다. Google Play는 소비가 올바로 기록되었는지를 나타내는 상태 코드를 반환합니다.

비소비성 인앱 상품과 소비성 인앱 상품

인앱 상품을 비소비성 아이템으로 처리할지, 아니면 소비성 아이템으로 처리할지는 개발자에게 달린 문제입니다.

비소비성 아이템
일반적으로 애플리케이션에서 한 번만 구매할 수 있고, 그러면 계속 이용할 수 있는 인앱 상품에 대해서는 소비를 구현하지 않습니다. 이런 아이템은 일단 구매하고 나면 사용자의 Google 계정에 영구적으로 연결됩니다. 비소비성 인앱 상품의 예로는 프리미엄 업그레이드나 레벨 팩이 있습니다.
소비성 아이템
반면에, 여러 번 구매하도록 만들 수 있는 아이템에 대해서는 소비를 구현할 수 있습니다. 보통, 이런 아이템은 일시적으로 특정한 효과를 제공합니다. 예를 들어, 사용자의 게임 내 캐릭터가 라이프 포인트나 특별한 금화 같은 것을 얻어 비축해 둘 수 있습니다. 애플리케이션에서 구매한 아이템의 혜택이나 효과를 분배하는 것을 인앱 상품의 프로비저닝이라고 합니다. 인앱 상품을 사용자들에게 프로비저닝하는 방법을 관리하고 추적할 책임은 개발자에게 있습니다.

중요: 애플리케이션에서 소비성 인앱 상품을 프로비저닝하기 전에 Google Play로 소비 요청을 보내고 소비가 기록되었음을 나타내는 성공 응답을 받아야 합니다.

애플리케이션에서 소비성 구매 관리

다음은 소비성 인앱 상품을 구매하는 기본적인 흐름을 설명한 내용입니다.

  1. getBuyIntent 호출로 구매 흐름을 시작합니다.
  2. Google Play에서 구매가 성공적으로 완료되었는지를 나타내는 응답 Bundle을 받습니다.
  3. 구매에 성공한 경우 consumePurchase를 호출하여 구매를 소비합니다.
  4. Google Play에서 소비가 성공적으로 완료되었는지를 나타내는 응답 코드를 받습니다.
  5. 소비에 성공한 경우 애플리케이션에서 상품을 프로비저닝합니다.

다음으로, 사용자가 애플리케이션을 시작하거나 애플리케이션에 로그인할 때 사용자가 미결제 상태의 소비성 인앱 상품을 소유하고 있는지 확인하고, 소유하고 있으면 해당 아이템을 소비하고 프로비저닝하세요. 다음은 애플리케이션에 소비성 인앱 상품을 구현할 때 권장되는 애플리케이션 시작 흐름입니다.

  1. getPurchases 요청을 보내서 사용자가 소유한 인앱 상품이 있는지 쿼리합니다.
  2. 소비성 인앱 상품이 있으면 consumePurchase를 호출하여 아이템을 소비합니다. 애플리케이션이 소비성 아이템에 대한 구매주문서를 완성했지만 소비 요청을 보낼 기회가 생기기도 전에 중지되거나 연결이 끊어졌을 수 있기 때문에 이 단계가 꼭 필요합니다.
  3. Google Play에서 소비가 성공적으로 완료되었는지를 나타내는 응답 코드를 받습니다.
  4. 소비에 성공한 경우 애플리케이션에서 상품을 프로비저닝합니다.

로컬 캐싱

Google Play 클라이언트는 인앱 결제 정보를 기기의 로컬 위치에서 캐시하므로, Version 3 API를 사용하여 이 정보를 더 자주 쿼리할 수 있습니다(예: getPurchases 호출을 통해). 이전 버전의 API와는 달리, 네트워크 연결을 통해 Google Play에 연결하는 방법 대신 캐시 조회를 통해 서비스되는 Version 3 API 호출이 많으며, 그 덕분에 API의 응답 시간이 대폭 단축되었습니다.