Purchasely
3.7
3.7
  • Welcome page
  • General
    • Presentation
  • 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 (beta)
    • Purchasely with RevenueCat
  • S2S notifications
    • Server-to-server notifications ?
    • Apple App Store
    • Google Play Store
    • Huawei App Gallery
    • Amazon App Store
  • 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
    • Batch
    • Amplitude
    • AppsFlyer
    • Adjust
    • AT Internet (Piano Analytics)
    • Branch
    • Braze
    • Clevertap
    • Customer.io
    • Firebase
    • Iterable
    • Mixpanel
    • MoEngage
    • OneSignal
    • Segment
    • Sendinblue
  • Advanced Features
    • Asynchronous paywalls
    • 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
  • 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 3 years 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.presentationFragmentForPlacement(
    placementId = "my_placement_id",
    contentId = "my_content_id",
    callbackLoaded = { 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,
        (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. 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