Skip to main content
The AppDNA SDK integrates with Google Play Billing Library 7.0.0 to handle subscription purchases, entitlement management, and purchase restoration. All billing operations use the SUBS product type.

Billing Module

Access billing functionality through the AppDNA.billing module (BillingModule).

Get Products

Retrieve product details for one or more product IDs:
val products = AppDNA.billing.getProducts(listOf("premium_monthly", "premium_yearly"))
// Returns List<Map<String, Any>>
Each product map contains pricing, title, description, and offer details from Google Play.

ProductInfo

PropertyTypeDescription
idStringProduct identifier
nameStringDisplay name
descriptionStringProduct description
formattedPriceStringLocalized price string (e.g., “$9.99”)
priceMicrosLongPrice in micros (e.g., 9990000)
currencyCodeStringISO 4217 currency code (e.g., “USD”)
offerTokenString?Offer token for the subscription offer

Purchase a Subscription

Initiate a purchase flow for a specific product:
AppDNA.billing.purchase("premium_monthly")
This triggers the Google Play purchase Activity. The result is delivered through the billing delegate.
The purchase method must be called from an Activity context. The SDK uses the current foreground Activity to launch the Google Play billing flow.

Restore Purchases

Restore previously purchased subscriptions:
AppDNA.billing.restorePurchases()
Restoring purchases queries Google Play for all active subscriptions and updates entitlements accordingly. This is useful after a reinstall or device change.

Entitlements

Get Current Entitlements

Retrieve the list of active entitlements:
val entitlements = AppDNA.billing.getEntitlements()
// Returns List<Map<String, Any>>

Check Active Subscription

Check whether the user has any active subscription:
val hasSubscription = AppDNA.billing.hasActiveSubscription()
// Returns Boolean

Listen for Entitlement Changes

Register a listener to be notified when entitlements change:
AppDNA.billing.onEntitlementsChanged { entitlements ->
    for (entitlement in entitlements) {
        Log.d("Billing", "Entitlement: ${entitlement.productId}, status: ${entitlement.status}")
    }
}

Billing Delegate

Implement AppDNABillingDelegate to receive billing lifecycle callbacks:
import ai.appdna.sdk.billing.AppDNABillingDelegate
import ai.appdna.sdk.billing.TransactionInfo
import ai.appdna.sdk.billing.Entitlement

class MyBillingDelegate : AppDNABillingDelegate {

    override fun onPurchaseCompleted(productId: String, transaction: TransactionInfo) {
        Log.d("Billing", "Purchase completed: $productId")
    }

    override fun onPurchaseFailed(productId: String, error: Exception) {
        Log.e("Billing", "Purchase failed: $productId", error)
    }

    override fun onEntitlementsChanged(entitlements: List<Entitlement>) {
        Log.d("Billing", "Entitlements updated: ${entitlements.size}")
    }

    override fun onRestoreCompleted(restoredProducts: List<String>) {
        Log.d("Billing", "Restored: ${restoredProducts.joinToString()}")
    }
}

Data Types

TransactionInfo

PropertyTypeDescription
transactionIdStringGoogle Play transaction identifier
productIdStringProduct identifier
purchaseDateStringISO 8601 purchase timestamp
environmentString"production" or "sandbox"

Entitlement

PropertyTypeDescription
productIdStringProduct identifier
storeStringStore identifier (e.g., "play_store")
statusStringStatus (e.g., "active", "expired")
expiresAtString?ISO 8601 expiration timestamp
isTrialBooleanWhether this is a free trial
offerTypeString?Offer type if applicable

PurchaseResult

The PurchaseResult sealed class represents all possible outcomes of a purchase:
VariantDescription
PurchaseResult.Purchased(entitlement)Purchase succeeded
PurchaseResult.CancelledUser cancelled the purchase flow
PurchaseResult.PendingPurchase is pending (e.g., awaiting payment)
PurchaseResult.UnknownUnknown result
PurchaseResult.Failed(error)Purchase failed with an error

Auto-Tracked Events

The billing module automatically tracks the following events:
EventTriggered When
purchase_startedUser initiates a purchase
purchase_completedPurchase is successfully completed
purchase_failedPurchase fails with an error
purchase_canceledUser cancels the purchase flow
purchase_pendingPurchase enters pending state
restore_startedUser initiates a restore
restore_completedRestore completes successfully
purchase_restoredAn individual purchase is restored
The SDK automatically acknowledges purchases within 3 days as required by Google Play. If a purchase is not acknowledged within this window, Google Play will automatically refund it. The NativeBillingManager also handles ITEM_ALREADY_OWNED errors by automatically triggering a restore flow.

Next Steps