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
  • On paywall displayed
  • Anywhere in your application

Was this helpful?

Edit on GitHub
  1. Basic configuration
  2. SDK configurations
  3. Appendices

Unlock content / service

PreviousPresent paywallsNextClose SDK (Android only)

Last updated 1 year ago

Was this helpful?

On paywall displayed

When you display a paywall with you have a closure for the result of user action PLYProductViewControllerResult with three possible values

  • Purchased

  • Restored

  • Cancelled\

You also have as a second argument the plan bought or restored by the user, it is set to nil if no purchase was made. This is the preferred way to get notified when a purchase or restoration was made from a Purchasely paywall.

let paywallCtrl = Purchasely.presentationController(
   for: "my_placement_id",
   contentId: "my_content_id",
   completion: { (result, plan) in
	switch result {
                case .purchased:
                    print("User purchased: \(plan?.name)")
                    break
                case .restored:
                    print("User restored: \(plan?.name)")
                    break
                case .cancelled:
                    break
                @unknown default:
                    break
	}												
})
UIViewController *paywallCtrl = [Purchasely presentationControllerWith:@"my_presentation_id"
															 contentId:@"my_content_id"
															completion:^(enum PLYProductViewControllerResult result, PLYPlan * _Nullable plan) {

}];
[self presentViewController:paywallCtrl animated:YES completion:nil];
Purchasely.presentationViewForPlacement(
    context = this,
    placementId = "my_placement_id",
    contentId = "my_content_id",
    onClose = { },
    onLoaded  = { isLoaded -> }
) { result, plan ->
    when(result) {
        PLYProductViewResult.PURCHASED -> Log.d("Purchasely", "User purchased ${plan?.name}")
        PLYProductViewResult.CANCELLED -> Log.d("Purchasely", "User cancelled purchased")
        PLYProductViewResult.RESTORED -> Log.d("Purchasely", "User restored ${plan?.name}")
    }
}
Purchasely.presentationFragmentForPlacement(
        "my_placement_id",
        "my_content_id",
        isLoaded -> null,
        onClose,
        (result, plan) -> {
            switch (result) {
                case PURCHASED:
                    Log.d("Purchasely", "User purchased" + plan.getName());
                    break;
                case RESTORED:
                    Log.d("Purchasely", "User restored" + plan.getName());
                    break;
                case CANCELLED:
                    Log.d("Purchasely", "User cancelled purchase");
                    break;
            }
        }
);
try {
  const result = await Purchasely.presentPresentationForPlacement({
    placementVendorId: 'onboarding',
    isFullscreen: true,
  });

  switch (result.result) {
    case ProductResult.PRODUCT_RESULT_PURCHASED:
    case ProductResult.PRODUCT_RESULT_RESTORED:
      if (result.plan != null) {
        console.log('User purchased ' + result.plan.name);
      }
      break;
    case ProductResult.PRODUCT_RESULT_CANCELLED:
      break;
  }
} catch (e) {
  console.error(e);
}
Purchasely.presentPresentationForPlacement(
	'onboarding', //placementId
	null, //contentId
	true, //fullscreen
	(callback) => {
		if(callback.result == Purchasely.PurchaseResult.PURCHASED) {
			console.log("User purchased " + callback.plan.name);
		} else if(callback.result == Purchasely.PurchaseResult.RESTORED) {
			console.log("User restored " + callback.plan.name);
		} else if(callback.result == Purchasely.PurchaseResult.CANCELLED) {
			console.log("User cancelled purchased");
		}
	},
	(error) => {
		console.log("Error with purchase : " + error);
	}
);
try {
  var result = await Purchasely.presentPresentationForPlacement(
      "onboarding",
      isFullscreen: true);

  switch (result.result) {
    case PLYPurchaseResult.purchased:
      print('User purchased: ${result.plan?.name}');
      break;
    case PLYPurchaseResult.restored:
      print('User restored: ${result.plan?.name}');
      break;
    case PLYPurchaseResult.cancelled:
      print("User cancelled purchased");
      break;
  }
} catch (e) {
  print(e);
}

Anywhere in your application

When a purchase or restoration is made, you can listen to our notification. This is the method to use in parts of your application where you wish to unlock some features after a purchase was made but you should only use it to unlock content, not to notify your server of a purchase or check the current state of user subscription.

You will be notified about the purchase but not about the plan purchased. If you want to know the plan, you must use the method describe above with paywall displayed

Once the purchase is made to Apple Servers, registered in our systems, Purchasely sends a local Notification in the NotificationCenter. You can use it to unlock the content or refresh it.

You can catch it like this

 NotificationCenter.default.addObserver(self, selector: #selector(reloadContent(_:)), name: .ply_purchasedSubscription, object: nil)
[[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(reloadContent)
												 name: @"ply_purchasedSubscription"
											   object:nil];
Purchasely.livePurchase().observe(this) { plan: PLYPlan? -> 
    reloadContent(plan) 
}

Purchasely.purchaseListener = purchaseListener
// You can use LiveData
Purchasely.livePurchase().observe(this, (plan) -> {
    reloadContent(plan);
});

// Or PurchaseListener
Purchasely.setPurchaseListener(purchaseListener);
Purchasely.addPurchasedListener(() => {
    // User has successfully purchased a product, reload content
});
Purchasely.purchasedSubscription(() => {
	// User has successfully purchased a product, reload content
});
Purchasely.listenToPurchases(() {
    print('User has purchased a product');
});

//when no longer needed, remove listener
Purchasely.stopListeningToPurchases();

And use it like that

 @objc func reloadContent(_ notification: Notification) {
     // Reload the content
 }
- (void)reloadContent: (NSNotification *)aNotification {
    // Reload the content
}
private fun reloadContent(plan: PLYPlan?) {
    //Reload the content
}

//Instance of PurchaseListener
private val purchaseListener: PurchaseListener = object : PurchaseListener {
    override fun onPurchaseStateChanged(@NotNull state: State) {
        if (state is State.PurchaseComplete) {
            reloadContent(state.plan)
        } else if (state is State.RestorationComplete) {
            reloadContent(state.plan)
        }
    }
}
private void reloadContent(@Nullable PLYPlan plan) {
    //Reload the content
}

//Instance of PurchaseListener
private PurchaseListener purchaseListener = new PurchaseListener() {
    @Override
    public void onPurchaseStateChanged(@NotNull State state) {
        if(state instanceof State.PurchaseComplete) {
            PLYPlan plan = ((State.PurchaseComplete) state).getPlan();
            reloadContent(plan);
        } else if(state instanceof State.RestorationComplete) {
            PLYPlan plan = ((State.RestorationComplete) state).getPlan();
            reloadContent(plan);
        }
    }
};

For example, this can be done in every controller that displays premium content. That way you won't have to reload the content each time the controller is displayed unless a payment was made

Purchasely.presentation