Asynchronous paywalls

Pre-fetch and customize paywalls display

The feature described in this section is supported on the following versions and above:

  • iOS: 3.5.0

  • Android: 3.5.0

  • ReactNative: 2.5.0

  • Cordova: 2.5.0

  • Flutter: 1.5.0

Purchasely, by default, shows the paywall screen with a loading indicator while fetching the paywall from the network and preparing it for display.

Using Purchasely.fetchPresentation() method, you can pre-fetch the paywall from the network before displaying it. This provides the following benefits:

  • Display the paywall only after it has been loaded from the network

  • Handle network errors gracefully

  • Show a custom loading screen

  • Pre-load the paywall while users navigate through your app, such as during onboarding screens

  • Choose not to display a paywall for a specific placement


Call Purchasely.fetchPresentation for a placement or with a presentation id

  1. An error may be returned if the presentation could not be fetched from the network.

  2. If successful, you will have a PLYPresentation instance containing the following properties

class PLYPresentation(
    id: String?
    placementId: String?
    audienceId: String?
    abTestId: String?
    abTestVariantId: String?
    language: String?
    type: PLYPresentationType
    plans: [String] // get PLYPlan instance with Purchasely.plan("planId")

    // Android SDK only (Kotlin or Java)
    view: PLYTemplateView?
    // iOS SDK only (Swift or Objective-C)
    controller: UIViewController?

A presentation can be one of the following types:

  • Normal: The default behavior, a Purchasely paywall created from our console.

  • Fallback: A Purchasely paywall, but not the one you requested, as it could not be found.

  • Deactivated: No paywall associated with that placement, possibly for a specific A/B test or audience.

  • Client: You declared your own paywall in our console and should display it. Use the list of plans to determine which offers to display to your users.\

// fetch presentation with id
Purchasely.fetchPresentation(with: "presentationId", fetchCompletion: { presentation, error in

// fetch presentation for placement
    for: "onboarding",
    fetchCompletion: { presentation, error in
         // closure to get presentation and display it
         guard let presentation = presentation, error == nil else {
             print("Error while fetching presentation: \(error?.localizedDescription ?? "unknown")")
         if presentation.type == .normal || presentation.type == .fallback {
             let paywallController = presentation.controller
             // display paywall controller.
         } else if presentation.type == .deactivated {
             // nothing to display
         } else if presentation.type == .client {
             let presentationId =
             let planIds = presentation.plans
             // display your own paywall
    completion: { result, plan in
        // closure when presentation controller is closed to get result
        switch result {
            case .purchased:
                print("User purchased: \(plan?.name)")
            case .restored:
                print("User restored: \(plan?.name)")
            case .cancelled:
            @unknown default:

Last updated

© Purchasely 2020-2023