> ## 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.

# onPassthrough()

> Handle not-granted outcomes (dismiss, no offers)

Registers a handler invoked for all not-granted outcomes — when the user dismisses the offer or no offers are available. This signals "Encore didn't result in a purchase — run your original button logic."

<Warning>
  Set `onPassthrough` before calling `placement().show()`. If not set, the SDK will log a warning.
</Warning>

## Signature

```kotlin theme={null}
fun onPassthrough(
    handler: (placementId: String) -> Unit
): Encore
```

## Parameters

| Name      | Type               | Description                                                                    |
| --------- | ------------------ | ------------------------------------------------------------------------------ |
| `handler` | `(String) -> Unit` | Callback receiving the `placementId`. Execute your original button logic here. |

## Returns

Returns the `Encore` instance for chaining.

## Usage

### Cancel flow passthrough

```kotlin theme={null}
Encore.shared.onPassthrough { placementId ->
    // Encore didn't intercept — proceed with original action
    when (placementId) {
        "cancel_flow" -> proceedWithCancellation()
        "downgrade_flow" -> proceedWithDowngrade()
        else -> Log.d("Encore", "Passthrough for $placementId")
    }
}
```

### Chained with onPurchaseRequest

```kotlin theme={null}
Encore.shared
    .onPurchaseRequest { request ->
        billingManager.purchase(request.productId)
    }
    .onPassthrough { placementId ->
        router.handleOriginalAction(placementId)
    }
```

<Tip>
  Use `onPassthrough` to ensure your original button logic still runs when Encore doesn't intercept. For example, if a user taps "Cancel Subscription" and Encore has no offers, the passthrough handler lets you proceed with the cancellation flow.
</Tip>
