Kotlin quickstart

Add Voidhash to a native Android app and show your first paywall.

This guide takes an existing Android app from installation to a paywall and access check. Requires minSdk 23, AGP 8.9.0, and Kotlin 2.0.21.

Install the SDK

The SDK ships as a Gradle module inside the npm package @voidhash/android. Add it to your build by pointing at the installed package directory:

settings.gradle.kts
includeBuild("node_modules/@voidhash/android")
app/build.gradle.kts
dependencies {
    implementation("com.voidhash.sdk")
}

Or vendor the sources and include them directly:

settings.gradle.kts
include(":voidhash-core", ":voidhash-sdk")
project(":voidhash-core").projectDir = file("third_party/voidhash/core")
project(":voidhash-sdk").projectDir = file("third_party/voidhash/sdk")

Add the billing permission — the SDK contributes INTERNET through its own manifest:

<uses-permission android:name="com.android.vending.BILLING" />

Play Billing 8.0.0, Play Services Base, OkHttp 4.x, and kotlinx-coroutines must be on the runtime classpath.

Configure the client

Configure in your Application class with the project's publishable key:

App.kt
import com.voidhash.sdk.Voidhash
import com.voidhash.sdk.VoidhashOptions
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope

class App : Application() {
    override fun onCreate() {
        super.onCreate()

        val voidhash = Voidhash.configure(
            context = this,
            publishableKey = "vh_pk_...",
            options = VoidhashOptions(debug = BuildConfig.DEBUG),
        )

        ProcessLifecycleOwner.get().lifecycleScope.launch {
            voidhash.initialize()
        }
    }
}

The publishable key is safe to include in the app. Never ship vh_sk_... secret keys.

configure is synchronous and cheap; initialize() connects to Google Play, resolves the project schema, and reconciles anything the store still reports as unfinished. It is safe to call repeatedly — only the first successful call does work, and a failed call can be retried. The client is also reachable as Voidhash.shared.

Configure one test offer in Studio

Create the smallest complete catalog:

  1. Create a perk such as premium.
  2. Create a product, choose its billing duration, and attach the perk.
  3. Create a paywall that includes the product, then publish it.
  4. Create a paywall location such as onboarding and assign the published paywall.

Connect Google Play Console before testing a release build — see Store setup. See Products and perks and Paywalls for the model behind these steps.

Present the paywall

Resolve the paywall by location and present it from an activity:

voidhash.presentPaywall(activity, location = "onboarding", listener = object : PaywallListener {
    override fun onPurchaseCompleted(transaction: VoidhashTransaction) = unlockPremium()
    override fun onEvent(name: String, properties: Map<String, Any?>) = track(name, properties)
    override fun onDismiss() = Unit
})

It returns false when the backend has no published paywall for the location — fall back to your own screen instead of leaving the customer with nothing.

The SDK presents the paywall fullscreen and speaks the paywall bridge protocol natively: purchases, restores, close, and external links are handled for you; custom events and logs are forwarded to the listener.

Check access

Gate features on an active perk grant from the person snapshot:

val person = voidhash.getCurrentPerson()

val hasPremium = person?.activePerkIds?.contains("premium") == true

The snapshot refreshes after a successful purchase or restore. See Check access for caching behavior and failure handling.

Run a test purchase

Build and run on a device signed into an account in a Play testing track, then buy through the presented paywall. Purchases sync server-side and are acknowledged only after validation succeeds; consumables are consumed instead.

Next steps