Quick Links 강의 1 편 - 설정 강의 2편 - 인앱상품 강의 3편 - 구독상품 Github 예제 코드 이제 인앱 상품 결제를 구현해 보겠습니다. 정확히 어떤 앱이 만들어질지 직접 동영상으로 확인 해 보세요! 1회성 구매 파트가 이번 포스팅 파트입니다. - 광고제거, 크리스탈 충전 상품정보를 받아와서 화면에 표시 - 광고제거 구매, 구매여부 체크 - 크리스탈 구매, 크리스탈 충전 구현에 앞서 참고사항 예제 코드들은 Kotlin으로 되어있으며, 비동기 처리에 Coroutine을 사용하기도 합니다. 하지만 Coroutine을 사용하지 않고 콜백형식으로 구현하는 방법도 간단히 설명드릴 예정입니다. (Kotlin과 Java의 전환이 어려우시다면 제 예전 글을 참조하셔서 Kotlin을 빠르게 배워보세요!)
app/build.gradle
AndroidManifest.xml
화면 디자인 파트는 중요한 부분은 없으니 빠르게 넘어가겠습니다. activity_main.xml
activity_one_time.xml
MainActivity.kt
결제 모듈 만들기
구글에서는 인앱 결제를 위한 라이브러리로 BillingClient라는걸 제공합니다. 이것도 충분히 편안..할수있는 라이브러리입니다만 기억해야할 것이 많기 때문에 더욱 편하게 쓰기 위해서 우리는
BillingModuleCoroutine을 사용하지 않는다면 저는
자 그럼, 제일 처음 구매가 이루어지면
상품정보 불러오기 별건 하지 않았지만 어쨌든 이제는 APK를 만들어서, 구글 플레이 내부 테스트에 배포 후 인앱 상품등록 후 진행하셔야합니다. 그렇지 않을경우 상품정보가 뜨지 않는 오류가 생길 수 있습니다.
원하는 상품정보를 불러오기 위해서는 * Coroutine을 사용하지 않는 분들을 위해서 Async 버전도 적습니다. billingClinet의 모든 메소드명 뒤에 Async를 붙이면 (응답정보, 반환값) 형태로 콜백을 받을 수 있습니다. 아래와 같이 바꿔서 이용하시면 됩니다.
받아온 SkuDetails에는 이름, 설명, 가격정보, Sku 코드 등 결제를 위한 다양한 정보들이 있습니다. 이쯤에서 OneTimeActivity.kt앞서 만든
앱을 실행해 보면 이제 상품정보가 뜨게 됩니다. 상품 구매 상품 구매 파트로 넘어가보겠습니다. BillingModule.kt purchase()라는 메소드를 호출하고 SkuDetails를 넘겨주게되면 해당 상품에 대한 구매절차를 시작합니다. 자세한 내용은 주석에 있으니 코드를 천천히 따라가 보세요.
소비(consume)와 구매 확인하기 (acknowledge) 크리스탈 1,000개 구매처럼 사용자가 반복적으로 구매할 수 있는 상품에 대해서는 소비(consume)처리를 해 주어야 재 구매가 가능합니다. 그렇지 않으면 계정당 1회 구매 밖에 되지 않겠죠? 사용자가 결제를 완료 했는데 (purchaseState == PurchaseState.PURCHASED) 구매 확인이 되지 않았다(!purchase.isAcknowledged)의 경우에도 자동 환불이 되는걸 막기 위해 구매 확인 절차가 필요합니다. 이 두 케이스를 확실하게 잡기 위해서 confirmPurchase로 구매 확인처리를 하는 메소드를 만들어보았습니다. BillingClient.consumePurchase()가 소비, BillingClient.acknowledgePurchase()가 확인을 하는 부분입니다.
사실 사용자가 구매할때 네트워크 오류나...갑자기 폰이 부서지거나..기타 등등의 이유로 구매확인을 놓칠 수도 있습니다. 이럴 경우를 대비해 Activity의 onResume()시 놓친 구매건이있으면 확인을 해주는 코드도 추가합니다.
OneTimeActivity.kt다시 화면으로 돌아와서, 만든 구매 코드를 적용시켜 보겠습니다.
크리스탈 저장에 이용되는 SharedPreference Util 클래스인 AppStorage의 내용은 다음과 같습니다.
이제 정상적으로 구매도 되고, 충전도 될것입니다. 하지만 아직 문제가 남았죠! 광고제거 구매를하고 화면을 나갔다오면 구매를 안한걸로 표시가 됩니다. 구매여부 확인도 마저 구현해보도록 하겠습니다. 구매여부 확인 BillingModule.kt매번 검사 코드를 넣는게 귀찮아서 isPurchaseConfirmed()라는 Extension Function을 만들어서 구현한 모습입니다. 사용자의 구매정보를 가져와서 해당 sku가 정상적으로 구매 완료된 상태라면 true를 반환, 기록이 없다면 false를 반환합니다.
OneTimeActivity.kt화면에서는 BillingModule이 초기화된 직후 불러와주면 제대로 적용됩니다. 구매여부 확인은 비 소비성 상품인 광고제거에만 필요하므로 그렇게 구현하였습니다.
인앱 구매 완성! 잘 따라오셨다면 무리없이 결제가 동작할 것입니다. 잘 안된다면 오류 코드에 따라 다음과 같은 문제가 있을 수 있습니다.
|