Purchasely
4.4
4.4
  • Welcome page
  • General
    • Presentation
    • Release notes
  • Quick start
    • Console Configuration
    • SDK Implementation
    • Testing
    • Sample
  • Basic configuration
    • Console Configuration
      • Creating a new application
      • Creating your Products
        • App Store
        • Play Store
        • Huawei App Gallery
        • Amazon App Store
        • Products & Plans
      • Design your Paywalls
      • Design your Paywalls-Latest
        • Carousel
        • Carousel Flow
        • Features List
        • Features List & Plan Picker with 2 & 3 columns
        • Feature list overlay
        • Plan picker horizontal
        • Plan picker with 2 and 3 Column
    • SDK installation
      • iOS SDK
      • Android SDK
      • React Native SDK
      • Cordova SDK
      • Flutter SDK
      • Unity SDK
    • SDK configurations
      • Paywall observer mode
      • Full mode
      • StoreKit 2
      • Appendices
        • Start the SDK
        • Set User Id
        • Notify when the app is ready
        • Present paywalls
        • Unlock content / service
        • Close SDK (Android only)
    • Stripe
    • Purchasely with RevenueCat
  • S2S notifications
    • Server-to-server notifications ?
    • Apple App Store
    • Google Play Store
    • Huawei App Gallery
  • Analytics
    • Dashboards
      • Introduction
      • Live
      • Subscriptions
      • Cohorts
      • Trials
      • Events
    • Events
      • Webhook events
        • Subscription events
        • Subscription events attributes
      • SDK events
        • UI events
        • UI attributes
  • Integrations
    • Webhook
      • Receiving and understanding messages
      • Managing entitlements
      • Detailed sequence diagrams
    • Airship
    • Amplitude
    • AppsFlyer
    • Adjust
    • Piano analytics(ex AT Internet)
    • Batch
    • Branch
    • Braze
    • Clevertap
    • Customer.io
    • Firebase
    • Iterable
    • Mixpanel
    • MoEngage
    • OneSignal
    • Segment
    • Brevo(ex Sendinblue)
  • Advanced Features
    • Asynchronous paywalls
    • NEW: Promotional offers
    • Anonymous user
    • Associating content
    • Audiences
    • Customising UI
      • Errors & alerts
      • Controllers (iOS) / Fragments (Android)
    • Deeplinks automations
    • Disable placements
    • Displaying users subscriptions
    • Localization
    • Lottie animations
    • Non-subscription products
    • Paywall action interceptor
    • Promoting your products
      • Self-promotion
      • Promoting In-App Purchases
    • Purchase manually
    • Subscription status
    • Use your own paywall
  • Others
    • Frequently Asked Questions
    • Migration guides
      • Migrate to Purchasely
      • Webhook
        • Migrate to Webhook v3.0
      • SDK
        • Migrate to SDK v3.0
          • v2.2.0
          • v2.1.3
        • Migrate to SDK v3.1
        • Migrate to SDK v3.2
        • Migrate to SDK v4.0.0
  • TESTING
    • Testing Cycle Durations
Powered by GitBook

© Purchasely 2020-2023

On this page
  • When to use it ?
  • What you can do in this mode ?
  • General overview
  • Implementation
  • 1- Start the SDK
  • 2- Set user identifier
  • 3- Configure and present paywalls
  • 4- Sync your purchases
  • 5- Configure deeplinks (optional)
  • 6- Migrate your existing subscriber base (optional)

Was this helpful?

Edit on GitHub
  1. Basic configuration
  2. SDK configurations

Paywall observer mode

PreviousSDK configurationsNextFull mode

Last updated 1 year ago

Was this helpful?

When to use it ?

This mode is perfect to use Purchasely data and Purchasely paywalls without changing your existing purchase layer.

You can use this mode if you want to:

  • use Purchasely remotely modifiable paywalls

  • benefit of our unified data set of to get a better understanding of your subscribers' lifecycle

  • fuel your marketing tools with these events and create

  • all this without changing your legacy transaction processor / backend

What you can do in this mode ?

You can:

  • Display paywalls and modify them remotely

  • Create as many paywalls as you need and multiply the touch points

  • Receive our from our to trigger your automations

  • Connect our data with your marketing tools using our integrations

  • Analyse your business with our

Purchasely will provide the controllers (iOS) and fragments (Android) for your paywalls and will inform you about subscription events through our Webhook and integrations.

In this mode Purchasely won't consume your purchases or acknowledge purchases made.

  • On iOS we won't finish the transaction of your consumables that will remain in the queue if you don't do that in your code.

  • On Android the transactions will be cancelled and refunded after 3 days.

General overview

Implementation

1- Start the SDK

The start method must be called as soon as possible to catch every purchase / renewal.

In this mode, Purchasely will be able to display paywalls and observe transactions but will not process them and validate them with Apple and Google

