android-in-app-purchaseslisted
Install: claude install-skill lenorebreakneck630/claude-zero-to-hero-android-KMP
# Android In-App Purchases
## Core Principles
- The BillingClient connection is a long-lived resource — manage it carefully and reconnect on disconnect.
- Never grant entitlement based on client-side purchase data alone. Always verify server-side.
- Acknowledge every non-consumable purchase within three days or Google will reverse it.
- Consume purchases only for consumable items (coins, credits, etc.) that can be re-purchased.
- Expose purchase/entitlement state as a `Flow` from a repository; the domain and presentation layers consume it without touching the Billing API directly.
---
## Dependencies
```kotlin
// build.gradle.kts
implementation(libs.android.billing)
implementation(libs.android.billing.ktx)
```
```toml
[libraries]
android-billing = { module = "com.android.billingclient:billing", version.ref = "billing" }
android-billing-ktx = { module = "com.android.billingclient:billing-ktx", version.ref = "billing" }
[versions]
billing = "6.2.1"
```
---
## BillingClient Setup and Connection
The `BillingClient` should live in the data layer, scoped to the application lifetime:
```kotlin
class BillingDataSource(
private val context: Context,
private val coroutineScope: CoroutineScope
) : PurchasesUpdatedListener {
private val _purchaseUpdates = MutableSharedFlow<List<Purchase>>(
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST
)
val purchaseUpdates: SharedFlow<List<Purchase>> = _purchaseUpdates.asSharedFlow(