Skip to main content

Overview

Encore placements let you present targeted offers at key decision points in your app. Each moment has different user intent and conversion characteristics. Start with the highest-impact moment and expand from there.

Paywall Abandonment (Primary)

The highest-impact moment. A user has seen your paywall and is about to leave without purchasing. Present an Encore offer as a last chance to convert.
// When the user dismisses your paywall
func onPaywallDismissed() {
    Encore.placement("paywall").show()
}
Why this works:
  • User has already shown purchase intent by viewing the paywall
  • They’ve seen your pricing — an offer feels like a personalized win
  • Highest conversion rate of any placement moment
When to trigger:
  • User taps “X” or swipes to dismiss the paywall
  • User taps “Not now” or “Maybe later”
  • User navigates back from a pricing screen
This is the recommended starting point for all new integrations. Get this working first, measure results, then expand to other moments.

Churn Intercept (Secondary)

Catch users who are actively trying to cancel their subscription. Present a retention offer before they complete cancellation.
// When the user taps "Cancel Subscription"
Button("Cancel Subscription") {
    Encore.placement("cancellation_flow").show()
}
Why this works:
  • User is an existing subscriber — they’ve already paid before
  • High willingness to stay if given the right incentive
  • Prevents revenue loss from churn
When to trigger:
  • User taps a cancel/unsubscribe button in your settings
  • User navigates to subscription management with cancel intent
  • Before redirecting to the App Store subscription management page
Your onPassthrough handler is critical here — if the user dismisses the offer, you must let them proceed with cancellation. Never block the cancel flow.

Choosing a Placement ID

Placement IDs identify where in your app the offer was triggered. Use descriptive, consistent names:
MomentPlacement IDDescription
Paywall abandonmentpaywallUser dismissed the paywall
Churn interceptcancellation_flowUser initiated cancellation
Feature gatefeature_gateUser hit a premium feature wall
Upgrade promptupgradeUser shown an upgrade path
Placement IDs are used in your Encore dashboard to track conversion by moment and optimize offer targeting.

Handling Results

Regardless of which moment you target, the same handlers apply:
// Handle purchases (registered once at app init)
Encore.shared.onPurchaseRequest { purchaseRequest in
    // Purchase the product through your subscription manager
}

// Handle dismissals (registered once at app init)
Encore.shared.onPassthrough { placementId in
    // Resume the user's original flow
    // e.g., proceed with cancellation, dismiss paywall, etc.
}
See onPurchaseRequest and onPassthrough for full API details.

Promotional Offer Handling

For retention moments like churn intercept, Encore can include a promotional offer with the purchase request. When a promotional offer is configured in your Encore dashboard, the PurchaseRequest object will contain a promoOfferId alongside the productId. Your onPurchaseRequest handler must apply this offer during purchase.
Promotional offers are configured in App Store Connect and linked through your Encore dashboard. The promoOfferId is only present when Encore determines the user should receive a promotional offer — standard purchases will have promoOfferId set to nil.
How you handle the promotional offer depends on your subscription manager:
When no onPurchaseRequest handler is set, Encore handles promotional offer signing and purchase automatically through native StoreKit. This is the recommended approach for apps using StoreKit directly.To enable automatic signing, provide your In-App Purchase key in the Encore dashboard under EntitlementsPromotional Offer Setup. See Create a Promotional Offer for setup instructions.
If you set a custom onPurchaseRequest handler, Encore will not sign offers automatically. You must handle promo offer signing yourself using StoreKit’s Product.SubscriptionOffer APIs. Only set a custom handler if your app requires it (e.g., when routing purchases to a third-party manager).

Next Steps