> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encorekit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Presenting Offers

> Present Encore retention offers to users at key moments in your Android app.

## Overview

Encore allows you to present targeted offers to users in exchange for rewards (free trials, discounts, credits) at critical moments like cancellation flows or feature paywalls. The SDK uses a delegation pattern — you register purchase and passthrough handlers, then call `.show()` wherever you need an offer.

***

## Handle Offer Results

<Tip>
  **Choosing your integration shape**: This page shows the handler pattern. If your call site has direct access to purchase logic, the async-result pattern is often cleaner. See [Integration Patterns](/concepts/integration-patterns) for the decision tree and [Android Integration Patterns](/publishers/android/guides/integration-patterns) for Kotlin examples.
</Tip>

Before presenting offers, register handlers that tell the SDK how to process purchases and what to do when a user dismisses. Register these once in `Application.onCreate()`, after `configure()`.

### Register `onPurchaseRequest`

Called when a user accepts an offer. Use this to trigger a purchase via Google Play Billing, RevenueCat, Adapty, or your own billing implementation.

```kotlin theme={null}
Encore.shared.onPurchaseRequest { request ->
    // Route to RevenueCat, Adapty, or your billing implementation
    billingManager.purchase(request.productId)
}
```

### Register `onPassthrough`

Called when the user dismisses the offer or no offers are available. Use this to resume the user's original action (e.g., proceed with cancellation).

```kotlin theme={null}
Encore.shared.onPassthrough { placementId ->
    // Resume your original user flow
    proceedWithCancellation()
}
```

### `onPurchaseComplete` (Optional)

Only needed when you don't set an `onPurchaseRequest` handler, or when integrating with subscription managers that don't auto-detect purchases (e.g., Adapty, Qonversion). RevenueCat and Superwall auto-detect purchases and don't need this callback.

```kotlin theme={null}
Encore.shared.onPurchaseComplete { productId, placementId ->
    // Sync purchase state with your subscription manager
}
```

### Summary

| Callback             | When it fires                                           | Required? |
| -------------------- | ------------------------------------------------------- | --------- |
| `onPurchaseRequest`  | User accepts the offer                                  | Yes       |
| `onPassthrough`      | User dismisses or no offers available                   | Yes       |
| `onPurchaseComplete` | Purchase finishes (for managers that don't auto-detect) | Optional  |

<Info>
  Both `onPurchaseRequest` and `onPassthrough` must be registered before presenting any placements.
</Info>

***

## Presenting an Offer

### With Coroutines (Recommended)

```kotlin theme={null}
lifecycleScope.launch {
    Encore.placement("cancellation_flow").show()
}
```

### Fire-and-Forget

For cases where you don't need to await the result:

```kotlin theme={null}
Encore.placement("cancellation_flow").show(lifecycleScope)
```

That's it — when the user accepts an offer, your `onPurchaseRequest` handler fires. When they dismiss or no offers are available, `onPassthrough` fires.

***

## Placement IDs

Use meaningful placement IDs to track where offers are triggered in your app:

```kotlin theme={null}
// Cancellation flow
Encore.placement("cancellation_flow").show()

// Feature paywall
Encore.placement("premium_feature_gate").show()

// Onboarding
Encore.placement("onboarding_offer").show()
```

Placement IDs appear in your Encore Dashboard analytics, letting you measure conversion rates per placement.

***

## Next Steps

* [Add Subscription Product](./add-subscription-product) - Create a Google Play subscription product and connect it to Encore
* [Configure Analytics](./configure-analytics) - Track offer performance and measure impact