The most important argument to set, besides apiKey , of course, is the runningMode in paywallObserver

import Purchasely

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    Purchasely.start(withAPIKey: "API_KEY,
                         appUserId: nil,
			 runningMode: .paywallObserver,
			 eventDelegate: nil,
			 logLevel: .debug) { (success, error) in
		print(success)
        }
	return true
}
#import <Purchasely/Purchasely-Swift.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
	// Override point for customization after application launch.

	[Purchasely startWithAPIKey:@"API_KEY"
			  appUserId:@"USER_ID"
			runningMode: PLYRunningModePaywallObserver
	              eventDelegate:nil
			 uiDelegate:nil
	  paywallActionsInterceptor:nil
		           logLevel: LogLevelInfo
			initialized: nil];
	return YES;
}
import io.purchasely.ext.Purchasely

Purchasely.Builder(applicationContext)
    .apiKey("API_KEY")
    .logLevel(LogLevel.DEBUG) // set to warning or error for release
    .userId("USER_ID")
    .runningMode(PLYRunningMode.PaywallObserver)
    .stores(listOf(GoogleStore(), HuaweiStore()))
    .build()

// When you are ready for Purchasely to initialize,
// you must call start() method that will grab configuration and products
// from the selected stores.
Purchasely.start { isConfigured ->
}
List<Store> stores = new ArrayList();
stores.add(new GoogleStore(), new HuaweiStore());

new Purchasely.Builder(getApplicationContext())
    .apiKey("API_KEY")
    .logLevel(LogLevel.DEBUG) // set to warning or error for release
    .userId("USER_ID")
    .runningMode(PLYRunningMode.Full.PaywallObserver)
    .stores(stores)
    .build();

// When you are ready for Purchasely to initialize,
// you must call start() method that will grab configuration and products
// from the selected stores.
Purchasely.start(isConfigured -> {
    null;
});
import Purchasely from 'react-native-purchasely';

/**
* @params String apiKey
* @params StringArray stores : may be Google, Amazon and Huawei
* @params String userId
* @params Purchasley.LogLevel logLevel
* @params RunningMode runningMode
**/
Purchasely.startWithAPIKey(
  'API_KEY',
  ['Google'],
  'USER_ID',
  Purchasely.logLevelDebug,
  RunningMode.PaywallObserver
);
/**
* @params String apiKey
* @params StringArray stores : may be Google, Amazon and Huawei
* @params String userId
* @params Purchasley.LogLevel logLevel
* @params Purchasely.RunningMode runningMode
**/
Purchasely.startWithAPIKey(
    'API_KEY', 
    ['Google'], 
    null, 
    Purchasely.LogLevel.DEBUG, 
    Purchasely.RunningMode.paywallObserver
);
/**
* @params String apiKey
* @params StringArray stores : may be Google, Amazon and Huawei
* @params String userId
* @params PLYLogLevel logLevel
* @params PLYRunningMode runningMode
**/
bool configured = await Purchasely.startWithApiKey(
        'API_KEY',
        ['Google'],
        null,
        PLYLogLevel.debug,
        PLYRunningMode.paywallObserver
    );
    
if (!configured) {
        print('Purchasely SDK not configured');
        return;
}

2- Set user identifier

We need to know whenever a user is logged in or logged out to:

  • Hide the login button in the paywalls

  • Check if the user already used a trial and display the correct price

3- Configure and present paywalls

To display a paywall, you need to can get a Controller / Fragment from Purchasely.

Then you must use the Paywall Actions Interceptor to perform the purchase triggered from Purchasely's paywalls with your purchase system.

Here is an example where MyPurchaseSystem is your internal subscription management system.

