diff --git a/versioned_docs/version-3.0/android-identifying-users.md b/versioned_docs/version-3.0/android-identifying-users.md deleted file mode 100644 index dca3434..0000000 --- a/versioned_docs/version-3.0/android-identifying-users.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: "Android – Identifying Users" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -Adapty creates an internal profile id for every user. But if you have your authentification system you should set your own Customer User Id. You can find the users by Customer User Id in [Profiles](profiles-crm), use it in [server-side API](getting-started-with-server-side-api), it will be sent to all integrations. - -### Setting Customer User Id on configuration - -If you have a user id during configuration, just pass it as `customerUserId` parameter to `.activate()` method: - -```kotlin title="Kotlin" -Adapty.activate(applicationContext, "PUBLIC_SDK_KEY", customerUserId = "YOUR_USER_ID") -``` -```java title="Java" -Adapty.activate(getApplicationContext(), "PUBLIC_SDK_KEY", observerMode, "YOUR_USER_ID"); -``` - -### Setting Customer User Id after configuration - -If you don't have a user id on SDK configuration, you can set it later at any time with `.identify()` method. The most common cases are after registration/authorization when the user switches from being an anonymous user to an authenticated user. - -```kotlin title="Kotlin" -Adapty.identify("YOUR_USER_ID") { error -> - if (error == null) { - // successful identify - } -} -``` -```java title="Java" -Adapty.identify("YOUR_USER_ID", error -> { - if (error == null) { - // successful identify - } -}); -``` - -Request parameters: - -- **Customer User Id** (required): a string user identifier. - -:::warning -Resubmitting of significant user data - -In some cases (for example, when a user logs into his account again), Adapty's servers already have information about that user. In such a scenario, Adapty SDK will automatically switch to work with the new user. If, during the anonymous user's existence, you passed some data to it (for example, custom attributes or attributions from third-party networks), you should resubmit that data. - -it is also quite important to re-request all paywalls and products after identify, because the data of the new user may be different -::: - -### Logging out and logging in - -You can logout the user anytime by calling `.logout()` method: - -```kotlin title="Kotlin" -Adapty.logout { error -> - if (error == null) { - // successful logout - } -} -``` -```java title="Java" -Adapty.logout(error -> { - if (error == null) { - // successful logout - } -}); -``` - -You can then login the user using `.identify()` method. \ No newline at end of file diff --git a/versioned_docs/version-3.0/android-push-notifications.md b/versioned_docs/version-3.0/android-push-notifications.md deleted file mode 100644 index d352ed5..0000000 --- a/versioned_docs/version-3.0/android-push-notifications.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "Push Notifications" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -To send push notifications you have to enter Firebase Cloud Messaging \(FCM\) **server key** in Adapty dashboard. Open Firebase, choose the app you want to use, go to **Project Settings > Cloud Messaging**, and copy the server key. If you don't have one you can create it by clicking the Add server key button in the right top corner. - - - - - - - - \ No newline at end of file diff --git a/versioned_docs/version-3.0/android-subscription-status.md b/versioned_docs/version-3.0/android-subscription-status.md deleted file mode 100644 index 16863f9..0000000 --- a/versioned_docs/version-3.0/android-subscription-status.md +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: "Android – Subscription Status" -description: "" -metadataTitle: "" ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - -With Adapty you don't have to hardcode product ids to check subscription status. You just have to verify that the user has an active access level. To do this, you have to call `.getProfile()` method: - - - -```kotlin -Adapty.getProfile { result -> - when (result) { - is AdaptyResult.Success -> { - val profile = result.value - // check the access - } - is AdaptyResult.Error -> { - val error = result.error - // handle the error - } - } -} -``` - - -```java -Adapty.getProfile(result -> { - if (result instanceof AdaptyResult.Success) { - AdaptyProfile profile = ((AdaptyResult.Success) result).getValue(); - // check the access - - } else if (result instanceof AdaptyResult.Error) { - AdaptyError error = ((AdaptyResult.Error) result).getError(); - // handle the error - } -}); -``` - - - - - - -Response parameters: - -- **Profile**: an [`AdaptyProfile`](sdk-models#adaptyprofile) object. This model contains info about access levels, subscriptions, and non-subscription purchases. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -:::note -The `.getProfile` method provides the most up-to-date result as it always tries to query the API. If for some reason (e.g. no internet connection), the Adapty SDK fails to retrieve information from the server, the data from cache will be returned. It is also important to note that the Adapty SDK updates Profile cache on a regular basis, in order to keep this information as up-to-date as possible. -::: - -Below is a complete example of checking the user's access level. - -```kotlin title="Kotlin" -Adapty.getProfile { result -> - when (result) { - is AdaptyResult.Success -> { - val profile = result.value - - if (profile.accessLevels["premium"]?.isActive == true) { - // grant access to premium features - } - } - is AdaptyResult.Error -> { - val error = result.error - // handle the error - } - } -} -``` -```java title="Java" -Adapty.getProfile(result -> { - if (result instanceof AdaptyResult.Success) { - AdaptyProfile profile = ((AdaptyResult.Success) result).getValue(); - - AdaptyProfile.AccessLevel premium = profile.getAccessLevels().get("premium"); - - if (premium != null && premium.isActive()) { - // grant access to premium features - } - } else if (result instanceof AdaptyResult.Error) { - AdaptyError error = ((AdaptyResult.Error) result).getError(); - // handle the error - } -}); -``` - -:::note -You can have multiple access levels per app. For example, if you have a newspaper app and sell subscriptions to different topics independently, you can create access levels "sports" and "science". But most of the time, you will only need one access level, in that case, you can just use the default "**premium**" access level. - -Read more about access levels in the [Access Level](access-level) section. -::: - -### Listening for subscription status updates - -You can respond to any changes in the user's subscription by setting an optional `OnProfileUpdatedListener`. The callback will fire whenever we receive a change in profile: - -```kotlin title="Kotlin" -Adapty.setOnProfileUpdatedListener { profile -> - // handle any changes to subscription state -} -``` -```java title="Java" -Adapty.setOnProfileUpdatedListener(profile -> { - // handle any changes to subscription state -}); -``` - -:::warning -Make sure to set up [Real-time Developer Notifications (RTDN)](real-time-developer-notifications-rtdn) to receive subscription updates without significant delays. -::: \ No newline at end of file diff --git a/versioned_docs/version-3.0/flutter-identifying-users.md b/versioned_docs/version-3.0/flutter-identifying-users.md deleted file mode 100644 index 05e5f0c..0000000 --- a/versioned_docs/version-3.0/flutter-identifying-users.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: "Flutter – Identifying Users" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -Adapty creates an internal profile id for every user. But if you have your authentification system you should set your own Customer User Id. You can find the users by Customer User Id in [Profiles](profiles-crm), use it in [server-side API](getting-started-with-server-side-api), it will be sent to all integrations. - -### Setting Customer User Id - -You can set your user id at any time with `.identify()` method. The most common cases are after registration/authorization when the user switches from being an anonymous user to an authenticated user. - -```javascript title="Flutter" -try { - await Adapty().identify(customerUserId); -} on AdaptyError catch (adaptyError) { - // handle the error -} catch (e) { -} -``` - -Request parameters: - -- **Customer User Id** (required): a string user identifier. - -:::warning -Resubmitting of significant user data - -In some cases (for example, when a user logs into his account again), Adapty's servers already have information about that user. In such a scenario, Adapty SDK will automatically switch to work with the new user. If, during the anonymous user's existence, you passed some data to it (for example, custom attributes or attributions from third-party networks), you should resubmit that data. - -it is also quite important to re-request all paywalls and products after identify, because the data of the new user may be different -::: - -### Logging out and logging in - -You can logout the user anytime by calling `.logout()` method: - -```javascript title="Flutter" -try { - await Adapty().logout(); -} on AdaptyError catch (adaptyError) { - // handle the error -} catch (e) { -} -``` - -You can then login the user using `.identify()` method. \ No newline at end of file diff --git a/versioned_docs/version-3.0/flutter-making-purchases.md b/versioned_docs/version-3.0/flutter-making-purchases.md deleted file mode 100644 index 3e47942..0000000 --- a/versioned_docs/version-3.0/flutter-making-purchases.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "Flutter – Making Purchases" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -To make the purchase, you have to call `.makePurchase()` method: - -```javascript title="Flutter" -try { - final profile = await Adapty().makePurchase(product: product); - // successful purchase -} on AdaptyError catch (adaptyError) { - // handle the error -} catch (e) { -} -``` - -Request parameters: - -- **Product** (required): an [`AdaptyPaywallProduct`](sdk-models#adaptypaywallproduct) object retrieved from the paywall. - -Response parameters: - -- **Profile**: an [`AdaptyProfile`](sdk-models#adaptyprofile) object. This model contains info about access levels, subscriptions, and non-subscription purchases. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -:::warning -Make sure you've added [App Store Shared Secret](app-store-shared-secret) in Adapty Dashboard, without it, we can't validate purchases. -::: - -Below is a complete example of making the purchase and checking the user's access level. - -```javascript title="Flutter" -try { - final profile = await Adapty().makePurchase(product: product); - if (profile?.accessLevels['premium']?.isActive ?? false) { - // grant access to premium features - } -} on AdaptyError catch (adaptyError) { - // handle the error -} catch (e) { -} -``` - -:::warning -Make sure to set up [App Store Server Notifications](app-store-server-notifications) to receive subscription updates without significant delays. -::: - -:::warning -Subscription offers - -If your paywall has an active promotional offer for the product you are attempting to purchase, Adapty will automatically apply that offer at the time of purchase. - -Adapty signs the request according to Apple guidelines, please make sure you've uploaded [Subscription Key](app-store-promotional-offers) in Adapty Dashboard when using promotional offers. -::: - -### Restoring purchases - -To restore purchases, you have to call `.restorePurchases()` method: - -```javascript title="Flutter" -try { - final profile = await Adapty().restorePurchases(); - // check the access level -} on AdaptyError catch (adaptyError) { - // handle the error -} catch (e) { -} -``` - -Response parameters: - -- **Profile**: an [`AdaptyProfile`](sdk-models#adaptyprofile) object. This model contains info about access levels, subscriptions, and non-subscription purchases. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -### Redeeming an Offer Code - -Since iOS 14.0 your users can redeem Offer Codes. To allow them to do so, you can present the Offer Code redemption sheet by calling the related SDK method. - -```javascript title="Flutter" -try { - await Adapty().presentCodeRedemptionSheet(); -} on AdaptyError catch (adaptyError) { - // handle the error -} catch (e) { -} -``` - -:::danger -Our experience shows that in some applications Offer Code Redemption sheet behaves unstable. We recommend that you redirect the user directly to the App Store. - -In order to do this, you need to open the url of the following format: -`https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}` -::: \ No newline at end of file diff --git a/versioned_docs/version-3.0/flutter-sdk-public-api.md b/versioned_docs/version-3.0/flutter-sdk-public-api.md deleted file mode 100644 index 8d32a0a..0000000 --- a/versioned_docs/version-3.0/flutter-sdk-public-api.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: "Flutter SDK - Public API" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; diff --git a/versioned_docs/version-3.0/flutter-subscription-status.md b/versioned_docs/version-3.0/flutter-subscription-status.md deleted file mode 100644 index 0143728..0000000 --- a/versioned_docs/version-3.0/flutter-subscription-status.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: "Flutter – Subscription Status" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -With Adapty you don't have to hardcode product ids to check subscription status. You just have to verify that the user has an active access level. To do this, you have to call `.getProfile()` method: - -```javascript title="Flutter" -try { - final profile = await Adapty().getProfile(); - // check the access -} on AdaptyError catch (adaptyError) { - // handle the error -} catch (e) { -} -``` - -Response parameters: - -- **Profile**: an [`AdaptyProfile`](sdk-models#adaptyprofile) object. This model contains info about access levels, subscriptions, and non-subscription purchases. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -:::note -The `.getProfile` method provides the most up-to-date result as it always tries to query the API. If for some reason (e.g. no internet connection), the Adapty SDK fails to retrieve information from the server, the data from cache will be returned. It is also important to note that the Adapty SDK updates `AdaptyProfile` cache on a regular basis, in order to keep this information as up-to-date as possible. -::: - -Below is a complete example of checking the user's access level. - -```javascript title="Flutter" -try { - final profile = await Adapty().getProfile(); - if (profile?.accessLevels['premium']?.isActive ?? false) { - // grant access to premium features - } -} on AdaptyError catch (adaptyError) { - // handle the error -} catch (e) { -} -``` - -:::note -You can have multiple access levels per app. For example, if you have a newspaper app and sell subscriptions to different topics independently, you can create access levels "sports" and "science". But most of the time, you will only need one access level, in that case, you can just use the default "**premium**" access level. - -Read more about access levels in the [Access Level](access-level) section. -::: - -### Listening for subscription status updates - -In order to receive messages from Adapty, you need to subscribe for a stream. Whenever the user's subscription changes, Adapty will fire an event. This stream will also produce an event at the start of the application, and the cached profile will get into it: - -```javascript title="Flutter" -Adapty().didUpdateProfileStream.listen((profile) { - // handle any changes to subscription state -}); -``` - -:::warning -Make sure to set up [App Store Server Notifications](app-store-server-notifications) to receive subscription updates without significant delays. -::: \ No newline at end of file diff --git a/versioned_docs/version-3.0/flutter-use-fallback-paywalls.md b/versioned_docs/version-3.0/flutter-use-fallback-paywalls.md deleted file mode 100644 index cddead3..0000000 --- a/versioned_docs/version-3.0/flutter-use-fallback-paywalls.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: "Flutter - Use fallback paywalls" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -To use fallback paywalls, call the `.setFallbackPaywalls` method. Pass the content of the fallback JSON file you [downloaded in the Adapty Dashboard](fallback-paywalls#download-fallback-paywalls-as-a-file-in-the-adapty-dashboard). Place this method in your code **before** fetching a paywall, ensuring that the mobile app possesses it when a fallback paywall is required to replace the standard one. - -```javascript title="Flutter" -import 'dart:async' show Future; -import 'dart:io' show Platform; -import 'package:flutter/services.dart' show rootBundle; - -final filePath = Platform.isIOS ? 'assets/ios_fallback.json' : 'assets/android_fallback.json'; -final jsonString = await rootBundle.loadString(filePath); - -try { - await adapty.setFallbackPaywalls(jsonString); -} on AdaptyError catch (adaptyError) { - // handle the error -} catch (e) { -} -``` - -Parameters: - -| Parameter | Description | -| :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **jsonString** | The contents of the fallback JSON file you [downloaded in the Adapty Dashboard](fallback-paywalls#download-fallback-paywalls-as-a-file-in-the-adapty-dashboard). | \ No newline at end of file diff --git a/versioned_docs/version-3.0/ios-identifying-users.md b/versioned_docs/version-3.0/ios-identifying-users.md deleted file mode 100644 index a00899a..0000000 --- a/versioned_docs/version-3.0/ios-identifying-users.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: "iOS – Identifying Users" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -Adapty creates an internal profile id for every user. But if you have your authentification system you should set your own Customer User Id. You can find the users by Customer User Id in [Profiles](profiles-crm), use it in [server-side API](getting-started-with-server-side-api), it will be sent to all integrations. - -### Setting Customer User Id on configuration - -If you have a user id during configuration, just pass it as `customerUserId` parameter to `.activate()` method: - -```swift title="Swift" -Adapty.activate("PUBLIC_SDK_KEY", customerUserId: "YOUR_USER_ID") -``` - -### Setting Customer User Id after configuration - -If you don't have a user id on SDK configuration, you can set it later at any time with `.identify()` method. The most common cases are after registration/authorization when the user switches from being an anonymous user to an authenticated user. - -```swift title="Swift" -Adapty.identify("YOUR_USER_ID") { error in - if error == nil { - // successful identify - } -} -``` - -Request parameters: - -- **Customer User Id** (required): a string user identifier. - -:::warning -Resubmitting of significant user data - -In some cases (for example, when a user logs into his account again), Adapty's servers already have information about that user. In such a scenario, Adapty SDK will automatically switch to work with the new user. If, during the anonymous user's existence, you passed some data to it (for example, custom attributes or attributions from third-party networks), you should resubmit that data. - -it is also quite important to re-request all paywalls and products after identify, because the data of the new user may be different -::: - -### Logging out and logging in - -You can logout the user anytime by calling `.logout()` method: - -```swift title="Swift" -Adapty.logout { error in - if error == nil { - // successful logout - } -} -``` - -You can then login the user using `.identify()` method. \ No newline at end of file diff --git a/versioned_docs/version-3.0/ios-making-purchases.md b/versioned_docs/version-3.0/ios-making-purchases.md deleted file mode 100644 index 9645e16..0000000 --- a/versioned_docs/version-3.0/ios-making-purchases.md +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: "iOS – Making Purchases" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -To make the purchase, you have to call `.makePurchase()` method: - -```swift title="Swift" -Adapty.makePurchase(product: product) { result in - switch result { - case let .success(profile): - // successful purchase - case let .failure(error): - // handle the error - } -} -``` - -Request parameters: - -- **Product** (required): an [`AdaptyPaywallProduct`](sdk-models#adaptypaywallproduct) object retrieved from the paywall. - -Response parameters: - -- **Profile**: an [`AdaptyProfile`](sdk-models#adaptyprofile) object. This model contains info about access levels, subscriptions, and non-subscription purchases. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -:::warning -Make sure you've added [App Store Shared Secret](app-store-shared-secret) in Adapty Dashboard, without it, we can't validate purchases. -::: - -Below is a complete example of making the purchase and checking the user's access level. - -```swift title="Swift" -Adapty.makePurchase(product: product) { result in - switch result { - case let .success(profile): - if profile.accessLevels["premium"]?.isActive ?? false { - // grant access to premium features - } - case let .failure(error): - // handle the error - } -} -``` - -:::warning -Make sure to set up [App Store Server Notifications](app-store-server-notifications) to receive subscription updates without significant delays. -::: - -:::warning -Subscription offers - -If your paywall has an active promotional offer for the product you are attempting to purchase, Adapty will automatically apply that offer at the time of purchase. - -Adapty signs the request according to Apple guidelines, please make sure you've uploaded [Subscription Key](app-store-promotional-offers) in Adapty Dashboard when using promotional offers. -::: - -### Restoring purchases - -To restore purchases, you have to call `.restorePurchases()` method: - -```swift title="Swift" -Adapty.restorePurchases { [weak self] result in - switch result { - case let .success(profile): - // check the access level - case let .failure(error): - // handle the error - } -} -``` - -Response parameters: - -- **Profile**: an [`AdaptyProfile`](sdk-models#adaptyprofile) object. This model contains info about access levels, subscriptions, and non-subscription purchases. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -### Deferred purchases - -For deferred purchases, Adapty SDK has an optional delegate method, which is called when the user starts the purchase in the App Store, and the transaction continues in your app. Just store `makeDeferredPurchase` and call it later if you want to hold your purchase for now. Then show the paywall to your user. To continue purchase, call `makeDeferredPurchase`. - -```swift title="Swift" -extension AppDelegate: AdaptyDelegate { - - func paymentQueue(shouldAddStorePaymentFor product: AdaptyDeferredProduct, defermentCompletion makeDeferredPurchase: @escaping (ResultCompletion?) -> Void) { - // you can store makeDeferredPurchase callback and call it later - - // or you can call it right away - makeDeferredPurchase { result in - // check the purchase - } - } - -} -``` - -### Redeeming an Offer Code - -Since iOS 14.0 your users can redeem Offer Codes. To allow them to do so, you can present the Offer Code redemption sheet by calling the related SDK method. - -```swift title="Swift" -Adapty.presentCodeRedemptionSheet() -``` - -:::danger -Our experience shows that in some applications Offer Code Redemption sheet behaves unstable. We recommend that you redirect the user directly to the App Store. - -In order to do this, you need to open the url of the following format: -`https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}` -::: \ No newline at end of file diff --git a/versioned_docs/version-3.0/ios-subscription-status.md b/versioned_docs/version-3.0/ios-subscription-status.md deleted file mode 100644 index a8663c2..0000000 --- a/versioned_docs/version-3.0/ios-subscription-status.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: "iOS – Subscription Status" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -With Adapty you don't have to hardcode product ids to check subscription status. You just have to verify that the user has an active access level. To do this, you have to call `.getProfile()` method: - -```swift title="Swift" -Adapty.getProfile { result in - if let profile = try? result.get() { - // check the access - } -} -``` - -Response parameters: - -- **Profile**: an AdaptyProfile object. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -:::note -The `.getProfile` method provides the most up-to-date result as it always tries to query the API. If for some reason (e.g. no internet connection), the Adapty SDK fails to retrieve information from the server, the data from cache will be returned. It is also important to note that the Adapty SDK updates `AdaptyProfile` cache on a regular basis, in order to keep this information as up-to-date as possible. -::: - -Below is a complete example of checking the user's access level. - -```swift title="Swift" -Adapty.getProfile { result in - if let profile = try? result.get(), - profile.accessLevels["premium"]?.isActive ?? false { - // grant access to premium features - } -} -``` - -:::note -You can have multiple access levels per app. For example, if you have a newspaper app and sell subscriptions to different topics independently, you can create access levels "sports" and "science". But most of the time, you will only need one access level, in that case, you can just use the default "**premium**" access level. - -Read more about access levels in the [Access Level](access-level) section. -::: - -### Listening for subscription status updates - -In order to receive messages from Adapty, you need to configure delegate: - -```swift title="Swift" -Adapty.delegate = self -``` - -Whenever the user's subscription changes, Adapty will fire an event. To receive subscription updates, extend `AdaptyDelegate` with `.didLoadLatestProfile` method. This method will also be called at the start of the application, and the cached profile will get into it: - -```swift title="Swift" -func didLoadLatestProfile(_ profile: AdaptyProfile) { - // handle any changes to subscription state -} -``` - -:::warning -Make sure to set up [App Store Server Notifications](app-store-server-notifications) to receive subscription updates without significant delays. -::: \ No newline at end of file diff --git a/versioned_docs/version-3.0/react-native-identifying-users.md b/versioned_docs/version-3.0/react-native-identifying-users.md deleted file mode 100644 index 4311ad6..0000000 --- a/versioned_docs/version-3.0/react-native-identifying-users.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: "React Native — Identifying Users" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -Adapty creates an internal profile id for every user. But if you have your authentification system you should set your own Customer User Id. You can find the users by Customer User Id in [Profiles](profiles-crm), use it in [server-side API](getting-started-with-server-side-api), it will be sent to all integrations. - -### Setting Customer User Id on configuration - -If you have a user id during configuration, just pass it as `customerUserId` parameter to `activate` method: - -```typescript title="Typescript" -adapty.activate("PUBLIC_SDK_KEY", { - customerUserId: "YOUR_USER_ID" -}); -``` - -### Setting customer user ID after configuration - -If you don't have a user id on SDK configuration, you can set it later at any time with `.identify()` method. The most common cases are after registration/authorization when the user switches from being an anonymous user to an authenticated user. - -```typescript title="Typescript" -try { - await adapty.identify("YOUR_USER_ID"); - // successfully identified -} catch (error) { - // handle the AdaptyError -} -``` - -Request parameters: - -- **Customer User ID** (required): a string user identifier. - -:::warning -Resubmitting of significant user data - -In some cases (for example, when a user logs into his account again), Adapty's servers already have information about that user. In such a scenario, Adapty SDK will automatically switch to work with the new user. If, during the anonymous user's existence, you passed some data to it (for example, custom attributes or attributions from third-party networks), you should resubmit that data. - -it is also quite important to re-request all paywalls and products after identify, because the data of the new user may be different -::: - -### Logging out and logging in - -You can logout the user anytime by calling `.logout()` method: - -```typescript title="Typescript" -try { - await adapty.logout(); - // successful logout -} catch (error) { - // handle `AdaptyError` -} -``` - -You can then login the user using `.identify()` method. \ No newline at end of file diff --git a/versioned_docs/version-3.0/react-native-making-purchases.md b/versioned_docs/version-3.0/react-native-making-purchases.md deleted file mode 100644 index ec1a2a4..0000000 --- a/versioned_docs/version-3.0/react-native-making-purchases.md +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: "React Native — Making Purchases" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -To make the purchase, you need to call `makePurchase` method: - -```typescript title="Typescript" -try { - const profile = await adapty.makePurchase(product); -} catch (error) { - // handle the `AdaptyError` -} -``` - -Request parameters: - -- **Product** (required): an [`AdaptyPaywallProduct`](sdk-models#adaptypaywallproduct) object retrieved from the paywall. - -Response parameters: - -- **Profile**: an [`AdaptyProfile`](sdk-models#adaptyprofile) object. This model contains info about access levels, subscriptions, and non-subscription purchases. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -:::warning -Make sure you've added [App Store Shared Secret](app-store-shared-secret) in Adapty Dashboard, without it, we can't validate purchases. -::: - -Below is a complete example of making the purchase and checking the user's access level. - -```typescript title="Typescript" -try { - const profile = await adapty.makePurchase(product); - const isSubscribed = profile.accessLevels['premium']?.isActive; - - if (isSubscribed) { - // grant access to premium features - } -} catch (error) { - // handlethe `AdaptyError` -} -``` - -:::warning -Make sure to set up [App Store Server Notifications](app-store-server-notifications) to receive subscription updates without significant delays. -::: - -:::warning -Subscription offers - -If your paywall has an active promotional offer for the product you are attempting to purchase, Adapty will automatically apply that offer at the time of purchase. - -Adapty signs the request according to Apple guidelines, please make sure you've uploaded [Subscription Key](app-store-promotional-offers) in Adapty Dashboard when using promotional offers. -::: - -### Restoring purchases - -To restore purchases, you need to call `restorePurchases` method: - -```typescript title="Typescript" -try { - const profile = await adapty.restorePurchases(); - // check the access level -} catch (error) { - // handle the `AdaptyError` -} -``` - -Response parameters: - -- **Profile**: an [`AdaptyProfile`](sdk-models#adaptyprofile) object. This object contains info about access levels, subscriptions, and non-subscription purchases. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -### Deferred purchases MAKE - -For deferred purchases, Adapty SDK has an optional delegate method, which is called when the user starts the purchase in the App Store, and the transaction continues in your app. Just store `makeDeferredPurchase` and call it later if you want to hold your purchase for now. Then show the paywall to your user. To continue purchase, call `makeDeferredPurchase`. - -```swift title="Swift" -extension AppDelegate: AdaptyDelegate { - - func paymentQueue(shouldAddStorePaymentFor product: AdaptyDeferredProduct, defermentCompletion makeDeferredPurchase: @escaping (ResultCompletion?) -> Void) { - // you can store makeDeferredPurchase callback and call it later - - // or you can call it right away - makeDeferredPurchase { result in - // check the purchase - } - } - -} -``` - -### iOS: Redeeming an Offer Code - -Since iOS 14.0 your users can redeem Offer Codes. To allow them to do so, you can present the Offer Code redemption sheet by calling the related SDK method. - -```typescript title="Typescript" -adapty.presentCodeRedemptionSheet(); -``` - -:::danger -Our experience shows that in some applications Offer Code Redemption sheet behaves unstable. We recommend that you redirect the user directly to the App Store. - -In order to do this, you need to open the url of the following format: -`https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}` -::: \ No newline at end of file diff --git a/versioned_docs/version-3.0/react-native-sdk-public-api.md b/versioned_docs/version-3.0/react-native-sdk-public-api.md deleted file mode 100644 index 72cc4ab..0000000 --- a/versioned_docs/version-3.0/react-native-sdk-public-api.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: "React Native SDK - Public API" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; diff --git a/versioned_docs/version-3.0/react-native-subscription-status.md b/versioned_docs/version-3.0/react-native-subscription-status.md deleted file mode 100644 index a837a10..0000000 --- a/versioned_docs/version-3.0/react-native-subscription-status.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: "React Native — Subscription Status" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -With Adapty you don't have to hardcode product ids to check subscription status. You just have to verify that the user has an active access level. To do this, you have to call `.getProfile()` method: - -```typescript title="Typescript" -const profile = await adapty.getProfile(); -``` - -Response parameters: - -- **Profile**: an AdaptyProfile object. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -:::note -The `.getProfile` method provides the most up-to-date result as it always tries to query the API. If for some reason (e.g. no internet connection), the Adapty SDK fails to retrieve information from the server, the data from cache will be returned. It is also important to note that the Adapty SDK updates `AdaptyProfile` cache on a regular basis, in order to keep this information as up-to-date as possible. -::: - -Below there is a complete example of checking the user's access level. - -```typescript title="Typescript" -const profile = adapty.getProfile(); -const isActive = profile.accessLevels["premium"]?.isActive; - -if (isActive) { - // grant access to premium features -} -``` - -:::note -You can have multiple access levels per app. For example, if you have a newspaper app and sell subscriptions to different topics independently, you can create access levels "sports" and "science". But most of the time, you will only need one access level, in that case, you can just use the default "**premium**" access level. - -Read more about access levels in the [Access Level](access-level) section. -::: - -### Listening for subscription status updates - -Whenever the user's subscription changes, Adapty will fire an event. To receive subscription updates, you can implement `.addEventListener` with `'onLatestProfileLoad'`event. This event will also be called at the start of the application, and the cached profile will get into it: - -```typescript title="Typescript" -adapty.addEventListener('onLatestProfileLoad', profile => { - // handle any changes to subscription state -}); -``` - -:::warning -Make sure to set up [App Store Server Notifications](app-store-server-notifications) to receive subscription updates without significant delays. -::: \ No newline at end of file diff --git a/versioned_docs/version-3.0/react-native-use-fallback-paywalls.md b/versioned_docs/version-3.0/react-native-use-fallback-paywalls.md deleted file mode 100644 index f3b8bbb..0000000 --- a/versioned_docs/version-3.0/react-native-use-fallback-paywalls.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: "React Native - Use fallback paywalls" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -Follow the instructions below to use the fallback paywalls in your mobile app code. - -### For Android - -1. Place the fallback file you [downloaded in the Adapty Dashboard](fallback-paywalls#download-fallback-paywalls-as-a-file-in-the-adapty-dashboard) to a directory on the native layer. There are 2 correct directories to put the file: `android/app/src/main/assets/` or `android/app/src/main/res/raw/`. - Please keep in mind that the `res/raw` folder has a special file naming convention (start with a letter, no capital letters, no special characters except for the underscore, and no spaces in the names). - - 1. **For android/app/src/main/assets/**: Pass the file path relatively to the `assets` directory, for example: - - `{ relativeAssetPath: 'android_fallback.json' }` if you placed the file to the root of `assets` itself - - `{ relativeAssetPath: '/android_fallback.json' }` if you placed it in a child folder of `assets` - 2. **For android/app/src/main/res/raw/**: Pass `{ rawResName: 'android_fallback' }`. Type the file name without the file extension. -2. Pass the result of step 2 to the `android` property of `FallbackPaywallsLocation`. - -### For iOS - -1. In XCode, use the menu **File** -> **Add Files to "YourProjectName"** to add the fallback file you [downloaded in the Adapty Dashboard](fallback-paywalls#download-fallback-paywalls-as-a-file-in-the-adapty-dashboard). -2. Pass `{ fileName: 'ios_fallback.json' }` to the `ios` property of `FallbackPaywallsLocation`. - -Here's an example of retrieving fallback paywall data from locally stored JSON files named `android_fallback.json` and `ios_fallback.json`. - -```typescript title="Current (v2.11+)" -//after v2.11 -const paywallsLocation = { - ios: { - fileName: 'ios_fallback.json' - }, - android: { - //if the file is located in 'android/app/src/main/assets/' - relativeAssetPath: 'android_fallback.json' - } -} -await adapty.setFallbackPaywalls(paywallsLocation); -``` -```typescript title="Legacy (before v2.11)" -//Legacy (before v2.11) -const fallbackPaywalls = Platform.select({ - ios: require('./ios_fallback.json'), - android: require('./android_fallback.json'), -}); -// React Native automatically parses JSON, but we do not need that -const fallbackString = JSON.stringify(fallbackPaywalls); - -await adapty.setFallbackPaywalls(fallbackString); -``` - -Parameters: - -| Parameter | Description | -| :------------------- | :------------------------------------------------------- | -| **paywallsLocation** | The object represents the location of the file resource. | \ No newline at end of file diff --git a/versioned_docs/version-3.0/unity-identifying-users.md b/versioned_docs/version-3.0/unity-identifying-users.md deleted file mode 100644 index 34dd476..0000000 --- a/versioned_docs/version-3.0/unity-identifying-users.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: "Unity – Identifying Users" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -Adapty creates an internal profile id for every user. But if you have your authentification system you should set your own Customer User Id. You can find the users by Customer User Id in [Profiles](profiles-crm), use it in [server-side API](getting-started-with-server-side-api), it will be sent to all integrations. - -### Setting Customer User Id after configuration - -You can set your user id at any time with `.Identify()` method. The most common cases are after registration/authorization when the user switches from being an anonymous user to an authenticated user. - -```swift title="Swift" -Adapty.Identify("YOUR_USER_ID", (error) => { - if(error == null) { - // successful identify - } -}); -``` - -Request parameters: - -- **Customer User Id** (required): a string user identifier. - -:::warning -Resubmitting of significant user data - -In some cases (for example, when a user logs into his account again), Adapty's servers already have information about that user. In such a scenario, Adapty SDK will automatically switch to work with the new user. If, during the anonymous user's existence, you passed some data to it (for example, custom attributes or attributions from third-party networks), you should resubmit that data. - -it is also quite important to re-request all paywalls and products after identify, because the data of the new user may be different -::: - -### Logging out and logging in - -You can logout the user anytime by calling `.Logout()` method: - -```swift title="Swift" -Adapty.Logout((error) => { - if(error == null) { - // successful logout - } -}); -``` - -You can then login the user using `.Identify()` method. \ No newline at end of file diff --git a/versioned_docs/version-3.0/unity-making-purchases.md b/versioned_docs/version-3.0/unity-making-purchases.md deleted file mode 100644 index c7df251..0000000 --- a/versioned_docs/version-3.0/unity-making-purchases.md +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: "Unity – Making Purchases" -description: "" -metadataTitle: "" ---- - -import Zoom from 'react-medium-image-zoom'; -import 'react-medium-image-zoom/dist/styles.css'; - -To make the purchase, you have to call `.MakePurchase()` method: - -```csharp title="C#" -Adapty.MakePurchase(product, (profile, error) => { - if(error != null) { - // handle error - return; - } - - // successful purchase -}); -``` - -Request parameters: - -- **Product** (required): an [`Adapty.PaywallProduct`](sdk-models#adaptypaywallproduct) object retrieved from the paywall. - -Response parameters: - -- **Profile**: an [`Adapty.Profile`](sdk-models#adaptyprofile) object. This model contains info about access levels, subscriptions, and non-subscription purchases. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -:::warning -Make sure you've added [App Store Shared Secret](app-store-shared-secret) in Adapty Dashboard, without it, we can't validate purchases. -::: - -Below is a complete example of making the purchase and checking the user's access level. - -```csharp title="C#" -Adapty.MakePurchase(product, (profile, error) => { - if(error != null) { - // handle error - return; - } - - // "premium" is an identifier of default access level - var accessLevel = profile.AccessLevels["premium"]; - if (accessLevel != null && accessLevel.IsActive) { - // grant access to premium features - } -}); -``` - -:::warning -Make sure to set up [App Store Server Notifications](app-store-server-notifications) to receive subscription updates without significant delays. -::: - -:::warning -Subscription offers - -If your paywall has an active promotional offer for the product you are attempting to purchase, Adapty will automatically apply that offer at the time of purchase. - -Adapty signs the request according to Apple guidelines, please make sure you've uploaded [Subscription Key](app-store-promotional-offers) in Adapty Dashboard when using promotional offers. -::: - -### Restoring purchases - -To restore purchases, you have to call `.RestorePurchases()` method: - -```csharp title="C#" -Adapty.RestorePurchases((profile, error) => { - if (error != null) { - // handle the error - } else { - // check the access level - } -}); -``` - -Response parameters: - -- **Profile**: an [`Adapty.Profile`](sdk-models#adaptyprofile) object. This model contains info about access levels, subscriptions, and non-subscription purchases. Generally, you have to check only access level status to determine whether the user has premium access to the app. - -### Redeeming an Offer Code - -Since iOS 14.0 your users can redeem Offer Codes. To allow them to do so, you can present the Offer Code redemption sheet by calling the related SDK method. - -```swift title="Swift" -Adapty.PresentCodeRedemptionSheet() -``` - -:::danger -Our experience shows that in some applications Offer Code Redemption sheet behaves unstable. We recommend that you redirect the user directly to the App Store. - -In order to do this, you need to open the url of the following format: -`https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}` -::: \ No newline at end of file