How to use your own paywall within Purchasely environment.
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
It could sound weird to use your home made paywall in a No Code paywall environment but it is indeed very useful to:
A/A test your paywall against the same one implemented using Purchasely's template
Test your existing paywall against one of our No Code paywall and run tests to beat your reference
Easily deploy price A/B testing infrastructure without changing your UI
Implementation
The basic paywall implementation directly returns a piece of UI but to be able to make both your paywall alongside with Purchasely's paywalls you will need to proceed differently.
First, you must declare your own paywall in our console along with the plans you wish to offer on your paywall if you want to do price A/B tests
Then you will need to fetch the paywalls and therefore you won't be able to directly display a screen returned by Purchasely.
You will have to first fetch the paywall then check whether you should display your own paywall or display the provided paywall.
Purchasely.fetchPresentation(for: "onboarding", fetchCompletion: { presentation, error in
guard let presentation = presentation, error == nil else {
print("Error while fetching presentation: \(error?.localizedDescription ?? "unknown")")
return
}
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 = presentation.id
let planIds = presentation.plans
// display your own paywall
}
})
[Purchasely fetchPresentationFor:@"onboarding" fetchCompletion:^(PLYPresentation * _Nullable presentation, NSError * _Nullable error) {
if (error != nil) {
NSLog(@"Error while fetching presentation: %@", error.localizedDescription);
return;
}
if (presentation.type == PLYPresentationTypeNormal || presentation.type == PLYPresentationTypeFallback) {
PLYPresentationViewController *paywallController = presentation.controller;
// display paywall controller.
} else if (presentation.type == PLYPresentationTypeDeactivated) {
// nothing to display
} else if (presentation.type == PLYPresentationTypeClient) {
NSString *presentationId = presentation.id;
NSArray<NSString *> *plans = presentation.plans;
//display your own paywall
}
} completion:nil];
Purchasely.fetchPresentationForPlacement(this, "onboarding") { presentation, error ->
if(error != null) {
Log.d("Purchasely", "Error fetching paywall", error)
return@fetchPresentationForPlacement
}
when(presentation?.type) {
PLYPresentationType.NORMAL,
PLYPresentationType.FALLBACK -> {
val paywallView = presentation.buildView(
context = this@MainActivity,
viewProperties = PLYPresentationViewProperties(
onClose = {
// TODO remove view
}
)
)
// Display Purchasely paywall
}
PLYPresentationType.DEACTIVATED -> {
// Nothing to display
}
PLYPresentationType.CLIENT -> {
val paywallId = presentation.id
val planIds = presentation.plans
// Display your own paywall
}
else -> {
//No presentation, it means an error was triggered
}
}
}
try {
var presentation = await Purchasely.fetchPresentation("ONBOARDING");
if (presentation == null) {
print("No presentation found");
return;
}
if (presentation.type == PLYPresentationType.deactivated) {
// No paywall to display
return;
}
if (presentation.type == PLYPresentationType.client) {
// Display my own paywall
return;
}
//Display Purchasely paywall
var presentResult = await Purchasely.presentPresentation(presentation,
isFullscreen: false);
switch (presentResult.result) {
case PLYPurchaseResult.cancelled:
{
print("User cancelled purchased");
}
break;
case PLYPurchaseResult.purchased:
{
print("User purchased ${presentResult.plan?.name}");
}
break;
case PLYPurchaseResult.restored:
{
print("User restored ${presentResult.plan?.name}");
}
break;
}
} catch (e) {
print(e);
}
// coming soon
Then call clientPresentationDisplayed(presentation) when your paywall is displayed and clientPresentationClosed(presentation) when your paywall is closed.
These steps are mandatory for Purchasely to compute conversion on your paywall and measure the performance of A/B tests.
// Call when your paywall is displayed
// in ViewDidAppear for example
Purchasely.clientPresentationOpened(with: presentation)
// Call when your paywall has been closed
// in viewWillDisappear for example
Purchasely.clientPresentationClosed(with: presentation)
// Call clientPresentationClosed in Purchasely.syncPurchase() closure
// if you are in paywallObserverMode
// Call when your paywall is displayed
// in ViewDidAppear for example
[Purchasely clientPresentationOpenedWith:presentation];
// Call when your paywall has been closed
// in viewWillDisappear for example
[Purchasely clientPresentationClosedWith:presentation];
// Call when your paywall is displayed
// For example in the onCreate() method of your Activity
Purchasely.clientPresentationDisplayed(presentation)
// Call when your paywall is closed
// For example in the onDestroy() method of your Activity
Purchasely.clientPresentationClosed(presentation)
// Call when your paywall is displayed
// For example in the onCreate() method of your Activity
Purchasely.clientPresentationDisplayed(presentation);
// Call when your paywall is closed
// For example in the onDestroy() method of your Activity
Purchasely.clientPresentationClosed(presentation);
// Call when your paywall is displayed
Purchasely.clientPresentationDisplayed(presentation);
// Call when your paywall is closed
Purchasely.clientPresentationClosed(presentation);
// Call when your paywall is displayed
Purchasely.clientPresentationDisplayed(presentation);
// Call when your paywall is closed
Purchasely.clientPresentationClosed(presentation);
You can of course do the purchase transaction from your own paywall with Purchasely by using Purchasely.purchase(plan), more information here