Purchasely.setPaywallActionsInterceptor { [weak self] (action, parameters, presentationInfos, proceed) in
	switch action {
		// Intercept the tap on purchase to display the terms and condition
		case .purchase:
			// Grab the plan to purchase
			guard let plan = parameters?.plan, let appleProductId = plan.appleProductId else {
				proceed(false)
				return
			}

			MyPurchaseSystem.purchase(appleProductId) { (success, error) {
				// We handle the purchase so we tell Purchasley not to handle it
				proceed(false)				
				if success {
					presentationInfos?.controller?.dismiss(animated: true, completion: nil)
				}
			}
		
		default:
			proceed(true)
	}
}
[Purchasely setPaywallActionsInterceptor:^(enum PLYPresentationAction action, PLYPresentationActionParameters *parameters, PLYPresentationInfo *presentationInfos, void (^ proceed)(BOOL)) {
        switch (action) {
            // Intercept the tap on purchase to display the terms and condition
            case PLYPresentationActionPurchase:{
                // Grab the plan to purchase
                NSString *appleProductId = parameters.plan.appleProductId;
                
                if (appleProductId == nil) {
                    proceed(NO);
                    return;
                }
                
                [MyPurchaseSystem purchase:appleProductId completion:^(BOOL success, NSError *Error) {
                    // We handle the purchase so we tell Purchasely not to handle it
                    proceed(false);
                    if (success) {
                        [presentationInfos.controller dismissViewControllerAnimated:YES completion:nil];
                    }
                }];

                break;
            }
            default:
                proceed(YES);
                break;
        }
    }];
Purchasely.setPaywallActionsInterceptor { info, action, parameters, processAction ->
    if (info?.activity == null) return@setPaywallActionsInterceptor

    when(action) {
        PLYPresentationAction.PURCHASE -> {
            Purchasely.plan("PLAN_VENDOR_ID",
                onSuccess = { plan ->
                    MyPurchaseSystem.purchase(plan.store_product_id)
                    processAction(false)
                },
                onError = { throwable ->
                    //display an error
                    processAction(false)
                }
            )
        }
        else -> processAction(true)
    }
}
Purchasely.setPaywallActionsInterceptor((info, action, parameters, listener) -> {
    switch (action) {
        case PURCHASE:
            Purchasely.plan("PLAN_VENDOR_ID", new PlanListener() {
                @Override
                public void onSuccess(@Nullable PLYPlan plan) {
                    MyPurchaseSystem.purchase(plan.store_product_id);
                    listener.processAction(false);
                }

                @Override
                public void onFailure(@NotNull Throwable throwable) {
                    //display an error
                    listener.processAction(false);
                }
            });                    
            break;
        default:
            listener.processAction(true);
    }
});
Purchasely.setPaywallActionInterceptorCallback((result) => {
    if (result.action === PLYPaywallAction.PURCHASE) {
      try {
        const plan = await Purchasely.planWithIdentifier('PLAN_VENDOR_ID');
        
        //If you want to intercept it, close paywall and display your screen
        Purchasely.closePaywall();
        
        MyPurchaseSystem.purchase(plan.productId)
        
        Purchasely.onProcessAction(false);
      } catch (e) {
        console.log(e);
        Purchasely.onProcessAction(false);
      }
    } else {
      Purchasely.onProcessAction(true);
    }
  });
Purchasely.setPaywallActionInterceptorCallback((result) => {
    if (result.action === Purchasely.PaywallAction.purchase) {
      Purchasely.planWithIdentifier('PLAN_VENDOR_ID', (plan) => {
      	//If you want to intercept it, close paywall and display your screen
        Purchasely.closePaywall();
        
        MyPurchaseSystem.purchase(plan.productId)
        
        Purchasely.onProcessAction(false);
      }, (error) => {
      	Purchasely.onProcessAction(false);
      });
    } else {
      Purchasely.onProcessAction(true);
    }
  });
Purchasely.setPaywallActionInterceptorCallback(
          (PaywallActionInterceptorResult result) {
    if (result.action == PLYPaywallAction.purchase) {
      try {
        var plan = await Purchasely.planWithIdentifier('PLAN_VENDOR_ID');
        
        //If you want to intercept it, close paywall and display your screen
        Purchasely.closePaywall();
        
        MyPurchaseSystem.purchase(plan.productId)
        
        Purchasely.onProcessAction(false);
      } catch (e) {
        print(e);
        Purchasely.onProcessAction(false);
      }
    } else {
      Purchasely.onProcessAction(true);
    }
 });

4- Sync your purchases

In oberver and paywallObserver modes, when a purchase or a restoration is made with your current flow, call the synchronize() method of our SDK to send the receipt to our backend. This allow us to save the receipts on our server to prepare for your migration.

// synchronize all purchases
Purchasely.synchronize()

// or you can synchronize for the specific apple product id bought
try await Purchasely.syncPurchase(for: "apple product id")
// synchronize all purchases
[Purchasely synchronize];

// or you can synchronize for the specific apple product id bought
[Purchasely syncPurchaseFor:@"apple-product-id" completionHandler:^(NSError * _Nullable error) {
    // Handle Error.    
}];
Purchasely.synchronize()
Purchasely.synchronize();
Purchasely.synchronize();
Purchasely.synchronize();

5- Configure deeplinks (optional)

Paywalls can be used in many othe ways that can be:

  • Push notifications deeplinks

6- Migrate your existing subscriber base (optional)

If your app already has subscribers, you must migrate them to Purchasely to:

  • Have complete dashboards including every subscriber acquired in the past

  • Handle status using the userSubscriptions

The userID parameter is optional and allows you to associate the purchase to a user instead of a device. You can also later if you wish to.

Use a to handle login from a paywall and display your login screen

Follow to import your subscribers to Purchasely.

subscription events
no-code automations
subscription events
Webhook
great charts
set it up
View implementation details
View implementation details
PaywallActionInterceptor
View implementation details
Promoted In-App Purchase
Deeplinks
this guide