Androidアプリに買い切り課金(1回限りのアイテム)を実装する手順とテスト方法をまとめます。
実装の流れ
- Google Play Consoleで商品を登録する
- アプリにBilling Libraryを追加する
- 購入フローを実装する
- 購入状態を保存・復元する
- テストする
1. Google Play Consoleで商品を登録する
Google Play Console
→ Google Playで収益化する
→ 1回限りのアイテム
→ 商品を作成
入力項目
| 項目 | 例 |
|---|---|
| アイテムID | remove_ads |
| 名前 | 広告を削除する |
| 説明 | 広告を非表示にします |
| 価格 | ¥400 |
商品IDはコード側と完全一致させる必要があります。登録後「有効にする」を忘れずに。
2. Billing Libraryの追加
build.gradle.ktsに依存関係を追加します。
dependencies {
implementation("com.android.billingclient:billing-ktx:7.0.0")
}
3. 購入フローの実装(Kotlin)
class BillingManager(private val context: Context) {
private val PRODUCT_ID = "remove_ads"
private val billingClient = BillingClient.newBuilder(context)
.setListener { billingResult, purchases ->
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
purchases?.forEach { purchase ->
handlePurchase(purchase)
}
}
}
.enablePendingPurchases()
.build()
// BillingClientの接続
fun startConnection(onReady: () -> Unit) {
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
onReady()
}
}
override fun onBillingServiceDisconnected() {}
})
}
// 商品情報の取得
suspend fun queryProductDetails(): ProductDetails? {
val params = QueryProductDetailsParams.newBuilder()
.setProductList(
listOf(
QueryProductDetailsParams.Product.newBuilder()
.setProductId(PRODUCT_ID)
.setProductType(BillingClient.ProductType.INAPP)
.build()
)
).build()
val result = billingClient.queryProductDetails(params)
return result.productDetailsList?.firstOrNull()
}
// 購入フローの開始
fun launchBillingFlow(activity: Activity, productDetails: ProductDetails) {
val productDetailsParams = BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails)
.build()
val billingFlowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(listOf(productDetailsParams))
.build()
billingClient.launchBillingFlow(activity, billingFlowParams)
}
// 購入の処理
private fun handlePurchase(purchase: Purchase) {
if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED) {
// 購入確認(必須)
val params = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()
// または acknowledgePurchase(消耗品でない場合)
// 購入状態を保存
savePurchaseState(true)
}
}
private fun savePurchaseState(isPurchased: Boolean) {
// SharedPreferencesなどに保存
}
}
4. よくあるエラーと対処法
「商品情報を取得できませんでした」
以下を順番に確認してください。
- Google Play Consoleで商品が「有効」になっているか
- 商品IDがコードと完全一致しているか(大文字小文字も含む)
- アプリが内部テスト以上でリリースされているか
- 端末でGoogle Playにサインインしているか
購入済みなのに未購入扱いになる
アプリ起動時に購入履歴を確認する処理が必要です。
// アプリ起動時に購入済みかチェック
suspend fun checkPurchaseStatus(): Boolean {
val params = QueryPurchasesParams.newBuilder()
.setProductType(BillingClient.ProductType.INAPP)
.build()
val result = billingClient.queryPurchasesAsync(params)
return result.purchasesList.any {
it.products.contains(PRODUCT_ID) &&
it.purchaseState == Purchase.PurchaseState.PURCHASED
}
}
5. テスト方法
ライセンステストで無料テスト
Google Play Console
→ 設定(歯車アイコン)
→ ライセンステスト
→ メーリングリストを作成
→ テスターのGoogleアカウントを追加
登録したアカウントでは課金画面を通過しても実際の請求は発生しません。
反映まで数時間かかる場合があります。テスト購入が成功すると「テスト購入」と表示されます。
まとめ
Google Play Billingの実装で詰まりやすいのは「商品情報を取得できない」エラーと「購入状態の復元」の2点です。
商品IDの一致確認とアプリ起動時の購入状態チェックを忘れずに実装してください。
確認環境:Billing Library 7.0.0 / Kotlin / Jetpack Compose