Skip to main content
Supported on: Android SDK 1.0.33+
The AppDNA billing module provides a unified interface for in-app purchases, subscription management, and entitlement checking on Android. It integrates with Google Play Billing Library 7.0.0 and handles purchase acknowledgment, restore, and entitlement state synchronization automatically.

Configuration

The Android SDK defaults to Google Play Billing, but the billing backend is selectable via the billingProvider configuration option (default BillingProvider.StoreKit2, which maps to Google Play Billing on Android). You enable billing by calling AppDNA.configure(...) from your Application.onCreate() and ensuring the Play Billing dependency is on your classpath (the SDK pulls it in transitively).
BillingProvider is a sealed class with these cases:
  • BillingProvider.StoreKit2 — the platform store (Google Play Billing on Android).
  • BillingProvider.RevenueCat — carries no key; the host configures Purchases itself and forwards results.
  • BillingProvider.Adapty(apiKey) — starts the Adapty bridge with the given publishable key.
  • BillingProvider.None — no billing; purchases and entitlement reads fail fast rather than silently no-op.
RevenueCat and Adapty bridges exist on Android too (integrations/RevenueCatBridge.kt, integrations/AdaptyBridge.kt). Select one with billingProvider. When left at the default, all billing flows route through the native NativeBillingManager against Google Play.

Module Access

Access the billing module through the AppDNA.billing property:

Get Products

Retrieve product details for one or more product IDs (suspend function — call from a coroutine, or use the Future overload from Java):
Java-friendly variant: AppDNA.billing.getProductsFuture(productIds): CompletableFuture<List<ProductInfo>>.

ProductInfo

Purchase a Subscription

Initiate a purchase flow for a specific product. purchase is a suspend function that returns a TransactionInfo on success and requires the current Activity to host the Play Billing flow:
The Google Play purchase result also fires through your registered AppDNABillingDelegate (see below).
Pass the foreground Activity directly — the SDK uses it to launch Google Play’s billing activity. Calling from a Service or Application context throws.

Promotional offers

Pass a PurchaseOptions to select a specific subscription offer token:
Server-side receipt verification is performed automatically by the SDK. You do not need to send purchase tokens to your own server for validation.

Restore Purchases

Restore previously purchased subscriptions and one-time products (e.g., after a device change or reinstall). Suspend function — returns List<String> of restored product IDs:
Restoring purchases queries Google Play for all active subscriptions and updates entitlements accordingly. This is useful after a reinstall or device change.

Entitlements

Retrieve the current user’s entitlements (suspend function):

Entitlement

Check Active Subscription

Quickly check if the user has any active subscription:

Listen for Entitlement Changes

Register a listener to be notified when entitlements change (e.g., subscription renewal, expiration, or new purchase):

AppDNABillingDelegate

All 5 methods on this delegate fire from the active billing bridge (Google Play NativeBillingManager). Register via AppDNA.billingDelegate = yourHandler.
  • onPurchaseCompleted and onPurchaseFailed fire for every purchase regardless of entry point — paywall-driven OR direct AppDNA.billing.purchase(...) calls.
  • onRestoreCompleted fires after every successful restore.
  • onEntitlementsChanged fires whenever entitlements change (also broadcast via the local EntitlementCache).
  • onBillingUnavailable fires once when the billing connection gives up after exhausting all reconnect attempts (Play Services missing or permanently broken). Hide paywalls / disable purchase UI when this fires.
Overlap with AppDNAPaywallDelegate: when a purchase comes from a paywall, both AppDNAPaywallDelegate.onPaywallPurchaseCompleted AND AppDNABillingDelegate.onPurchaseCompleted fire. Each represents a different layer (paywall lifecycle vs platform billing). Pick one as your source of truth for your analytics — they will not double-count if you only listen on one. For more granular control, implement the AppDNABillingDelegate interface:
All methods have default empty implementations — override only the ones you need.

Example Implementation

Data Types

TransactionInfo

PurchaseResult

The PurchaseResult sealed class represents all possible outcomes of a purchase:

Auto-Tracked Events

The billing module automatically tracks the following events:
These events include the product identifier and relevant metadata. They are tracked regardless of whether you implement AppDNABillingDelegate.
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.

Full Example

Next Steps