Purchasely
Rechercher…
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
Swift
Objective-C
Kotlin
Java
React Native
Cordova
Flutter
1
let paywallCtrl = Purchasely.presentationController(with: "my_presentation_id",
2
contentId: "my_content_id",
3
completion: { (result, plan) in
4
5
})
6
present(paywallCtrl, animated: true)
Copied!
1
UIViewController *paywallCtrl = [Purchasely presentationControllerWith:@"my_presentation_id"
2
contentId:@"my_content_id"
3
completion:^(enum PLYProductViewControllerResult result, PLYPlan * _Nullable plan) {
4
5
}];
6
[self presentViewController:paywallCtrl animated:YES completion:nil];
Copied!
1
Purchasely.presentationFragment(
2
presentationId = "my_presentation_id",
3
contentId = "content_id"
4
) { result, plan ->
5
}
Copied!
1
Purchasely.presentationFragment("my_presentation_id", "my_content_id",
2
new ProductViewResultListener() {
3
@Override
4
public void onResult(@NotNull PLYProductViewResult result, @Nullable PLYPlan plan) {
5
}
6
});
Copied!
1
await Purchasely.presentPresentationWithIdentifier('my_presentation_id', 'my_content_id');
2
Copied!
1
Purchasely.presentPresentationWithIdentifier(
2
'my_presentation_id',
3
'my_content_id',
4
(callback) => {
5
},
6
(error) => {
7
}
8
);
Copied!
1
await Purchasely.presentPresentationWithIdentifier('my_presentation_id', 'my_content_id');
Copied!
or manually
Swift
Objective-C
Kotlin
Java
React Native
Cordova
Flutter
1
Purchasely.purchase(plan: plan, contentId: "my_content_id", success: {
2
// Unlock / reload content and display a success / thank you message to user
3
} failure: { (error) in
4
// Display error
5
}
Copied!
1
[Purchasely purchaseWithPlan:plan
2
contentId:@"my_content_id"
3
success:^{
4
// Unlock / reload content and display a success / thank you message to user
5
} failure:^(NSError * _Nonnull) {
6
// Display error
7
}];
Copied!
1
Purchasely.purchase(this@MainActivity, plan, "content_id", object: PurchaseListener {
2
override fun onPurchaseStateChanged(state: State) {
3
}
4
})
Copied!
1
Purchasely.purchase(this, plan, "my_content_id", (PurchaseListener) state -> {
2
});
Copied!
1
try {
2
const plan = await Purchasely.purchaseWithPlanVendorId(
3
'PLAN_VENDOR_ID',
4
'my_content_id'
5
);
6
console.log('Purchased ' + plan);
7
} catch (e) {
8
console.log(e);
9
}
Copied!
1
Purchasely.purchaseWithPlanVendorId("PLAN_VENDOR_ID", "my_content_id", (plan) => {
2
console.log('Purchased ' + plan);
3
}, (error) => {
4
console.log(error);
5
});
Copied!
1
try {
2
Map<dynamic, dynamic> plan =
3
await Purchasely.purchaseWithPlanVendorId('PURCHASELY_PLUS_MONTHLY');
4
print('Purchased $plan');
5
} catch (e) {
6
print(e);
7
}
Copied!
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 :
1
{
2
"event_name": "ACTIVATE",
3
"api_version": 3,
4
"content_id": "my_movie_id",
5
"environment": "SANDBOX",
6
"event_created_at": "2021-11-22T09:23:38.559Z",
7
"event_created_at_ms": 1637573018559,
8
"is_family_shared": false,
9
"offer_type": "NONE",
10
"original_purchased_at": "2021-11-22T09:23:36.000Z",
11
"original_purchased_at_ms": 1637573016000,
12
"plan": "<plan vendorID defined in the Purchasely console>",
13
"product": "<product vendorID define in the Purchasely console>",
14
"purchased_at": "2021-11-22T09:23:36.000Z",
15
"purchased_at_ms": 1637573016000,
16
"purchasely_one_time_purchase_id": "otp_XXXXXXXFFFFFFFFF",
17
"store": "APPLE_APP_STORE",
18
"store_app_bundle_id": "<app bundle id defined in the store console>",
19
"store_country": "US",
20
"store_original_transaction_id": "100000099999999",
21
"store_product_id": "<store product id defined in the store console>",
22
"store_transaction_id": "100000099999999",
23
"user_id": "<user id you provided through the sdk>"
24
}
Copied!

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.
Copier le lien
Éditer sur GitHub