Superwall
Advanced

Custom callbacks

Handle custom callback requests from paywalls to run app-side logic and return results.

Available from Android SDK 2.7.0.

Overview

Custom callbacks let a paywall request arbitrary actions from your app and receive results that determine which branch (onSuccess / onFailure) executes inside the paywall. Common use cases include validating user input, fetching data, or running business logic that lives outside the paywall.

How it works

  1. In the paywall editor, attach a Custom callback action to an element (button, form submit, etc.) and give it a name (e.g. validate_email).
  2. When the user triggers that element the SDK calls your onCustomCallback handler with a CustomCallback object.
  3. Your handler runs whatever logic is needed and returns a CustomCallbackResult — either .success() or .failure() — with optional data.
  4. The paywall receives the result and executes the matching onSuccess or onFailure branch.

Setting up the handler

Register the handler on a PaywallPresentationHandler before calling register:

val handler = PaywallPresentationHandler()

handler.onCustomCallback { callback ->
    when (callback.name) {
        "validate_email" -> {
            val email = callback.variables?.get("email") as? String
            if (isValidEmail(email)) {
                CustomCallbackResult.success(mapOf("validated" to true))
            } else {
                CustomCallbackResult.failure(mapOf("error" to "Invalid email"))
            }
        }
        else -> CustomCallbackResult.failure()
    }
}

Superwall.instance.register(placement = "campaign_trigger", handler = handler) {
    // Feature launched
}

CustomCallback

The CustomCallback data class is passed to your handler:

Prop

Type

CustomCallbackResult

Return one of the following from your handler to signal the outcome:

// Success — the paywall's onSuccess branch runs
CustomCallbackResult.success(data = mapOf("key" to "value"))

// Failure — the paywall's onFailure branch runs
CustomCallbackResult.failure(data = mapOf("error" to "Something went wrong"))

Both success() and failure() accept an optional data map whose values are sent back to the paywall and accessible as callbacks.<name>.data.<key>.

Callback behavior

When configuring the custom callback action in the paywall editor you can choose between two behaviors:

  • Blocking — the paywall waits for your handler to return before continuing the tap-action chain. Use this when the next step depends on the result (e.g. form validation).
  • Non-blocking — the paywall continues immediately. The onSuccess / onFailure handlers still fire when the result arrives, but subsequent actions in the chain do not wait.

Accessing returned data in the paywall

Inside the paywall you can reference the returned data using the pattern callbacks.<callback_name>.data.<key>. For example, if the callback named validate_email returns mapOf("validated" to true), the paywall can access callbacks.validate_email.data.validated.

How is this guide?

Edit on GitHub