ls -al

仮想通貨やプログラミングに関する事などをつらつらと書き綴ります

Google Play Billing Library 2.0を触ってみた

アプリ内課金を実装しようと思い、Google Play Billing Library 2.0を使って実際に実装、リリースするところまで出来たので、引っかかった部分など今回得たノウハウを纏めてみたいと思います。

注意点

 本記事は決済周りの処理を取り扱います。本記事の内容に従って実装を行ったことによる損害の責任は取りかねますので、自己責任で参考にしてください。

Google Play Billing Library 2.0とは

 Googleが提供するアプリ内課金を実装するためのライブラリです。Kotlin Firstが提唱されているAndroidですが、このライブラリは相変わらずJavaで実装されており、当然KotlinCoroutineなどでいい感じにはなっておらず、Callback形式で泥臭いインターフェースを触ることになります。決済周りを扱うので、これも当然なのですがテストも結構面倒です。

いい感じにしてみよう

 色々苦戦したのでいい感じにしてみました。 今回やりたかったのは、一度払えば以後ずっと適用される広告除去機能の実装です。以下のようなコードでそのような要件を満たす機能が実装できました。

各クラスの役割

  • BillingRepository

    • Google Play Billing Libraryをラップして扱いやすいインターフェースを提供するRepository。一部Repositoryらしくない処理が混じってるのでリファクタ推奨(コメントを参照してください)
  • BillingModel

    • 取得した支払い情報を格納しておくModel
  • Skus

    • 登録したSkuのidとかを登録しておくEntity

コード

こんな感じで使えます。

KotlinCoroutineでラップしておいたので、Callbackと格闘することなく非常に簡単に扱えます。

テストのやり方

  • テストに使う端末はどうしよう?

    • 支払いのテストにはエミュレータは使用できません。正しいテストを行うには実機でテストをする必要があります。
  • 支払いが行えることをテストしたい

    • android.test.purchasedというIDで指定できるskuを使用してください。これはGoogleが用意した支払いが可能なskuです。なお、テスト用のIDは以下のようなものがあります。
      • android.test.purchased
        • 正常に購入出来るID
      • android.test.canceled
        • 購入するとGooglePlayにキャンセルされるID
      • android.test.item_unavailable
        • 商品が存在しないID
  • 支払ったことを確認するテストをしたい

    • android.test.purchasedというIDで指定できるskuを使用してください。これに対してlaunchBillingFlowを使って実際に購入すると、GooglePlayに購入履歴が残ります。これによって、どうやって購入履歴を取得するかのテストが可能になります。
  • アプリは出来たので結合して実際のアイテムに対して動作を確認したい

    • アプリをGooglePlayにアップロードし、α版でクローズドリリースする必要があります。リリース後、Google Play Consoleのトップ -> 設定 -> アカウントの詳細へ移動し、ライセンステストという欄を確認します。ここに「テスト用のアクセス権がある Gmail アカウント」という項目があるので、テスト時に支払いを行うアカウントのGmailアカウントを登録してください。その後、クローズドリリースしたアプリをインストールし、支払いを行うことで、実際に購入しなくてもテストを行うことが出来ます。詳しくはこちらを確認してください。

ハマったところ

  • エミュレータではテストできない

    • launchBillingFlowなどは動いてしまいます…それに騙されてエミュレータでテストをしていると、queryPurchaseが動かないという問題に直面します。公式ドキュメントにも記載のあるとおり、きちんと実機でやりましょう。
  • queryPurchaseでは正確な支払い情報が取得できない

    • queryPurchaseというメソッドがあり、最初はそちらで実装していたのですが、どうやらこのメソッドが取得できるのは、今インストールされているアプリ上でそのデバイスが支払った情報みたいです。つまり、以前にインストールしていてその時に支払った情報や、ほかデバイスで支払った情報はこれでは取得できません。queryPurchaseHistoryAsyncを使うことで、そういった問題点を回避して支払い情報を所得出来ます。おそらく大抵のユースケースでは、queryPurchaseを使ってしまうと余計な不具合を発生させてしまうので、気をつけましょう。

参考

Use the Google Play Billing Library