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
  • Introducing Content Ids
  • Implementation
  • Security concerns

Was this helpful?

Edit on GitHub
  1. Advanced Features

Associating content

When you purchase an item / subscription, in most cases, you will know what it is meant for without needing additional details. This is the case if you purchase 200 coins, unlock level 3 of your game or subscribe to a service.

In some cases the identifier of the plan purchased is not enough to precisely identify the purchase. This is especially the case when it comes to consumables. As subscriptions and consumables cannot be purchased multiple times their usages are usually unambiguous.

There are many use cases in which you need to identify the content purchased:

  • Pay-per-view app / book store You will have several consumables that define the different possible prices of each movie on your platform. Several movies will have the same pricing and the plan identifier is not enough to know which movie was purchased as it only dexscribes a price. You will need to identify the program additionally.

  • Fantasy league If you develop a fantasy league app with multiple league and you can unlock boosters, you will have to know which league the booster must be applied to.

  • Multiple user account app If your app or game has several profiles / accounts you will want to associate the account to the purchase.

  • … in fact each time the plan identifier is not enough to identify what you purchased and unlock the feature, you will need to pass an additional identifier.

Introducing Content Ids

contentId is a feature that let's you attach your own identifier to a purchase. That identifier will be tied to the purchase during the entire process and will be sent to you through the webhook.

On your pay-per-view app you can attribute the movie identifier to dirctly unlock it without having to make any additional call to your backend to associate the purchase once it is confirmed.

Implementation

As always the implementation is easy as you just need to pass the (optional) parameter when you want to purchase.

It can be with our own paywalls

let paywallCtrl = Purchasely.presentationController(with: "my_presentation_id",
													contentId: "my_content_id",
													completion: { (result, plan) in
													
})
present(paywallCtrl, animated: true)
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.presentationView(
    context = context,
    properties = properties
) { result, plan ->
}
Purchasely.presentationView(context, properties,
new ProductViewResultListener() {
    @Override
    public void onResult(@NotNull PLYProductViewResult result, @Nullable PLYPlan plan) {
   }
});
await Purchasely.presentPresentationWithIdentifier('my_presentation_id', 'my_content_id');
Purchasely.presentPresentationWithIdentifier(
    'my_presentation_id',
    'my_content_id',
    (callback) => {
    },
    (error) => {
    }
);
await Purchasely.presentPresentationWithIdentifier('my_presentation_id', 'my_content_id');

or manually

Purchasely.purchase(plan: plan,	contentId: "my_content_id", success: {
	// Unlock / reload content and display a success / thank you message to user
} failure: { (error) in
	// Display error
}
[Purchasely purchaseWithPlan:plan
				   contentId:@"my_content_id"
					 success:^{
	// Unlock / reload content and display a success / thank you message to user
} failure:^(NSError * _Nonnull) {
	// Display error
}];
Purchasely.purchase(this@MainActivity, plan, offer, "content_id", object: PurchaseListener {
    override fun onPurchaseStateChanged(state: State) {
    }
})
Purchasely.purchase(this, plan, offer, "my_content_id", (PurchaseListener) state -> {
});
try {
  const plan = await Purchasely.purchaseWithPlanVendorId(
    'PLAN_VENDOR_ID',
    'my_content_id'
  );
  console.log('Purchased ' + plan);
} catch (e) {
  console.log(e);
}
Purchasely.purchaseWithPlanVendorId("PLAN_VENDOR_ID", "my_content_id", (plan) => {
	console.log('Purchased ' + plan);
}, (error) => {
	console.log(error);
});
try {
    Map<dynamic, dynamic> plan =
        await Purchasely.purchaseWithPlanVendorId('PURCHASELY_PLUS_MONTHLY');
    print('Purchased $plan');
} catch (e) {
    print(e);
}

Once we have checked that the customer purchase is genuine and wasn't already used, we will send you the following event on the Webhook that includes content_id :

{
  "event_name": "ACTIVATE",
  "api_version": 3,
  "content_id": "my_movie_id",
  "environment": "SANDBOX",
  "event_created_at": "2021-11-22T09:23:38.559Z",
  "event_created_at_ms": 1637573018559,
  "is_family_shared": false,
  "offer_type": "NONE",
  "original_purchased_at": "2021-11-22T09:23:36.000Z",
  "original_purchased_at_ms": 1637573016000,
  "plan": "<plan vendorID defined in the Purchasely console>",
  "product": "<product vendorID define in the Purchasely console>",
  "purchased_at": "2021-11-22T09:23:36.000Z",
  "purchased_at_ms": 1637573016000,
  "purchasely_one_time_purchase_id": "otp_XXXXXXXFFFFFFFFF",
  "store": "APPLE_APP_STORE",
  "store_app_bundle_id": "<app bundle id defined in the store console>",
  "store_country": "US",
  "store_original_transaction_id": "100000099999999",
  "store_product_id": "<store product id defined in the store console>",
  "store_transaction_id": "100000099999999",
  "user_id": "<user id you provided through the sdk>"
}

Security concerns

While you receive the contentId, you shouldn't blindly unlock the content and attribute the purchase. Some (smart) users could rewrite the request that leaves the phone and set a content_id for an expensive item after purchasing a cheaper one.

You should check that the content_id and the plan vendor_id match what you have in your database. If not raise an exception in your backend and contact the user.

PreviousAnonymous userNextAudiences

Last updated 1 year ago

Was this helpful?