Adapty использует пространство имён `AdaptySDK`. В начале файлов скриптов, использующих Adapty SDK, можно добавить:
```csharp showLineNumbers title="C#"
using AdaptySDK;
```
Подпишитесь на события Adapty:
```csharp showLineNumbers title="C#"
using UnityEngine;
using AdaptySDK;
public class AdaptyListener : MonoBehaviour, AdaptyEventListener {
public void OnLoadLatestProfile(AdaptyProfile profile) {
// handle updated profile data
}
public void OnInstallationDetailsSuccess(AdaptyInstallationDetails details) { }
public void OnInstallationDetailsFail(AdaptyError error) { }
}
```
Мы рекомендуем настроить Script Execution Order так, чтобы AdaptyListener выполнялся раньше Default Time. Это обеспечит инициализацию Adapty как можно раньше.
Теперь настройте пейволы в своём приложении:
- Если вы используете [Adapty Paywall Builder](adapty-paywall-builder), сначала [активируйте модуль AdaptyUI](#activate-adaptyui-module-of-adapty-sdk) ниже, затем следуйте [быстрому старту с Paywall Builder](unity-quickstart-paywalls).
- Если вы создаёте собственный интерфейс пейвола, смотрите [быстрый старт для кастомных пейволов](unity-quickstart-manual).
## Активация модуля AdaptyUI в Adapty SDK \{#activate-adaptyui-module-of-adapty-sdk\}
Если вы планируете использовать [Paywall Builder](adapty-paywall-builder) и установили модуль AdaptyUI, его необходимо активировать. Это можно сделать при конфигурации:
```csharp showLineNumbers title="C#"
var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY")
.SetActivateUI(true);
```
## Дополнительная настройка \{#optional-setup\}
### Логирование \{#logging\}
#### Настройка системы логирования \{#set-up-the-logging-system\}
Adapty логирует ошибки и другую важную информацию, чтобы помочь вам разобраться в происходящем. Доступны следующие уровни логирования:
| Level | Description |
| ---------- | ------------------------------------------------------------ |
| `error` | Будут записываться только ошибки |
| `warn` | Будут записываться ошибки и сообщения от SDK, которые не вызывают критических ошибок, но заслуживают внимания |
| `info` | Будут записываться ошибки, предупреждения и различные информационные сообщения |
| `verbose` | Будет записываться любая дополнительная информация, которая может быть полезна при отладке: вызовы функций, запросы к API и т. д. |
Уровень логирования можно задать при настройке Adapty в вашем приложении:
```csharp showLineNumbers title="C#"
// 'verbose' is recommended for development and the first production release
var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY");
builder.LogLevel = AdaptyLogLevel.Verbose;
```
Уровень логирования также можно изменить во время работы приложения:
```csharp showLineNumbers title="C#"
Adapty.SetLogLevel(AdaptyLogLevel.Verbose, (error) => {
// handle result
});
```
### Политики обработки данных \{#data-policies\}
Adapty не хранит персональные данные ваших пользователей, если вы явно их не передаёте. При этом вы можете настроить дополнительные политики безопасности данных в соответствии с требованиями стора или законодательства конкретной страны.
#### Отключение сбора и передачи IP-адресов \{#disable-ip-address-collection-and-sharing\}
При активации модуля Adapty установите `SetIPAddressCollectionDisabled` в значение `true`, чтобы отключить сбор и передачу IP-адресов пользователей. Значение по умолчанию — `false`.
Используйте этот параметр для защиты конфиденциальности пользователей, соблюдения региональных требований по защите данных (например, GDPR или CCPA) или для сокращения избыточного сбора данных в случаях, когда функции на основе IP-адреса не нужны вашему приложению.
```csharp showLineNumbers title="C#"
var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY")
.SetIPAddressCollectionDisabled(true);
```
#### Отключение сбора и передачи рекламного идентификатора \{#disable-advertising-id-collection-and-sharing\}
При активации модуля Adapty установите `SetAppleIDFACollectionDisabled` и/или `SetGoogleAdvertisingIdCollectionDisabled` в значение `true`, чтобы отключить сбор рекламных идентификаторов. Значение по умолчанию — `false`.
Используйте этот параметр для соблюдения политик App Store/Google Play, чтобы не вызывать запрос App Tracking Transparency, или если ваше приложение не требует рекламной атрибуции или аналитики на основе рекламных идентификаторов.
```csharp showLineNumbers title="C#"
var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY")
.SetAppleIDFACollectionDisabled(true)
.SetGoogleAdvertisingIdCollectionDisabled(true);
```
#### Настройка конфигурации медиакеша для AdaptyUI \{#set-up-media-cache-configuration-for-adaptyui\}
По умолчанию AdaptyUI кеширует медиафайлы (изображения и видео) для повышения производительности и снижения потребления трафика. Вы можете настроить параметры кеша, передав собственную конфигурацию.
Используйте `SetAdaptyUIMediaCache`, чтобы переопределить настройки кеша по умолчанию:
```csharp showLineNumbers title="C#"
var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY")
.SetAdaptyUIMediaCache(
100 * 1024 * 1024, // MemoryStorageTotalCostLimit 100MB
null, // MemoryStorageCountLimit
100 * 1024 * 1024 // DiskStorageSizeLimit 100MB
);
```
Параметры:
| Параметр | Обязательный | Описание |
|-----------------------------|----------|----------------------------------------------------------------------------------------|
| memoryStorageTotalCostLimit | optional | Общий размер кэша в памяти в байтах. По умолчанию используется платформозависимое значение. |
| memoryStorageCountLimit | optional | Максимальное количество элементов в памяти. По умолчанию используется платформозависимое значение. |
| diskStorageSizeLimit | optional | Максимальный размер файлов на диске в байтах. По умолчанию используется платформозависимое значение. |
### Включение локальных уровней доступа (Android) \{#enable-local-access-levels-android\}
По умолчанию [локальные уровни доступа](local-access-levels) включены на iOS и отключены на Android. Чтобы включить их и на Android, установите `SetGoogleLocalAccessLevelAllowed` в `true`:
```csharp showLineNumbers title="C#"
var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY")
.SetGoogleLocalAccessLevelAllowed(true);
```
### Очистка данных при восстановлении из резервной копии \{#clear-data-on-backup-restore\}
Когда `SetAppleClearDataOnBackup` установлен в `true`, SDK обнаруживает восстановление приложения из резервной копии iCloud и удаляет все локально сохранённые данные SDK, включая кешированную информацию о профиле, данные о продуктах и пейволы. После этого SDK инициализируется с чистым состоянием. Значение по умолчанию — `false`.
:::note
Удаляется только локальный кеш SDK. История транзакций с Apple и пользовательские данные на серверах Adapty остаются неизменными.
:::
```csharp showLineNumbers title="C#"
var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY")
.SetAppleClearDataOnBackup(true);
```
## Устранение неполадок \{#troubleshooting\}
#### Правила резервного копирования Android (настройка Auto Backup) \{#android-backup-rules-auto-backup-configuration\}
Некоторые SDK (включая Adapty) поставляются с собственной конфигурацией Android Auto Backup. Если вы используете несколько SDK, каждый из которых определяет правила резервного копирования, слияние манифестов Android может завершиться ошибкой, связанной с `android:fullBackupContent`, `android:dataExtractionRules` или `android:allowBackup`.
Типичные симптомы ошибки: `Manifest merger failed: Attribute application@dataExtractionRules value=(@xml/your_data_extraction_rules)
is also present at [com.other.sdk:library:1.0.0] value=(@xml/other_sdk_data_extraction_rules)`
:::note
Эти изменения нужно вносить в директорию Android-платформы (обычно находится в папке `android/` вашего проекта).
:::
Чтобы решить проблему, необходимо:
- Указать механизму слияния манифестов использовать значения вашего приложения для атрибутов, связанных с резервным копированием.
- Создать файлы правил резервного копирования, объединяющие правила Adapty с правилами других SDK.
#### 1. Добавьте пространство имён `tools` в манифест
В файле `AndroidManifest.xml` убедитесь, что корневой тег `
2. Добавьте следующую строку в `/Assets/Plugins/Android/launcherTemplate.gradle`:
```groovy showLineNumbers
apply plugin: 'com.android.application'
// highlight-next-line
apply plugin: 'kotlin-android'
apply from: 'setupSymbols.gradle'
apply from: '../shared/keepUnitySymbols.gradle'
```
3. Добавьте следующую строку в `/Assets/Plugins/Android/baseProjectTemplate.gradle`:
```groovy showLineNumbers
plugins {
// If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity
// See which Gradle version is preinstalled with Unity here https://docs.unity3d.com/Manual/android-gradle-overview.html
// See official Gradle and Android Gradle Plugin compatibility table here https://developer.android.com/studio/releases/gradle-plugin#updating-gradle
// To specify a custom Gradle version in Unity, go do "Preferences > External Tools", uncheck "Gradle Installed with Unity (recommended)" and specify a path to a custom Gradle version
id 'com.android.application' version '8.3.0' apply false
id 'com.android.library' version '8.3.0' apply false
// highlight-next-line
id 'org.jetbrains.kotlin.android' version '1.8.0' apply false
**BUILD_SCRIPT_DEPS**
}
```
---
# File: unity-quickstart-paywalls
---
---
title: "Включение покупок с помощью пейволов в Unity SDK"
description: "Узнайте, как отображать пейволы в вашем приложении на Unity с помощью Adapty SDK."
---
Чтобы включить встроенные покупки, нужно понять три ключевых концепции:
- [**Продукты**](product) — всё, что пользователи могут купить (подписки, расходуемые покупки, пожизненный доступ)
- [**Пейволы**](paywalls) — конфигурации, определяющие, какие продукты предлагать. В Adapty пейволы — единственный способ получить продукты, но благодаря этому вы можете менять предложения, цены и наборы продуктов, не трогая код приложения.
- [**Плейсменты**](placements) — где и когда показывать пейволы в приложении (например, `main`, `onboarding`, `settings`). Вы настраиваете пейволы для плейсментов в дашборде, а затем запрашиваете их по ID плейсмента в коде. Это упрощает проведение A/B-тестов и показ разных пейволов разным пользователям.
Adapty предлагает три способа включить покупки в приложении. Выберите подходящий в зависимости от требований вашего приложения:
| Реализация | Сложность | Когда использовать |
|---------------------------|------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Adapty Paywall Builder | ✅ Просто | Вы [создаёте готовый к покупкам пейвол в no-code конструкторе](quickstart-paywalls). Adapty автоматически его отображает и берёт на себя весь сложный процесс покупки, валидацию чеков и управление подписками. |
| Пейволы, созданные вручную | 🟡 Средне | Вы реализуете UI пейвола в коде приложения, но всё равно получаете объект пейвола из Adapty для гибкости в управлении предложениями. Смотрите [гайд](unity-quickstart-manual). |
| Observer mode | 🔴 Сложно | У вас уже есть собственная инфраструктура обработки покупок, и вы хотите её использовать. Учтите, что observer mode имеет ограничения в Adapty. Смотрите [статью](observer-vs-full-mode). |
:::important
**Описанные ниже шаги показывают, как реализовать пейвол, созданный в Adapty Paywall Builder.**
Если вы не хотите использовать Paywall Builder, смотрите [гайд по обработке покупок в пейволах, созданных вручную](unity-making-purchases).
:::
Чтобы отобразить пейвол, созданный в Adapty Paywall Builder, в коде приложения вам нужно только:
1. **Получить пейвол**: Получите пейвол из Adapty.
2. **Отобразить пейвол — Adapty возьмёт на себя покупки**: Покажите контейнер пейвола в вашем приложении.
3. **Обработать действия кнопок**: Свяжите взаимодействия пользователя с пейволом с реакцией приложения на них. Например, открывайте ссылки или закрывайте пейвол при нажатии кнопок.
## Прежде чем начать \{#before-you-start\}
Перед началом выполните следующие шаги:
1. Подключите приложение к [App Store](initial_ios) и/или [Google Play](initial-android) в дашборде Adapty.
2. [Создайте продукты](create-product) в Adapty.
3. [Создайте пейвол и добавьте в него продукты](create-paywall).
4. [Создайте плейсмент и добавьте в него пейвол](create-placement).
5. [Установите и активируйте Adapty SDK](sdk-installation-unity) в коде приложения.
:::tip
Самый быстрый способ выполнить эти шаги — следовать [quickstart-гайду](quickstart) или создать пейволы и плейсменты с помощью [Developer CLI](developer-cli-quickstart).
:::
## 1. Получите пейвол \{#1-get-the-paywall\}
Ваши пейволы привязаны к плейсментам, настроенным в дашборде. Плейсменты позволяют запускать разные пейволы для разных аудиторий или проводить [A/B-тесты](ab-tests).
Чтобы получить пейвол, созданный в Adapty Paywall Builder, необходимо:
1. Получить объект `paywall` по ID [плейсмента](placements) с помощью метода `GetPaywall` и проверить, является ли это пейволом, созданным в конструкторе, с помощью свойства `HasViewConfiguration`.
2. Создать представление пейвола с помощью метода `CreatePaywallView`. Представление содержит элементы UI и стили, необходимые для отображения пейвола.
:::important
Чтобы получить конфигурацию представления, необходимо включить переключатель **Show on device** в Paywall Builder. В противном случае вы получите пустую конфигурацию представления, и пейвол не будет отображён.
:::
```csharp showLineNumbers
Adapty.GetPaywall("YOUR_PLACEMENT_ID", (paywall, error) => {
if(error != null) {
// handle the error
return;
}
// Create paywall view parameters
var parameters = new AdaptyUICreatePaywallViewParameters();
// Create the paywall view
AdaptyUI.CreatePaywallView(paywall, parameters, (view, error) => {
if(error != null) {
// handle the error
return;
}
// view - the paywall view ready to be presented
});
});
```
:::info
Этот quickstart содержит минимальную конфигурацию, необходимую для отображения пейвола. Подробнее о расширенных настройках смотрите в [гайде по получению пейволов](unity-get-pb-paywalls).
:::
## 2. Отобразите пейвол \{#2-display-the-paywall\}
Теперь, когда у вас есть конфигурация пейвола, достаточно добавить несколько строк для его отображения.
Чтобы показать пейвол, используйте метод `view.Present()` на объекте `view`, созданном методом `CreatePaywallView`. Каждый объект `view` можно использовать только один раз. Если нужно показать пейвол снова, вызовите `CreatePaywallView` ещё раз, чтобы создать новый экземпляр `view`.
```csharp showLineNumbers title="Unity"
view.Present((error) => {
// handle the error
});
```
:::info
Подробнее об отображении пейвола смотрите в нашем [гайде](unity-present-paywalls).
:::
## 3. Обработайте действия кнопок \{#3-handle-button-actions\}
Когда пользователи нажимают кнопки в пейволе, Unity SDK автоматически обрабатывает покупки и восстановление. Однако другие кнопки имеют пользовательские или предопределённые идентификаторы и требуют обработки действий в вашем коде.
Например, в вашем пейволе, скорее всего, есть кнопка закрытия и ссылки для открытия (например, условия использования и политика конфиденциальности). Чтобы обработать эти действия, ваш класс должен реализовывать интерфейс `AdaptyPaywallsEventsListener` и зарегистрироваться как слушатель.
:::tip
Читайте наши гайды о том, как обрабатывать [действия](unity-handle-paywall-actions) кнопок и [события](unity-handling-events).
:::
```csharp showLineNumbers title="Unity"
public class YourClass : MonoBehaviour, AdaptyPaywallsEventsListener
{
void Start()
{
// Register this class as the paywall events listener
Adapty.SetPaywallsEventsListener(this);
}
// AdaptyPaywallsEventsListener method - handles button actions
public void PaywallViewDidPerformAction(
AdaptyUIPaywallView view,
AdaptyUIUserAction action
) {
switch (action.Type) {
case AdaptyUIUserActionType.Close:
view.Dismiss(null);
break;
case AdaptyUIUserActionType.OpenUrl:
Application.OpenURL(action.Value);
break;
default:
break;
}
}
}
```
## Следующие шаги \{#next-steps\}
:::tip
Есть вопросы или возникли проблемы? Загляните на наш [форум поддержки](https://adapty.featurebase.app/), где можно найти ответы на распространённые вопросы или задать свой. Наша команда и сообщество всегда готовы помочь!
:::
Ваш пейвол готов к отображению в приложении. Протестируйте покупки в [песочнице App Store](test-purchases-in-sandbox) или в [Google Play Store](testing-on-android), чтобы убедиться, что тестовая покупка через пейвол проходит успешно.
Теперь вам нужно [проверить уровень доступа пользователей](unity-check-subscription-status), чтобы убедиться, что вы показываете пейвол или открываете доступ к платным функциям нужным пользователям.
## Полный пример \{#full-example\}
Вот как все эти шаги можно интегрировать в приложение вместе.
```csharp showLineNumbers
using System;
using UnityEngine;
using AdaptySDK;
public class PaywallManager : MonoBehaviour, AdaptyPaywallsEventsListener
{
[SerializeField] private string placementId = "YOUR_PLACEMENT_ID";
private AdaptyUIPaywallView currentPaywallView;
void Start()
{
// Register for paywall events
Adapty.SetPaywallsEventsListener(this);
GetAndDisplayPaywall();
}
private void GetAndDisplayPaywall()
{
Adapty.GetPaywall(placementId, (paywall, error) => {
if (error != null) {
Debug.LogError("Error getting paywall: " + error.Message);
return;
}
if (paywall.HasViewConfiguration) {
CreateAndPresentPaywallView(paywall);
} else {
Debug.LogWarning("Paywall was not created using the builder");
}
});
}
private void CreateAndPresentPaywallView(AdaptyPaywall paywall)
{
var parameters = new AdaptyUICreatePaywallViewParameters();
AdaptyUI.CreatePaywallView(paywall, parameters, (view, error) => {
if (error != null) {
Debug.LogError("Error creating paywall view: " + error.Message);
return;
}
currentPaywallView = view;
view.Present((presentError) => {
if (presentError != null) {
Debug.LogError("Error presenting paywall: " + presentError.Message);
return;
}
Debug.Log("Paywall presented successfully");
});
});
}
// AdaptyPaywallsEventsListener implementation
public void PaywallViewDidPerformAction(
AdaptyUIPaywallView view,
AdaptyUIUserAction action
) {
switch (action.Type) {
case AdaptyUIUserActionType.Close:
Debug.Log("Close button pressed");
view.Dismiss(null);
break;
case AdaptyUIUserActionType.OpenUrl:
Application.OpenURL(action.Value);
break;
default:
break;
}
}
// Required interface methods (implement as needed)
public void PaywallViewDidAppear(AdaptyUIPaywallView view) { }
public void PaywallViewDidDisappear(AdaptyUIPaywallView view) { }
public void PaywallViewDidSelectProduct(AdaptyUIPaywallView view, string productId) { }
public void PaywallViewDidStartPurchase(AdaptyUIPaywallView view, AdaptyPaywallProduct product) { }
public void PaywallViewDidFinishPurchase(AdaptyUIPaywallView view, AdaptyPaywallProduct product, AdaptyPurchaseResult purchasedResult) { }
public void PaywallViewDidFailPurchase(AdaptyUIPaywallView view, AdaptyPaywallProduct product, AdaptyError error) { }
public void PaywallViewDidStartRestore(AdaptyUIPaywallView view) { }
public void PaywallViewDidFinishRestore(AdaptyUIPaywallView view, AdaptyProfile profile) { }
public void PaywallViewDidFailRestore(AdaptyUIPaywallView view, AdaptyError error) { }
public void PaywallViewDidFailRendering(AdaptyUIPaywallView view, AdaptyError error) { }
public void PaywallViewDidFailLoadingProducts(AdaptyUIPaywallView view, AdaptyError error) { }
public void PaywallViewDidFinishWebPaymentNavigation(AdaptyUIPaywallView view, AdaptyPaywallProduct product, AdaptyError error) { }
public void ShowPaywall()
{
GetAndDisplayPaywall();
}
void OnDestroy()
{
if (currentPaywallView != null) {
currentPaywallView.Dismiss(null);
}
}
}
```
---
# File: unity-check-subscription-status
---
---
title: "Проверка статуса подписки в Unity SDK"
description: "Узнайте, как проверить статус подписки в приложении Unity с помощью Adapty."
---
Чтобы решить, может ли пользователь получить доступ к платному контенту или нужно показать ему пейвол, проверьте его [уровень доступа](access-level) в профиле.
В этой статье рассказывается, как обращаться к состоянию профиля, чтобы понимать, что показывать пользователю — пейвол или платный контент.
## Получение статуса подписки \{#get-subscription-status\}
Когда нужно решить, показать пользователю пейвол или платный контент, проверьте его [уровень доступа](access-level) в профиле. Есть два способа:
- Вызвать `GetProfile`, если нужны актуальные данные профиля прямо сейчас (например, при запуске приложения) или требуется принудительное обновление.
- Настроить **автоматические обновления профиля**, чтобы хранить локальную копию, которая автоматически обновляется при изменении статуса подписки.
### Получение профиля \{#get-profile\}
Самый простой способ узнать статус подписки — использовать метод `GetProfile`:
```csharp showLineNumbers
Adapty.GetProfile((profile, error) => {
if (error != null) {
// handle the error
return;
}
// check the access
});
```
### Отслеживание обновлений подписки \{#listen-to-subscription-updates\}
Чтобы автоматически получать обновления профиля в приложении:
1. Унаследуйте `AdaptyEventListener` и реализуйте метод `OnLoadLatestProfile` — Adapty будет автоматически вызывать его при каждом изменении статуса подписки пользователя.
2. Сохраняйте обновлённые данные профиля при вызове этого метода, чтобы использовать их в приложении без дополнительных сетевых запросов.
```csharp
public class SubscriptionManager : MonoBehaviour, AdaptyEventListener {
private AdaptyProfile currentProfile;
void Start() {
// Register this object as an Adapty event listener
Adapty.SetEventListener(this);
}
// Store the profile when it updates
public void OnLoadLatestProfile(AdaptyProfile profile) {
currentProfile = profile;
// Update UI, unlock content, etc.
}
public void OnInstallationDetailsSuccess(AdaptyInstallationDetails details) { }
public void OnInstallationDetailsFail(AdaptyError error) { }
// Use stored profile instead of calling getProfile()
public bool HasAccess() {
if (currentProfile?.AccessLevels != null &&
currentProfile.AccessLevels.ContainsKey("premium")) {
return currentProfile.AccessLevels["premium"].IsActive;
}
return false;
}
}
```
:::note
Adapty автоматически вызывает `OnLoadLatestProfile` при запуске приложения, предоставляя кешированные данные о подписке даже при отсутствии интернета.
:::
## Связь профиля с логикой пейвола \{#connect-profile-with-paywall-logic\}
Когда нужно мгновенно решить, показывать пейвол или открывать доступ к платным функциям, можно проверить профиль пользователя напрямую. Это удобно при запуске приложения, входе в премиальные разделы или перед показом определённого контента.
```csharp
private void CheckAccessLevel()
{
Adapty.GetProfile((profile, error) => {
if (error != null) {
Debug.LogError("Error checking access level: " + error.Message);
// Show paywall if access check fails
return;
}
var accessLevel = profile.AccessLevels["YOUR_ACCESS_LEVEL"];
if (accessLevel == null || !accessLevel.IsActive) {
// Show paywall if no access
}
});
}
private void InitializePaywall()
{
LoadPaywall();
CheckAccessLevel();
}
```
## Дальнейшие шаги \{#next-steps\}
Теперь, когда вы знаете, как отслеживать статус подписки, узнайте, как [работать с профилями пользователей](unity-quickstart-identify), чтобы они получали доступ к тому, за что заплатили.
---
# File: unity-quickstart-identify
---
---
title: "Идентификация пользователей в Unity SDK"
description: "Быстрый старт по настройке Adapty для управления встроенными подписками в Unity."
---
:::important
Этот гайд для вас, если у вас есть собственная система аутентификации. Здесь вы узнаете, как работать с профилями пользователей в Adapty, чтобы они корректно интегрировались с вашей существующей системой аутентификации.
:::
То, как вы управляете покупками пользователей, зависит от модели аутентификации в вашем приложении:
- Если ваше приложение не использует серверную аутентификацию и не хранит данные пользователей, см. [раздел об анонимных пользователях](#anonymous-users).
- Если в вашем приложении есть (или будет) серверная аутентификация, см. [раздел об идентифицированных пользователях](#identified-users).
**Ключевые понятия**:
- **Профили** — это сущности, необходимые для работы SDK. Adapty создаёт их автоматически.
- Они могут быть анонимными **(без customer user ID)** или идентифицированными **(с customer user ID)**.
- Вы передаёте **customer user ID**, чтобы связать профили в Adapty с вашей внутренней системой авторизации.
Вот чем отличаются анонимные и идентифицированные пользователи:
| | Анонимные пользователи | Идентифицированные пользователи |
|-------------------------|---------------------------------------------------------------|-------------------------------------------------------------------------------------------------------|
| **Управление покупками** | Восстановление покупок на уровне стора | История покупок сохраняется на всех устройствах через customer user ID |
| **Управление профилем** | Новый профиль при каждой переустановке | Один и тот же профиль во всех сессиях и на всех устройствах |
| **Сохранность данных** | Данные анонимных пользователей привязаны к установке приложения | Данные идентифицированных пользователей сохраняются между установками приложения |
## Анонимные пользователи \{#anonymous-users\}
Если у вас нет серверной аутентификации, **вам не нужно реализовывать аутентификацию в коде приложения**:
1. Когда SDK активируется при первом запуске приложения, Adapty **создаёт новый профиль для пользователя**.
2. Когда пользователь совершает покупку в приложении, она **привязывается к его профилю Adapty и аккаунту в сторе**.
3. Когда пользователь **переустанавливает** приложение или устанавливает его на **новое устройство**, Adapty **создаёт новый анонимный профиль при активации**.
4. Если пользователь ранее совершал покупки в вашем приложении, по умолчанию они автоматически синхронизируются из App Store при активации SDK.
Таким образом, для анонимных пользователей при каждой установке будет создаваться новый профиль — но это не проблема, так как в аналитике Adapty можно [настроить, что считать новой установкой](general#4-installs-definition-for-analytics).
Для анонимных пользователей нужно считать установки по **device ID**. В этом случае каждая установка приложения на устройство считается отдельной установкой, включая переустановки.
## Идентификация пользователей \{#identified-users\}
Есть два способа идентифицировать пользователей в приложении:
- [**При входе/регистрации:**](#during-loginsignup) Если пользователи входят в систему после запуска приложения, вызовите `identify()` с customer user ID в момент аутентификации.
- [**При активации SDK:**](#during-the-sdk-activation) Если customer user ID уже сохранён на момент запуска приложения, передайте его при вызове `activate()`.
:::important
По умолчанию, когда Adapty получает покупку от Customer User ID, который уже связан с другим Customer User ID, уровень доступа становится общим — оба профиля получают платный доступ. Вы можете настроить это поведение так, чтобы платный доступ переносился с одного профиля на другой, или полностью отключить общий доступ. Подробнее см. в [статье](general#6-sharing-paid-access-between-user-accounts).
:::
### При входе или регистрации \{#during-loginsignup\}
Если вы идентифицируете пользователей после запуска приложения (например, после входа или регистрации), используйте метод `identify`, чтобы задать их customer user ID.
- Если вы **ещё не использовали этот customer user ID**, Adapty автоматически привяжет его к текущему профилю.
- Если вы **уже использовали этот customer user ID для идентификации пользователя**, Adapty переключится на работу с профилем, связанным с этим customer user ID.
:::important
ID пользователя должен быть уникальным для каждого пользователя. Если вы укажете фиксированное значение параметра, все пользователи будут считаться одним.
:::
Дождитесь выполнения коллбэка `Identify` перед вызовом других методов SDK. Параллельные вызовы приводят к ошибке `#3006 profileWasChanged` или попаданию в анонимный профиль. См. [Порядок вызовов в Unity SDK](unity-sdk-call-order).
```csharp showLineNumbers
Adapty.Identify("YOUR_USER_ID", (error) => { // Уникальный для каждого пользователя
if(error == null) {
// successful identify
}
});
```
### Во время активации SDK \{#during-the-sdk-activation\}
Если вы уже знаете customer user ID в момент активации SDK, можно передать его прямо в метод `activate` — вместо того чтобы вызывать `identify` отдельно.
Если вы знаете customer user ID, но задаёте его только после активации, то при активации Adapty создаст новый анонимный профиль и переключится на существующий лишь после вызова `identify`.
Вы можете передать как существующий customer user ID (тот, что использовали раньше), так и новый. Если передать новый — профиль, созданный при активации, будет автоматически привязан к этому customer user ID.
:::note
По умолчанию создание анонимных профилей не влияет на аналитические дашборды, поскольку установки считаются по идентификаторам устройств.
Идентификатор устройства соответствует одной установке приложения из стора на устройстве и пересоздаётся только при переустановке приложения.
Он не зависит от того, первая это установка или повторная, и от того, используется ли существующий пользовательский ID.
Создание профиля (при активации SDK или выходе из аккаунта), вход в систему или обновление приложения без переустановки не генерируют дополнительных событий установки.
Если вы хотите считать установки на основе уникальных пользователей, а не устройств, перейдите в **App settings** и настройте параметр [**Installs definition for analytics**](general#4-installs-definition-for-analytics).
:::
```csharp showLineNumbers
using UnityEngine;
using AdaptySDK;
var builder = new AdaptyConfiguration.Builder("YOUR_API_KEY")
.SetCustomerUserId("YOUR_USER_ID"); // Customer user IDs must be unique for each user. If you hardcode the parameter value, all users will be considered as one.
Adapty.Activate(builder.Build(), (error) => {
if (error != null) {
// handle the error
return;
}
});
```
### Выход пользователей из системы \{#log-users-out\}
Если у вас есть кнопка для выхода из аккаунта, используйте метод `logout`.
:::important
При выходе из аккаунта для пользователя создаётся новый анонимный профиль.
:::
```csharp showLineNumbers
Adapty.Logout((error) => {
if(error == null) {
// successful logout
}
});
```
:::info
Чтобы снова войти в приложение, используйте метод `identify`.
:::
### Разрешите покупки без входа в систему \{#allow-purchases-without-login\}
Если пользователи могут совершать покупки как до, так и после входа в приложение, нужно убедиться, что после авторизации они сохранят доступ к купленным возможностям:
1. Когда неавторизованный пользователь совершает покупку, Adapty привязывает её к анонимному идентификатору профиля.
2. Когда пользователь входит в аккаунт, Adapty переключается на работу с идентифицированным профилем.
- Если это новый customer user ID (например, покупка была совершена до регистрации), Adapty присваивает customer user ID текущему профилю, сохраняя всю историю покупок.
- Если это существующий customer user ID (customer user ID уже привязан к профилю), нужно получить актуальный уровень доступа после переключения профиля. Можно вызвать [`getProfile`](unity-check-subscription-status) сразу после идентификации или [подписаться на обновления профиля](unity-check-subscription-status), чтобы данные синхронизировались автоматически.
## Следующие шаги \{#next-steps\}
Поздравляем! Вы реализовали логику встроенных покупок в своём приложении! Желаем вам успехов в монетизации!
Чтобы получить от Adapty ещё больше, изучите эти темы:
- [**Тестирование**](troubleshooting-test-purchases): Убедитесь, что всё работает как ожидается
- [**Онбординги**](onboardings): Вовлекайте пользователей с помощью онбордингов и повышайте удержание
- [**Интеграции**](configuration): Интегрируйтесь с сервисами маркетинговой атрибуции и аналитики буквально в одну строку кода
- [**Установка пользовательских атрибутов профиля**](unity-setting-user-attributes): Добавляйте пользовательские атрибуты к профилям и создавайте сегменты, чтобы запускать A/B-тесты или показывать разные пейволы разным пользователям
---
# File: adapty-sdk-integration-skill-unity
---
---
title: "Интеграция Adapty в приложение Unity с помощью навыка SDK integration"
description: "Используйте навык adapty-sdk-integration для сквозной интеграции Adapty SDK в приложение Unity с помощью AI-инструмента для написания кода."
---
опциональный
по умолчанию: `en`
|Идентификатор [локализации пейвола](add-paywall-locale-in-adapty-paywall-builder). Ожидается языковой код, состоящий из одного или двух подтегов, разделённых символом минус (**-**). Первый подтег — язык, второй — регион.
Пример: `en` означает английский, `pt-br` — португальский (Бразилия).
Подробнее о кодах локалей и рекомендациях по их использованию — в разделе [Локализации и коды локалей](localizations-and-locale-codes).
| | **fetchPolicy** | по умолчанию: `.reloadRevalidatingCacheData` |По умолчанию SDK пытается загрузить данные с сервера и возвращает кешированные данные в случае ошибки. Мы рекомендуем этот вариант, так как он гарантирует, что пользователи всегда получают самые актуальные данные.
Однако если ваши пользователи часто сталкиваются с нестабильным интернетом, рассмотрите вариант `.returnCacheDataElseLoad` — он возвращает кешированные данные, если они есть. В этом случае пользователи могут получить не самые свежие данные, зато загрузка будет быстрее вне зависимости от качества соединения. Кеш регулярно обновляется, поэтому его безопасно использовать в течение сессии, чтобы избежать лишних сетевых запросов.
Обратите внимание: кеш сохраняется при перезапуске приложения и очищается только при его переустановке или ручной очистке.
Adapty SDK хранит пейволы локально в двух слоях: регулярно обновляемый кеш, описанный выше, и [резервные пейволы](fallback-paywalls). Для ускорения загрузки пейволов мы также используем CDN и отдельный резервный сервер на случай недоступности CDN. Эта система гарантирует, что вы всегда получаете актуальную версию пейволов, сохраняя надёжность даже при слабом интернет-соединении.
| | **loadTimeout** | по умолчанию: 5 сек |Ограничивает таймаут этого метода. При достижении таймаута будут возвращены кешированные данные или локальный резервный вариант.
Обратите внимание: в редких случаях метод может завершиться с небольшой задержкой относительно значения, указанного в `loadTimeout`, так как операция может включать несколько запросов под капотом.
| Параметры ответа: | Параметр | Описание | | :-------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------- | | Paywall | Объект [`AdaptyPaywall`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall.html) со списком ID продуктов, идентификатором пейвола, Remote Config и рядом других свойств. | ## Получение конфигурации отображения пейвола, созданного в Paywall Builder \{#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder\} :::important Убедитесь, что в Paywall Builder включён переключатель **Show on device**. Если этот параметр не активирован, конфигурация отображения не будет доступна для получения. ::: После загрузки пейвола проверьте, содержит ли он `ViewConfiguration` — это признак того, что пейвол создан в Paywall Builder. Это поможет вам понять, как отображать пейвол. Если `ViewConfiguration` присутствует, обрабатывайте его как пейвол Paywall Builder; если нет — [обработайте его как пейвол с Remote Config](present-remote-config-paywalls-unity). В Unity SDK напрямую вызывайте метод `CreatePaywallView`, не запрашивая конфигурацию вью вручную. :::warning Результат метода `CreatePaywallView` можно использовать только один раз. Если нужно использовать его повторно, вызовите `CreatePaywallView` заново. Повторный вызов без пересоздания может привести к ошибке `AdaptyUIError.viewAlreadyPresented`. ::: ```csharp showLineNumbers var parameters = new AdaptyUICreatePaywallViewParameters() .SetPreloadProducts(preloadProducts) .SetLoadTimeout(new TimeSpan(0, 0, 3)); AdaptyUI.CreatePaywallView(paywall, parameters, (view, error) => { // handle the result }); ``` Параметры: | Параметр | Наличие | Описание | | :------------------ | :------------------ | :----------------------------------------------------------- | | **paywall** | обязательный | Объект `AdaptyPaywall` для получения контроллера нужного пейвола. | | **loadTimeout** | по умолчанию: 5 сек | Ограничивает таймаут для этого метода. Если таймаут истёк, будут возвращены кешированные данные или локальный резервный пейвол. Обратите внимание, что в редких случаях метод может завершиться с небольшой задержкой сверх значения `loadTimeout`, поскольку операция может включать несколько запросов под капотом. | | **PreloadProducts** | опциональный | Передайте массив `AdaptyPaywallProducts` для оптимизации времени отображения продуктов на экране. Если передать `nil`, AdaptyUI автоматически загрузит необходимые продукты. | | **CustomTags** | опциональный | Задайте словарь пользовательских тегов и их значений. Пользовательские теги служат плейсхолдерами в контенте пейвола и динамически заменяются конкретными строками для персонализации. Подробнее см. в разделе о пользовательских тегах в Paywall Builder. | | **CustomTimers** | опциональный | Задайте словарь пользовательских таймеров и дат их окончания. Пользовательские таймеры позволяют отображать обратный отсчёт на пейволе. | :::note Если вы используете несколько языков, узнайте, как добавить [локализацию Paywall Builder](add-paywall-locale-in-adapty-paywall-builder) и как правильно использовать коды локалей [здесь](localizations-and-locale-codes). ::: Как только у вас есть представление, [покажите пейвол](unity-present-paywalls). ## Настройка ассетов \{#customize-assets\} Чтобы настроить изображения и видео на пейволе, используйте кастомные ассеты. Hero-изображения и видео имеют предопределённые идентификаторы: `hero_image` и `hero_video`. В бандле кастомных ассетов вы обращаетесь к этим элементам по их идентификаторам и настраиваете их поведение. Для остальных изображений и видео нужно [задать кастомный идентификатор](custom-media) в дашборде Adapty. Например, вы можете: - Показывать разные изображения или видео разным пользователям. - Показывать локальное превью-изображение, пока загружается основное удалённое. - Показывать превью-изображение перед запуском видео. :::important Чтобы использовать эту функцию, обновите Adapty Unity SDK до версии 3.8.0 или выше. ::: Вот пример того, как можно передавать пользовательские ресурсы через простой словарь: ```csharp showLineNumbers var customAssets = new Dictionaryопциональный
по умолчанию: `en`
|Идентификатор локализации пейвола. Ожидается языковой код, состоящий из одного или двух подтегов, разделённых символом минуса (**-**). Первый подтег — язык, второй — регион.
Пример: `en` означает английский, `pt-br` — бразильский португальский.
| | **fetchPolicy** | по умолчанию: `.reloadRevalidatingCacheData` |По умолчанию SDK пытается загрузить данные с сервера и возвращает кешированные данные в случае ошибки. Мы рекомендуем этот вариант: он гарантирует, что пользователи всегда получают актуальные данные.
Однако если у ваших пользователей нестабильное интернет-соединение, рассмотрите использование `.returnCacheDataElseLoad` — этот режим возвращает кешированные данные, если они есть. В таком случае данные могут быть не самыми свежими, зато загрузка будет быстрее независимо от качества соединения. Кеш регулярно обновляется, поэтому его безопасно использовать в течение сессии, чтобы сократить количество сетевых запросов.
Обратите внимание: кеш сохраняется при перезапуске приложения и очищается только при его переустановке или принудительной очистке.
Adapty SDK хранит пейволы локально в двух слоях: регулярно обновляемый кеш, описанный выше, и резервные пейволы. Для более быстрой загрузки пейволов также используется CDN, а на случай его недоступности — отдельный резервный сервер. Такая система гарантирует, что вы всегда получаете актуальную версию пейволов, обеспечивая надёжность даже при плохом интернет-соединении.
| --- # File: unity-present-paywalls --- --- title: "Отображение пейволов" description: "Узнайте, как отображать пейволы в приложении Unity с помощью Adapty SDK." --- Если вы настроили пейвол с помощью Paywall Builder, вам не нужно беспокоиться о его рендеринге в коде мобильного приложения для отображения пользователю. Такой пейвол содержит как то, что должно быть показано, так и то, как именно это должно быть показано. :::warning Этот гайд охватывает **новый Paywall Builder**, который требует Adapty SDK версии 3.3.0 или выше. Чтобы отображать пейволы на Remote Config, см. [Рендеринг пейволов, созданных с помощью Remote Config](present-remote-config-paywalls). ::: Чтобы отобразить пейвол, используйте метод `view.Present()` для объекта `view`, созданного методом [`CreatePaywallView`](unity-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder). Каждый объект `view` можно использовать только один раз. Если нужно показать пейвол снова, вызовите `CreatePaywallView` ещё раз, чтобы создать новый экземпляр `view`. :::warning Повторное использование одного и того же `view` без его пересоздания может привести к ошибке `AdaptyUIError.viewAlreadyPresented`. ::: ```csharp showLineNumbers title="Unity" view.Present((error) => { // handle the error }); ``` :::tip Хотите увидеть реальный пример интеграции Adapty SDK в мобильное приложение? Посмотрите наши [примеры приложений](sample-apps) — они демонстрируют полную настройку: отображение пейволов, совершение покупок и другие базовые функции. ::: ## Показ диалога \{#show-dialog\} Используйте этот метод вместо стандартных диалоговых окон, когда на Android отображается пейвол. На Android обычные алерты появляются позади пейвола и становятся невидимы для пользователей. Этот метод гарантирует корректное отображение диалога поверх пейвола на всех платформах. ```csharp showLineNumbers title="Unity" var dialog = new AdaptyUIDialogConfiguration() .SetTitle("Close paywall?") .SetContent("You will lose access to exclusive offers.") .SetDefaultActionTitle("Stay") .SetSecondaryActionTitle("Close"); AdaptyUI.ShowDialog(view, dialog, (action, error) => { if (error == null) { if (action == AdaptyUIDialogActionType.Secondary) { // User confirmed - close the paywall view.Dismiss(); } // If primary - do nothing, user stays } }); ``` ## Настройка стиля презентации на iOS \{#configure-ios-presentation-style\} Настройте способ отображения пейвола на iOS, передав параметр `iosPresentationStyle` в метод `Present()`. Параметр принимает значения `AdaptyUIIOSPresentationStyle.FullScreen` (по умолчанию) или `AdaptyUIIOSPresentationStyle.PageSheet`. ```csharp showLineNumbers title="Unity" view.Present(AdaptyUIIOSPresentationStyle.PageSheet, (error) => { // handle the error }); ``` --- # File: unity-handle-paywall-actions --- --- title: "Реагирование на действия кнопок в Unity SDK" description: "Обрабатывайте действия кнопок пейвола в Unity с помощью Adapty для лучшей монетизации приложения." --- Если вы создаёте пейволы с помощью Paywall Builder, важно правильно настроить кнопки: 1. Добавьте [кнопку в Paywall Builder](paywall-buttons) и назначьте ей готовое действие или создайте собственный ID действия. 2. Напишите код в приложении для обработки каждого назначенного действия. В этом гайде показано, как обрабатывать пользовательские и стандартные действия в коде. :::warning **Только покупки и восстановления обрабатываются автоматически.** Все остальные действия кнопок — закрытие пейволов, открытие ссылок и т. д. — требуют реализации обработчиков в коде приложения. ::: ## Закрытие пейволов \{#close-paywalls\} Чтобы добавить кнопку, закрывающую пейвол: 1. В Paywall Builder добавьте кнопку и назначьте ей действие **Close**. 2. В коде приложения реализуйте обработчик действия `close`, который скрывает пейвол. ```csharp showLineNumbers title="Unity" public void PaywallViewDidPerformAction( AdaptyUIPaywallView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Close: view.Dismiss(null); break; default: // handle other events break; } } ``` ## Открытие URL из пейволов \{#open-urls-from-paywalls\} :::tip Если вы хотите добавить группу ссылок (например, пользовательское соглашение и восстановление покупок), добавьте элемент **Link** в Paywall Builder и обработайте его так же, как кнопки с действием **Open URL**. ::: Чтобы добавить кнопку, открывающую ссылку из пейвола (например, **Terms of use** или **Privacy policy**): 1. В Paywall Builder добавьте кнопку, назначьте ей действие **Open URL** и введите нужный URL. 2. В коде приложения реализуйте обработчик действия `openUrl`, который открывает полученный URL в браузере. ```csharp showLineNumbers title="Unity" public void PaywallViewDidPerformAction( AdaptyUIPaywallView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.OpenUrl: var urlString = action.Value; if(!string.IsNullOrWhiteSpace(urlString)) { Application.OpenURL(urlString); } break; default: // handle other events break; } } ``` ## Вход в приложение \{#log-into-the-app\} Чтобы добавить кнопку, которая выполняет вход пользователя в приложение: 1. В Paywall Builder добавьте кнопку и назначьте ей действие **Custom** с ID `login`. 2. В коде приложения реализуйте обработчик пользовательского действия `login`, который идентифицирует пользователя. ```csharp showLineNumbers title="Unity" public void PaywallViewDidPerformAction( AdaptyUIPaywallView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Custom: if (action.Value == "login") { // Navigate to login scene SceneManager.LoadScene("LoginScene"); } break; default: // handle other events break; } } ``` ## Обработка пользовательских действий \{#handle-custom-actions\} Чтобы добавить кнопку для обработки любых других действий: 1. В Paywall Builder добавьте кнопку, назначьте ей действие **Custom** и задайте ID. 2. В коде приложения реализуйте обработчик созданного ID действия. Например, если у вас есть другой набор предложений по подпискам или разовых покупок, можно добавить кнопку, которая будет отображать другой пейвол: ```csharp showLineNumbers title="Unity" public void PaywallViewDidPerformAction( AdaptyUIPaywallView view, AdaptyUIUserAction action ) { switch (action.Type) { case AdaptyUIUserActionType.Custom: if (action.Value == "openNewPaywall") { // Display another paywall ShowAlternativePaywall(); } break; default: // handle other events break; } } private void ShowAlternativePaywall() { // Implement your logic to show alternative paywall } ``` --- # File: unity-handling-events --- --- title: "Обработка событий пейвола" description: "Узнайте, как обрабатывать события пейвола в Unity-приложении с помощью Adapty SDK." --- :::important Этот гайд охватывает обработку событий для покупок, восстановлений, выбора продуктов и отрисовки пейвола. Также необходимо реализовать обработку кнопок (закрытие пейвола, открытие ссылок и т. д.). Подробнее см. в нашем [гайде по обработке действий с кнопками](unity-handle-paywall-actions). ::: Пейволы, настроенные с помощью [Paywall Builder](adapty-paywall-builder), не требуют дополнительного кода для совершения и восстановления покупок. Однако они генерируют ряд событий, на которые ваше приложение может реагировать. Это нажатия кнопок (кнопки закрытия, URL-адреса, выбор продуктов и т. д.), а также уведомления о действиях, связанных с покупками на пейволе. Узнайте, как реагировать на эти события, ниже. :::warning Этот гайд предназначен **только для пейволов нового Paywall Builder**, которые требуют Adapty SDK версии 3.3.0 или выше. ::: :::tip Хотите увидеть реальный пример интеграции Adapty SDK в мобильное приложение? Посмотрите наши [примеры приложений](sample-apps) — они демонстрируют полную настройку: отображение пейволов, совершение покупок и другие базовые функции. ::: ## Обработка событий \{#handling-events\} Чтобы контролировать или отслеживать процессы, происходящие на экране пейвола в вашем мобильном приложении, реализуйте интерфейс `AdaptyPaywallsEventsListener`: ```csharp showLineNumbers title="Unity" using UnityEngine; using AdaptySDK; public class PaywallEventsHandler : MonoBehaviour, AdaptyPaywallsEventsListener { void Start() { Adapty.SetPaywallsEventsListener(this); } // Implement all required interface methods below } ``` ### События, инициируемые пользователем \{#user-generated-events\} #### Пейвол появился \{#paywall-appeared\} Вызывается, когда экран пейвола отображается на экране. :::note На iOS также вызывается, когда пользователь нажимает [кнопку веб-пейвола](web-paywall#step-2a-add-a-web-purchase-button) внутри пейвола и веб-пейвол открывается во встроенном браузере. ::: ```csharp showLineNumbers title="Unity" public void PaywallViewDidAppear(AdaptyUIPaywallView view) { } ``` #### Пейвол исчез \{#paywall-disappeared\} Вызывается, когда экран пейвола закрывается. :::note На iOS также вызывается, когда [веб-пейвол](web-paywall#step-2a-add-a-web-purchase-button), открытый из пейвола во встроенном браузере, исчезает с экрана. ::: ```csharp showLineNumbers title="Unity" public void PaywallViewDidDisappear(AdaptyUIPaywallView view) { } ``` #### Выбор продукта \{#product-selection\} Вызывается, когда продукт выбран для покупки (пользователем или системой). ```csharp showLineNumbers title="Unity" public void PaywallViewDidSelectProduct( AdaptyUIPaywallView view, string productId ) { } ```
## Слишком большое число просмотров пейвола \{#the-paywall-view-number-is-too-big\}
**Проблема**: Счётчик просмотров пейвола показывает вдвое больше ожидаемого значения.
**Причина**: Возможно, в вашем коде вызывается `LogShowPaywall`, что дублирует счётчик просмотров при использовании Paywall Builder. Для пейволов, созданных в Paywall Builder, аналитика отслеживается автоматически, поэтому использовать этот метод не нужно.
**Решение**: Убедитесь, что в вашем коде не вызывается `LogShowPaywall`, если вы используете Paywall Builder.
## Другие проблемы \{#other-issues\}
**Проблема**: Вы столкнулись с другими проблемами, связанными с Paywall Builder, которые не описаны выше.
**Решение**: При необходимости обновите SDK до последней версии с помощью [гайдов по миграции](unity-sdk-migration-guides). Многие проблемы устраняются в новых версиях SDK.
---
# File: unity-quickstart-manual
---
---
title: "Включение покупок в вашем кастомном пейволе в Unity SDK"
description: "Интегрируйте Adapty SDK в ваши кастомные пейволы Unity для включения встроенных покупок."
---
Этот гайд описывает, как интегрировать Adapty в ваши кастомные пейволы. Вы сохраняете полный контроль над реализацией пейвола, а SDK Adapty получает продукты, обрабатывает новые покупки и восстанавливает предыдущие.
:::important
**Этот гайд предназначен для разработчиков, которые реализуют кастомные пейволы.** Если вы хотите самый простой способ включить покупки, используйте [Adapty Paywall Builder](unity-quickstart-paywalls). С Paywall Builder вы создаёте пейволы в визуальном редакторе без написания кода, Adapty автоматически обрабатывает всю логику покупок, и вы можете тестировать разные дизайны без повторной публикации приложения.
:::
## Прежде чем начать \{#before-you-start\}
### Настройте продукты \{#set-up-products\}
Для включения встроенных покупок вам нужно понять три ключевых концепции:
- [**Продукты**](product) — всё, что пользователи могут купить (подписки, расходуемые покупки, пожизненный доступ)
- [**Пейволы**](paywalls) — конфигурации, определяющие, какие продукты предлагать. В Adapty пейволы — единственный способ получить продукты, но такой подход позволяет изменять продукты, цены и офферы без изменения кода приложения.
- [**Плейсменты**](placements) — где и когда вы показываете пейволы в приложении (например, `main`, `onboarding`, `settings`). Вы настраиваете пейволы для плейсментов в дашборде, затем запрашиваете их по ID плейсмента в коде. Это упрощает проведение A/B-тестов и показ разных пейволов разным пользователям.
Убедитесь, что вы понимаете эти концепции, даже если работаете с кастомным пейволом. По сути, это просто способ управлять продуктами, которые вы продаёте в приложении.
Для реализации кастомного пейвола вам нужно создать **пейвол** и добавить его в **плейсмент**. Эта настройка позволяет получать ваши продукты. Чтобы понять, что нужно сделать в дашборде, следуйте [быстрому старту здесь](quickstart).
### Управление пользователями \{#manage-users\}
Вы можете работать как с бэкенд-аутентификацией, так и без неё.
SDK Adapty по-разному обрабатывает анонимных и идентифицированных пользователей. Прочитайте [гайд по идентификации](unity-quickstart-identify), чтобы разобраться в особенностях и убедиться, что вы правильно работаете с пользователями.
## Шаг 1. Получите продукты \{#step-1-get-products\}
Чтобы получить продукты для вашего кастомного пейвола, необходимо:
1. Получить объект `paywall`, передав ID [плейсмента](placements) в метод `getPaywall`.
2. Получить массив продуктов для этого пейвола с помощью метода `getPaywallProducts`.
```csharp showLineNumbers
using AdaptySDK;
void LoadPaywall() {
Adapty.GetPaywall("YOUR_PLACEMENT_ID", (paywall, error) => {
if (error != null) {
// Handle the error
return;
}
Adapty.GetPaywallProducts(paywall, (products, productsError) => {
if (productsError != null) {
// Handle the error
return;
}
// Use products to build your custom paywall UI
});
});
}
```
## Шаг 2. Принимайте покупки \{#step-2-accept-purchases\}
Когда пользователь нажимает на продукт в вашем кастомном пейволе, вызовите метод `makePurchase` с выбранным продуктом. Это запустит процесс покупки и вернёт обновлённый профиль.
```csharp showLineNumbers
using AdaptySDK;
void PurchaseProduct(AdaptyPaywallProduct product) {
Adapty.MakePurchase(product, (result, error) => {
if (error != null) {
// Handle the error
return;
}
switch (result.Type) {
case AdaptyPurchaseResultType.Success:
var profile = result.Profile;
// Purchase successful, profile updated
break;
case AdaptyPurchaseResultType.UserCancelled:
// User canceled the purchase
break;
case AdaptyPurchaseResultType.Pending:
// Purchase is pending (e.g., user will pay offline with cash)
break;
}
});
}
```
## Шаг 3. Восстановите покупки \{#step-3-restore-purchases\}
Сторы требуют, чтобы все приложения с подписками предоставляли пользователям возможность восстановить покупки.
Вызовите метод `restorePurchases`, когда пользователь нажимает кнопку восстановления. Это синхронизирует историю покупок с Adapty и вернёт обновлённый профиль.
```csharp showLineNumbers
using AdaptySDK;
void RestorePurchases() {
Adapty.RestorePurchases((profile, error) => {
if (error != null) {
// Handle the error
return;
}
// Restore successful, profile updated
});
}
```
## Следующие шаги \{#next-steps\}
:::tip
Есть вопросы или возникли проблемы? Загляните на наш [форум поддержки](https://adapty.featurebase.app/), где можно найти ответы на распространённые вопросы или задать свой. Наша команда и сообщество всегда готовы помочь!
:::
Ваш пейвол готов к отображению в приложении. Протестируйте покупки в [песочнице App Store](test-purchases-in-sandbox) или в [Google Play Store](testing-on-android), чтобы убедиться, что вы можете совершить тестовую покупку через пейвол.
Далее [проверьте, завершили ли пользователи покупку](unity-check-subscription-status), чтобы решить, показывать ли пейвол или предоставить доступ к платным функциям.
---
# File: fetch-paywalls-and-products-unity
---
---
title: "Получение пейволов и продуктов для пейволов с Remote Config в Unity SDK"
description: "Получайте пейволы и продукты в Adapty Unity SDK для улучшения монетизации пользователей."
---
Прежде чем отображать Remote Config и кастомные пейволы, нужно получить информацию о них. Обратите внимание, что этот раздел посвящён Remote Config и кастомным пейволам. Для получения пейволов, настроенных в Paywall Builder, смотрите [Получение пейволов Paywall Builder и их конфигурации](unity-get-pb-paywalls).
:::tip
Хотите увидеть реальный пример интеграции Adapty SDK в мобильное приложение? Посмотрите наши [примеры приложений](sample-apps) — они демонстрируют полную настройку: отображение пейволов, совершение покупок и другие базовые функции.
:::
опциональный
по умолчанию: `en`
|Идентификатор [локализации пейвола](add-remote-config-locale). Ожидается код языка, состоящий из одного или нескольких подтегов, разделённых символом минус (**-**). Первый подтег обозначает язык, второй — регион.
Например: `en` — английский, `pt-br` — бразильский португальский.
Подробнее о кодах локалей и рекомендуемых подходах к их использованию — в разделе [Локализации и коды локалей](unity-localizations-and-locale-codes).
| | **fetchPolicy** | по умолчанию: `.reloadRevalidatingCacheData` |По умолчанию SDK пытается загрузить данные с сервера и возвращает кешированные данные в случае сбоя. Мы рекомендуем этот вариант, поскольку он гарантирует, что пользователи всегда получают актуальные данные.
Однако если ваши пользователи часто сталкиваются с нестабильным интернет-соединением, рассмотрите использование `.returnCacheDataElseLoad` — этот режим возвращает кешированные данные, если они есть. В таком сценарии пользователи могут получать не самые свежие данные, зато загрузка будет быстрее независимо от качества соединения. Кеш регулярно обновляется, поэтому его безопасно использовать в рамках сессии для снижения количества сетевых запросов.
Обратите внимание: кеш сохраняется при перезапуске приложения и очищается только при его переустановке или вручную.
Adapty SDK хранит пейволы на двух уровнях: регулярно обновляемый кеш, описанный выше, и [резервные пейволы](unity-use-fallback-paywalls). Также используется CDN для более быстрой загрузки пейволов и отдельный резервный сервер на случай недоступности CDN. Такая система гарантирует, что вы всегда получаете актуальную версию пейволов, обеспечивая надёжность даже при слабом интернете.
| | **loadTimeout** | по умолчанию: 5 сек |Ограничивает время ожидания для данного метода. По истечении таймаута будут возвращены кешированные данные или локальный резервный вариант.
Обратите внимание: в редких случаях метод может завершиться с небольшой задержкой сверх значения, указанного в `loadTimeout`, так как операция может включать несколько запросов под капотом.
| Не задавайте ID продуктов жёстко в коде! Поскольку пейволы настраиваются удалённо, набор доступных продуктов, их количество и специальные предложения (например, бесплатные пробные периоды) могут меняться со временем. Убедитесь, что ваш код учитывает эти сценарии. Например, если изначально вы получаете 2 продукта, приложение должно отображать именно 2 продукта. Но если позднее вы получите 3 продукта, приложение должно показать все 3 без каких-либо изменений в коде. Единственное, что нужно задать жёстко, — это ID плейсмента. Параметры ответа: | Параметр | Описание | | :-------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | | Paywall | Объект [`AdaptyPaywall`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall.html) со списком идентификаторов продуктов, идентификатором пейвола, Remote Config и рядом других свойств. | ## Получение продуктов \{#fetch-products\} Получив пейвол, вы можете запросить массив продуктов, соответствующих ему: ```csharp showLineNumbers Adapty.GetPaywallProducts(paywall, (products, error) => { if(error != null) { // handle the error return; } // products - the requested products array }); ``` Параметры ответа: | Параметр | Описание | | :-------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Products | Список объектов [`AdaptyPaywallProduct`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall_product.html) с: идентификатором продукта, названием продукта, ценой, валютой, длительностью подписки и рядом других свойств. | При реализации собственного дизайна пейвола вам, скорее всего, понадобятся свойства объекта [`AdaptyPaywallProduct`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall_product.html). Ниже приведены наиболее часто используемые из них, полный список доступных свойств смотрите в документации по ссылке. | Свойство | Описание | |-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Title** | Чтобы отобразить название продукта, используйте `product.LocalizedTitle`. Обратите внимание: локализация зависит от выбранной пользователем страны стора, а не от локали устройства. | | **Price** | Чтобы отобразить цену в локализованном формате, используйте `product.Price.LocalizedString`. Локализация основана на локали устройства. Цену в числовом виде можно получить через `product.Price.Amount` — значение будет в местной валюте. Символ валюты доступен через `product.Price.CurrencySymbol`. | | **Subscription Period** | Чтобы отобразить период подписки (например, неделя, месяц, год и т. д.), используйте `product.Subscription?.LocalizedPeriod`. Локализация основана на локали устройства. Для программного получения периода подписки используйте `product.Subscription?.Period`. Через это свойство доступен enum `Unit` со значениями `AdaptySubscriptionPeriodUnit.Day`, `AdaptySubscriptionPeriodUnit.Week`, `AdaptySubscriptionPeriodUnit.Month`, `AdaptySubscriptionPeriodUnit.Year` и `AdaptySubscriptionPeriodUnit.Unknown`. Значение `NumberOfUnits` содержит количество единиц периода. Например, для квартальной подписки в свойстве `Unit` будет `AdaptySubscriptionPeriodUnit.Month`, а в `NumberOfUnits` — `3`. | | **Introductory Offer** | Чтобы отобразить бейдж или другой индикатор наличия introductory offer в подписке, проверьте свойство `product.Subscription?.Offer?.Phases`. Это список, который может содержать до двух фаз скидки: фазу бесплатного пробного периода и фазу вводной цены. Каждый объект фазы содержит следующие полезные свойства:необязательный
по умолчанию: `en`
|Идентификатор локализации пейвола. Ожидается языковой код, состоящий из одного или двух подтегов, разделённых символом минус (**-**). Первый подтег обозначает язык, второй — регион.
Например: `en` — английский, `pt-br` — бразильский португальский.
| | **fetchPolicy** | по умолчанию: `.reloadRevalidatingCacheData` |По умолчанию SDK пытается загрузить данные с сервера и возвращает кэшированные данные в случае сбоя. Мы рекомендуем этот вариант — он гарантирует, что пользователи всегда получают актуальные данные.
Однако если у ваших пользователей нестабильное интернет-соединение, рассмотрите использование `.returnCacheDataElseLoad`: оно возвращает кэшированные данные, если они есть. В этом случае пользователи могут не получить самые последние данные, но загрузка будет быстрее независимо от качества соединения. Кэш регулярно обновляется, поэтому его безопасно использовать в течение сессии, чтобы избежать лишних сетевых запросов.
Обратите внимание: кэш сохраняется при перезапуске приложения и очищается только при его переустановке или вручную.
Adapty SDK хранит пейволы локально на двух уровнях: регулярно обновляемый кэш, описанный выше, и резервные пейволы. Для более быстрой загрузки пейволов мы также используем CDN и отдельный резервный сервер на случай недоступности CDN. Такая система гарантирует, что вы всегда получаете последнюю версию пейволов, обеспечивая надёжность даже при нестабильном интернет-соединении.
| --- # File: present-remote-config-paywalls-unity --- --- title: "Отображение пейвола, настроенного через Remote Config, в Unity SDK" description: "Узнайте, как отображать пейволы на основе Remote Config в Adapty Unity SDK для персонализации пользовательского опыта." --- Если вы настроили пейвол с помощью Remote Config, вам потребуется реализовать его отображение в коде мобильного приложения. Поскольку Remote Config гибко адаптируется под ваши нужды, вы сами решаете, что включать в пейвол и как он будет выглядеть. Мы предоставляем метод для получения Remote Config, а дальнейшее отображение пейвола остаётся за вами. ## Получение Remote Config пейвола и его отображение \{#get-paywall-remote-config-and-present-it\} Чтобы получить Remote Config пейвола, обратитесь к свойству `remoteConfig` и извлеките нужные значения. ```csharp showLineNumbers Adapty.GetPaywall("YOUR_PLACEMENT_ID", (paywall, error) => { if (error != null) { // handle the error return; } // Access remote config dictionary var dictionary = paywall.RemoteConfig?.Dictionary; var headerText = dictionary?["header_text"] as string; // Or access raw JSON data var jsonData = paywall.RemoteConfig?.Data; }); ``` Получив все необходимые значения, приступайте к отрисовке и сборке пейвола. Убедитесь, что дизайн адаптируется под разные экраны и ориентации устройств — это обеспечит удобный пользовательский опыт на любом устройстве. :::warning Не забудьте [зафиксировать событие просмотра пейвола](present-remote-config-paywalls-unity#track-paywall-view-events), как описано ниже — это позволит аналитике Adapty собирать данные для воронок и A/B-тестов. ::: После отображения пейвола настройте процесс покупки. Когда пользователь совершает покупку, вызовите `.MakePurchase()` с продуктом из вашего пейвола. Подробнее о методе `.MakePurchase()` читайте в разделе [Совершение покупок](unity-making-purchases). Рекомендуем также [создать резервный пейвол (fallback paywall)](unity-use-fallback-paywalls). Он будет отображаться пользователю при отсутствии интернета или кеша, обеспечивая бесперебойную работу приложения в таких ситуациях. ## Отслеживание событий просмотра пейвола \{#track-paywall-view-events\} Adapty помогает измерять эффективность ваших пейволов. Данные о покупках мы собираем автоматически, а вот просмотры пейволов нужно логировать вручную — только вы знаете, когда пользователь видит пейвол. Чтобы зафиксировать событие просмотра, вызовите `.LogShowPaywall(paywall)` — это отразится в метриках пейвола в воронках и A/B-тестах. :::important Вызов `.LogShowPaywall(paywall)` не требуется, если вы отображаете пейволы, созданные в [Paywall Builder](adapty-paywall-builder). ::: ```csharp showLineNumbers Adapty.LogShowPaywall(paywall, (error) => { // handle the error }); ``` Параметры запроса: | Параметр | Обязательный | Описание | | :---------- | :----------- |:------------------------------------------------------------------| | **paywall** | да | Объект [`AdaptyPaywall`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall.html). | --- # File: unity-making-purchases --- --- title: "Совершение покупок в мобильном приложении с Unity SDK" description: "Гайд по обработке встроенных покупок и подписок с помощью Adapty." --- Отображение пейволов в мобильном приложении — обязательный шаг для предоставления пользователям доступа к премиум-контенту или сервисам. Однако просто показать пейвол достаточно для поддержки покупок только в том случае, если вы используете [Paywall Builder](adapty-paywall-builder) для его настройки. Если вы не используете Paywall Builder, для совершения покупки и открытия нужного контента необходимо вызвать отдельный метод `.makePurchase()`. Именно через него пользователи взаимодействуют с пейволами и выполняют нужные транзакции. Если на вашем пейволе настроен активный promotional offer для продукта, который пользователь хочет купить, Adapty автоматически применит его в момент покупки. :::warning Обратите внимание: introductory offer применяется автоматически только при использовании пейволов, созданных с помощью Paywall Builder. В других случаях вам потребуется [проверить право пользователя на introductory offer в iOS](fetch-paywalls-and-products#check-intro-offer-eligibility-on-ios). Пропуск этого шага может привести к отклонению приложения при релизе. Кроме того, пользователям, которым положен introductory offer, может быть выставлена полная цена. ::: Убедитесь, что вы [выполнили начальную настройку](quickstart), не пропустив ни одного шага. Без неё мы не сможем валидировать покупки. ## Совершение покупки \{#make-purchase\} :::note **Используете [Paywall Builder](adapty-paywall-builder)?** Покупки обрабатываются автоматически — этот шаг можно пропустить. **Нужна пошаговая инструкция?** Ознакомьтесь с [гайдом по быстрому старту](unity-implement-paywalls-manually) — там есть полное руководство по реализации с подробным контекстом. ::: ```csharp showLineNumbers using AdaptySDK; void MakePurchase(AdaptyPaywallProduct product) { Adapty.MakePurchase(product, (result, error) => { switch (result.Type) { case AdaptyPurchaseResultType.Pending: // handle pending purchase break; case AdaptyPurchaseResultType.UserCancelled: // handle purchase cancellation break; case AdaptyPurchaseResultType.Success: var profile = result.Profile; // handle successfull purchase break; default: break; } }); } ``` Параметры запроса: | Параметр | Наличие | Описание | | :---------- | :------- |:------------------------------------------------------------------------------------------------------| | **Product** | обязательный | Объект [`AdaptyPaywallProduct`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall_product.html), полученный из пейвола. | Параметры ответа: | Параметр | Описание | |---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **Profile** |При успешном запросе ответ содержит этот объект. Объект [AdaptyProfile](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_profile.html) предоставляет исчерпывающую информацию об уровнях доступа пользователя, подписках и разовых покупках в приложении.
Проверьте статус уровня доступа, чтобы убедиться, что у пользователя есть необходимый доступ к приложению.
| :::warning **Примечание:** если вы используете Apple StoreKit версии ниже 2.0 и Adapty SDK версии ниже v2.9.0, вам необходимо указать [общий секрет App Store](app-store-connection-configuration#step-5-enter-app-store-shared-secret). Этот метод в настоящее время устарел и не рекомендован Apple. ::: ## Смена подписки при покупке \{#change-subscription-when-making-a-purchase\} Когда пользователь выбирает новую подписку вместо продления текущей, поведение зависит от стора: - В App Store подписка обновляется автоматически в рамках группы подписок. Если пользователь покупает подписку из одной группы, уже имея активную из другой, обе подписки будут действовать одновременно. - В Google Play подписка не обновляется автоматически. Переключение нужно реализовать в коде приложения, как описано ниже. Чтобы заменить подписку на другую в Android, вызовите метод `.makePurchase()` с дополнительным параметром: ```csharp showLineNumbers // Create subscription update parameters var subscriptionUpdateParams = new AdaptySubscriptionUpdateParameters( "old_product_id", // Product ID of the current subscription AdaptySubscriptionUpdateReplacementMode.WithTimeProration ); Adapty.MakePurchase(product, subscriptionUpdateParams, (profile, error) => { if(error != null) { // Handle the error return; } // successful cross-grade }); ``` Дополнительный параметр запроса: | Параметр | Наличие | Описание | | :--------------------------- | :------- |:-------------------------------------------------------------------------------------------------------| | **subscriptionUpdateParams** | обязателен | объект [`AdaptySubscriptionUpdateParameters`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_subscription_update_parameters.html). | Подробнее о подписках и режимах замены читайте в документации Google Developer: - [О режимах замены](https://developer.android.com/google/play/billing/subscriptions#replacement-modes) - [Рекомендации Google по режимам замены](https://developer.android.com/google/play/billing/subscriptions#replacement-recommendations) - Режим замены [`CHARGE_PRORATED_PRICE`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode#CHARGE_PRORATED_PRICE()). Примечание: этот метод доступен только для апгрейда подписки. Даунгрейд не поддерживается. - Режим замены [`DEFERRED`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode#DEFERRED()). Примечание: фактическая смена подписки произойдёт только по окончании текущего расчётного периода. ## Активация промокодов в iOS \{#redeem-offer-codes-in-ios\}Объект [`AdaptyProfile`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_profile.html). Модель содержит информацию об уровнях доступа, подписках и разовых покупках.
Проверьте **статус уровня доступа**, чтобы определить, есть ли у пользователя доступ к приложению.
| :::tip Хотите увидеть реальный пример интеграции Adapty SDK в мобильное приложение? Посмотрите наши [примеры приложений](sample-apps) — они демонстрируют полную настройку: отображение пейволов, совершение покупок и другие базовые функции. ::: --- # File: implement-observer-mode-unity --- --- title: "Реализация режима Observer в Unity SDK" description: "Реализуйте режим Observer в Adapty для отслеживания событий подписки пользователей в Unity SDK." --- Если у вас уже есть собственная инфраструктура покупок и вы не готовы полностью переходить на Adapty, вы можете воспользоваться [режимом Observer](observer-vs-full-mode). В базовом варианте режим Observer обеспечивает расширенную аналитику и бесшовную интеграцию с системами атрибуции и аналитики. Если это соответствует вашим потребностям, вам нужно только: 1. Включить его при настройке Adapty SDK, установив параметр `observerMode` в значение `true`. Следуйте инструкциям по настройке для [Unity](sdk-installation-unity#activate-adapty-module-of-adapty-sdk). 2. [Передавать транзакции](report-transactions-observer-mode-unity) из вашей существующей инфраструктуры покупок в Adapty. ### Настройка режима Observer \{#observer-mode-setup\} Включите режим Observer, если вы самостоятельно обрабатываете покупки и управляете статусом подписки, а Adapty используете для отправки событий подписки и аналитики. :::important В режиме Observer Adapty SDK не закрывает транзакции, поэтому убедитесь, что вы обрабатываете их самостоятельно. ::: ```csharp showLineNumbers title="C#" using UnityEngine; using AdaptySDK; public class AdaptyListener : MonoBehaviour, AdaptyEventListener { void Start() { DontDestroyOnLoad(this.gameObject); Adapty.SetEventListener(this); var builder = new AdaptyConfiguration.Builder("YOUR_PUBLIC_SDK_KEY") .SetObserverMode(true); // Enable observer mode Adapty.Activate(builder.Build(), (error) => { if (error != null) { // handle the error return; } }); } public void OnLoadLatestProfile(AdaptyProfile profile) { } public void OnInstallationDetailsSuccess(AdaptyInstallationDetails details) { } public void OnInstallationDetailsFail(AdaptyError error) { } } ``` Параметры: | Параметр | Описание | |--------------|---------------------------------------------------------------------------------------------------------------| | observerMode | Булево значение, управляющее [режимом Observer](observer-vs-full-mode). Значение по умолчанию — `false`. | ## Использование пейволов Adapty в режиме Observer \{#using-adapty-paywalls-in-observer-mode\} Если вы также хотите использовать пейволы и функции A/B-тестирования Adapty — это возможно, но потребует дополнительной настройки в режиме Observer. Помимо шагов выше, вам нужно будет: 1. Отображать пейволы как обычно для [пейволов на Remote Config](present-remote-config-paywalls-unity). 3. [Связать пейволы](report-transactions-observer-mode-unity) с транзакциями покупок. --- # File: report-transactions-observer-mode-unity --- --- title: "Отчёт о транзакциях в Observer Mode в Unity SDK" description: "Сообщайте о транзакциях покупок в Observer Mode Adapty для отслеживания пользовательских данных и дохода в Unity SDK." ---Для iOS, StoreKit 1: объект [SKPaymentTransaction](https://developer.apple.com/documentation/storekit/skpaymenttransaction).
Для iOS, StoreKit 2: объект [Transaction](https://developer.apple.com/documentation/storekit/transaction).
Для Android: строковый идентификатор (purchase.getOrderId покупки, где покупка — экземпляр класса [Purchase](https://developer.android.com/reference/com/android/billingclient/api/Purchase) из библиотеки биллинга.
| | variationId | обязательный | Строковый идентификатор варианта. Его можно получить через свойство `variationId` объекта [AdaptyPaywall](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_paywall.html). |phoneNumber
firstName
lastName
| String | | gender | Enum, допустимые значения: `female`, `male`, `other` | | birthday | Date | ### Пользовательские атрибуты \{#custom-user-attributes\} Вы можете задавать собственные атрибуты, связанные с использованием приложения. Например, для фитнес-приложений это может быть количество тренировок в неделю, для приложений по изучению языков — уровень знаний пользователя и т. д. Атрибуты можно применять в сегментах для создания персонализированных пейволов и предложений, а также в аналитике — чтобы понять, какие продуктовые метрики сильнее всего влияют на выручку. ```csharp showLineNumbers try { builder = builder.SetCustomStringAttribute("string_key", "string_value"); builder = builder.SetCustomDoubleAttribute("double_key", 123.0f); } catch (Exception e) { // handle the exception } ``` Чтобы удалить существующий ключ, используйте метод `.withRemoved(customAttributeForKey:)`: ```csharp showLineNumbers try { builder = builder.RemoveCustomAttribute("key_to_remove"); } catch (Exception e) { // handle the exception } ``` Иногда нужно узнать, какие пользовательские атрибуты уже установлены. Для этого используйте поле `customAttributes` объекта `AdaptyProfile`. :::warning Имейте в виду, что значение `customAttributes` может быть устаревшим: атрибуты пользователя могут отправляться с разных устройств в любое время, поэтому данные на сервере могут измениться после последней синхронизации. ::: ### Ограничения \{#limits\} - До 30 пользовательских атрибутов на одного пользователя. - Длина имени ключа — до 30 символов. Допустимые символы: буквы, цифры, а также `_`, `-`, `.`. - Значение может быть строкой или числом с плавающей точкой длиной не более 50 символов. --- # File: unity-listen-subscription-changes --- --- title: "Проверка статуса подписки в Unity SDK" description: "Отслеживайте и управляйте статусом подписки пользователей в Adapty для повышения удержания клиентов в вашем Unity-приложении." --- С Adapty отслеживать статус подписки очень просто. Не нужно вручную прописывать идентификаторы продуктов в коде — достаточно проверить наличие активного [уровня доступа](access-level), чтобы узнать, есть ли у пользователя активная подписка.Объект [AdaptyProfile](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_profile.html). Как правило, для определения доступа к премиум-функциям достаточно проверить статус уровня доступа профиля.
Метод `.getProfile` всегда пытается обратиться к API и возвращает наиболее актуальные данные. Если по какой-то причине (например, при отсутствии интернета) Adapty SDK не может получить данные с сервера, возвращаются данные из кэша. Важно учитывать, что Adapty SDK регулярно обновляет кэш `AdaptyProfile`, чтобы поддерживать информацию в актуальном состоянии.
| Метод `.getProfile()` возвращает профиль пользователя, из которого можно получить статус уровня доступа. В приложении может быть несколько уровней доступа. Например, в газетном приложении с независимыми подписками на разные темы можно создать уровни доступа «sports» и «science». Но в большинстве случаев достаточно одного уровня доступа — тогда можно просто использовать уровень доступа "premium" по умолчанию. Пример проверки уровня доступа "premium" по умолчанию: ```csharp showLineNumbers Adapty.GetProfile((profile, error) => { if (error != null) { // handle the 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 } }); ``` ### Отслеживание обновлений статуса подписки \{#listening-for-subscription-status-updates\} При каждом изменении подписки пользователя Adapty генерирует событие. Чтобы получать сообщения от Adapty, необходимо выполнить дополнительную настройку: ```csharp showLineNumbers // Extend `AdaptyEventListener ` with `OnLoadLatestProfile ` method: public class AdaptyListener : MonoBehaviour, AdaptyEventListener { public void OnLoadLatestProfile(AdaptyProfile profile) { // handle any changes to subscription state } } ``` Adapty также генерирует событие при запуске приложения. В этом случае передаётся кэшированный статус подписки. ### Кэш статуса подписки \{#subscription-status-cache\} Кэш, реализованный в Adapty SDK, хранит статус подписки профиля. Это означает, что даже при недоступности сервера из кэша можно получить информацию о статусе подписки профиля. Однако важно учитывать, что напрямую запрашивать данные из кэша невозможно. SDK периодически обращается к серверу каждую минуту, чтобы проверить наличие обновлений профиля. При наличии изменений — например, новых транзакций или других обновлений — они записываются в кэш, чтобы он оставался синхронизированным с сервером. --- # File: unity-deal-with-att --- --- title: "Работа с ATT в Unity SDK" description: "Начните работу с Adapty на Unity для удобной настройки и управления подписками." --- Если ваше приложение использует фреймворк AppTrackingTransparency и запрашивает у пользователя разрешение на отслеживание, необходимо передать [статус авторизации](https://developer.apple.com/documentation/apptrackingtransparency/attrackingmanager/authorizationstatus/) в Adapty. ```csharp showLineNumbers var builder = new Adapty.ProfileParameters.Builder() .SetAppTrackingTransparencyStatus(IOSAppTrackingTransparencyStatus.Authorized); Adapty.UpdateProfile(builder.Build(), (error) => { if(error != null) { // handle the error } }); ``` :::warning Настоятельно рекомендуем передавать это значение как можно раньше при каждом его изменении — только тогда данные будут своевременно отправлены в настроенные вами интеграции. ::: --- # File: kids-mode-unity --- --- title: "Режим для детей в Unity SDK" description: "Легко включите режим для детей, чтобы соответствовать политикам Apple и Google. В Unity SDK не собираются IDFA, GAID или рекламные данные." --- Если ваше Unity-приложение предназначено для детей, вы обязаны соблюдать политики [Apple](https://developer.apple.com/kids/) и [Google](https://support.google.com/googleplay/android-developer/answer/9893335). Если вы используете Adapty SDK, несколько простых шагов помогут настроить его в соответствии с этими политиками и пройти проверку в сторах. ## Что нужно сделать? \{#whats-required\} Необходимо настроить Adapty SDK так, чтобы отключить сбор следующих данных: - [IDFA (Identifier for Advertisers)](https://en.wikipedia.org/wiki/Identifier_for_Advertisers) (iOS) - [Android Advertising ID (AAID/GAID)](https://support.google.com/googleplay/android-developer/answer/6048248) (Android) - [IP-адрес](https://www.ftc.gov/system/files/ftc_gov/pdf/p235402_coppa_application.pdf) Кроме того, рекомендуем осторожно использовать пользовательский ID. Идентификатор в формате `опциональный
по умолчанию: `en`
|Идентификатор локализации онбординга. Ожидается языковой код, состоящий из одного или двух подтегов, разделённых символом минус (**-**). Первый подтег — язык, второй — регион.
Пример: `en` — английский, `pt-br` — бразильский португальский.
Подробнее о кодах локалей и рекомендациях по их использованию см. в разделе [Локализации и коды локалей](flutter-localizations-and-locale-codes).
| | **fetchPolicy** | по умолчанию: `.reloadRevalidatingCacheData` |По умолчанию SDK пытается загрузить данные с сервера и возвращает кэшированные данные в случае ошибки. Мы рекомендуем этот вариант, так как он гарантирует актуальность данных для пользователей.
Однако если у ваших пользователей нестабильное интернет-соединение, рассмотрите `.returnCacheDataElseLoad` — он возвращает кэш, если он есть. В этом случае данные могут быть не самыми свежими, зато загрузка будет быстрее при любом качестве соединения. Кэш регулярно обновляется, поэтому использовать его в течение сессии для сокращения сетевых запросов безопасно.
Обратите внимание: кэш сохраняется при перезапуске приложения и очищается только при переустановке или ручной очистке.
Adapty SDK хранит онбординги локально в двух слоях: регулярно обновляемый кэш (описан выше) и резервные онбординги. Также используется CDN для ускорения загрузки и отдельный резервный сервер на случай недоступности CDN. Эта система обеспечивает актуальность онбордингов и надёжность даже при нестабильном интернет-соединении.
| | **loadTimeout** | по умолчанию: 5 сек |Ограничивает таймаут выполнения метода. По истечении таймаута возвращаются кэшированные данные или локальный резервный вариант.
Обратите внимание: в редких случаях метод может превысить таймаут, указанный в `loadTimeout`, поскольку операция может включать несколько запросов под капотом.
| Параметры ответа: | Параметр | Описание | |:----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Onboarding | Объект [`AdaptyOnboarding`](https://unity.adapty.io/class_adapty_s_d_k_1_1_adapty_onboarding.html), содержащий: идентификатор и конфигурацию онбординга, Remote Config и ряд других свойств. | После получения онбординга вызовите метод `CreateOnboardingView`. :::warning Результат метода `CreateOnboardingView` можно использовать только один раз. Если нужно использовать его повторно, вызовите `CreateOnboardingView` заново. Повторный вызов без пересоздания может привести к ошибке `AdaptyUIError.viewAlreadyPresented`. ::: ```csharp showLineNumbers AdaptyUI.CreateOnboardingView(onboarding, (view, error) => { // handle the result }); ``` Параметры: | Параметр | Обязательность | Описание | |:---------------| :------------- |:-----------------------------------------------------------------------------| | **onboarding** | обязательный | Объект `AdaptyOnboarding` для получения представления нужного онбординга. | | **externalUrlsPresentation** |опциональный
по умолчанию: `InAppBrowser`
|Управляет тем, как открываются ссылки в онбординге. Доступные варианты:
- `AdaptyWebPresentation.InAppBrowser` — открывает ссылки во встроенном браузере (по умолчанию)
- `AdaptyWebPresentation.ExternalBrowser` — открывает ссылки во внешнем браузере устройства
Примеры использования см. в разделе [Настройка открытия ссылок в онбордингах](unity-present-onboardings#customize-how-links-open-in-onboardings).
| После успешной загрузки онбординга и его конфигурации отображения вы можете [показать его в мобильном приложении](unity-present-onboardings). ## Ускорение загрузки онбординга с помощью онбординга для аудитории по умолчанию \{#speed-up-onboarding-fetching-with-default-audience-onboarding\} Как правило, онбординги загружаются практически мгновенно, и беспокоиться об ускорении этого процесса не нужно. Однако если у вас много аудиторий и онбордингов, а у пользователей слабое интернет-соединение, загрузка онбординга может занять больше времени, чем хотелось бы. В таких случаях можно отображать онбординг по умолчанию, чтобы обеспечить плавный пользовательский опыт, а не показывать пустой экран. Для этого используйте метод `GetOnboardingForDefaultAudience`, который загружает онбординг указанного плейсмента для аудитории **All Users**. Важно понимать, что рекомендуемый подход — получать онбординг методом `getOnboarding`, как описано в разделе [Получение онбординга](#fetch-onboarding) выше. :::warning По возможности используйте `GetOnboarding` вместо `GetOnboardingForDefaultAudience`, поскольку у последнего есть существенные ограничения: - **Проблемы совместимости**: могут возникнуть сложности при поддержке нескольких версий приложения — придётся либо делать обратно совместимый дизайн, либо мириться с тем, что старые версии могут отображаться некорректно. - **Отсутствие персонализации**: отображается только контент для аудитории «All Users» без таргетинга по стране, атрибуции или пользовательским атрибутам. Если скорость загрузки важнее этих ограничений для вашего случая, используйте `GetOnboardingForDefaultAudience`, как показано ниже. В остальных случаях используйте `GetOnboarding`, как описано [выше](#fetch-onboarding). ::: ```csharp showLineNumbers Adapty.GetOnboardingForDefaultAudience("YOUR_PLACEMENT_ID", (onboarding, error) => { if (error != null) { // handle the error return; } // the requested onboarding }); ``` Параметры: | Параметр | Обязательность | Описание | |---------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | **placementId** | обязательный | Идентификатор нужного [плейсмента](placements). Это значение вы указывали при создании плейсмента в дашборде Adapty. | | **locale** |опциональный
по умолчанию: `en`
|Идентификатор локализации онбординга. Ожидается языковой код, состоящий из одного или двух подтегов, разделённых символом минус (**-**). Первый подтег — язык, второй — регион.
Пример: `en` — английский, `pt-br` — бразильский португальский.
| | **fetchPolicy** | по умолчанию: `.reloadRevalidatingCacheData` |По умолчанию SDK пытается загрузить данные с сервера и возвращает кэшированные данные в случае ошибки. Мы рекомендуем этот вариант, так как он гарантирует актуальность данных для пользователей.
Однако если у ваших пользователей нестабильное интернет-соединение, рассмотрите `.returnCacheDataElseLoad` — он возвращает кэш, если он есть. В этом случае данные могут быть не самыми свежими, зато загрузка будет быстрее при любом качестве соединения. Кэш регулярно обновляется, поэтому использовать его в течение сессии для сокращения сетевых запросов безопасно.
Обратите внимание: кэш сохраняется при перезапуске приложения и очищается только при переустановке или ручной очистке.
Adapty SDK хранит онбординги локально в двух слоях: регулярно обновляемый кэш (описан выше) и резервные онбординги. Также используется CDN для ускорения загрузки и отдельный резервный сервер на случай недоступности CDN. Эта система обеспечивает актуальность онбордингов и надёжность даже при нестабильном интернет-соединении.
| --- # File: unity-present-onboardings --- --- title: "Показ онбординга в Unity SDK" description: "Узнайте, как эффективно показывать онбординги для повышения конверсии." --- Если вы настроили онбординг с помощью билдера, вам не нужно беспокоиться о его отрисовке в коде Unity-приложения для показа пользователю. Такой онбординг содержит как то, что должно отображаться внутри него, так и то, как именно это должно отображаться. Прежде чем начать, убедитесь, что: 1. Вы установили [Adapty Unity SDK](sdk-installation-unity) версии 3.14.0 или новее. 2. Вы [создали онбординг](create-onboarding). 3. Вы добавили онбординг в [плейсмент](placements). Чтобы отобразить онбординг, вызовите метод `view.Present()` на объекте `view`, созданном методом `CreateOnboardingView`. Каждый `view` можно использовать только один раз. Если нужно показать пейвол повторно, вызовите `CreateOnboardingView` ещё раз, чтобы создать новый экземпляр `view`. :::warning Повторное использование одного и того же `view` без его пересоздания может привести к ошибке `AdaptyUIError.viewAlreadyPresented`. ::: ```csharp showLineNumbers title="Unity" view.Present((presentError) => { if (presentError != null) { // handle the error } }; ``` ## Настройка стиля презентации на iOS \{#configure-ios-presentation-style\} Настройте способ отображения онбординга на iOS, передав параметр `iosPresentationStyle` в метод `Present()`. Параметр принимает значения `AdaptyUIIOSPresentationStyle.FullScreen` (по умолчанию) или `AdaptyUIIOSPresentationStyle.PageSheet`. ```csharp showLineNumbers title="Unity" view.Present(AdaptyUIIOSPresentationStyle.PageSheet, (error) => { // handle the error }); ``` ## Настройка открытия ссылок в онбординге \{#customize-how-links-open-in-onboardings\} :::important Настройка способа открытия ссылок в онбординге поддерживается начиная с Adapty SDK v3.15. ::: По умолчанию ссылки в онбординге открываются во встроенном браузере — это обеспечивает удобство работы, поскольку веб-страницы отображаются прямо внутри приложения без переключения между приложениями. Чтобы ссылки открывались во внешнем браузере, передайте `AdaptyWebPresentation.ExternalBrowser` в метод `CreateOnboardingView`: ```csharp showLineNumbers title="Unity" AdaptyUI.CreateOnboardingView( onboarding, AdaptyWebPresentation.ExternalBrowser, // default — InAppBrowser (view, error) => { if (error != null) { // handle the error return; } // present the onboarding view view.Present((presentError) => { if (presentError != null) { // handle the error } }); } ); ``` Доступные варианты: - `AdaptyWebPresentation.InAppBrowser` — открывает ссылки во встроенном браузере (по умолчанию) - `AdaptyWebPresentation.ExternalBrowser` — открывает ссылки во внешнем браузере устройства --- # File: unity-handling-onboarding-events --- --- title: "Обработка событий онбординга в Unity SDK" description: "Обрабатывайте события онбординга в Unity с помощью Adapty." --- Прежде чем начать, убедитесь, что: 1. Вы установили [Adapty Unity SDK](sdk-installation-unity) версии 3.14.0 или новее. 2. Вы [создали онбординг](create-onboarding). 3. Вы добавили онбординг в [плейсмент](placements). Онбординги, настроенные с помощью конструктора, генерируют события, на которые может реагировать ваше приложение. Ниже описано, как с ними работать. Чтобы управлять процессами на экране онбординга в Unity-приложении или отслеживать их, реализуйте интерфейс `AdaptyOnboardingsEventsListener`. ## Пользовательские действия \{#custom-actions\} В конструкторе можно добавить к кнопке действие **custom** и назначить ему ID.
Затем вы можете использовать этот ID в своём коде и обрабатывать его как пользовательское действие. Например, если пользователь нажимает на кнопку, такую как **Login** или **Allow notifications**, будет вызван метод `OnboardingViewOnCustomAction` с параметром `actionId`, соответствующим **Action ID** из билдера. Вы можете задавать собственные ID, например "allowNotifications".
Чтобы обрабатывать события онбординга, реализуйте интерфейс `AdaptyOnboardingsEventsListener`:
```csharp showLineNumbers title="Unity"
public class OnboardingManager : MonoBehaviour, AdaptyOnboardingsEventsListener
{
void Start()
{
Adapty.SetOnboardingsEventsListener(this);
}
public void OnboardingViewOnCustomAction(
AdaptyUIOnboardingView view,
AdaptyUIOnboardingMeta meta,
string actionId
)
{
if (actionId == "allowNotifications") {
// request notification permissions
}
}
public void OnboardingViewDidFailWithError(
AdaptyUIOnboardingView view,
AdaptyError error
)
{
// handle errors
}
// Implement other required interface methods (see examples below)
}
```
:::important
Обратите внимание: вам нужно самостоятельно обработать закрытие онбординга. Например, скрыть экран онбординга.
:::
Реализуйте метод `OnboardingViewOnCloseAction` в своём классе:
```csharp showLineNumbers title="Unity"
public class OnboardingManager : MonoBehaviour, AdaptyOnboardingsEventsListener
{
public void OnboardingViewOnCloseAction(
AdaptyUIOnboardingView view,
AdaptyUIOnboardingMeta meta,
string actionId
)
{
view.Dismiss((error) => {
if (error != null) {
// handle the error
}
});
}
// ... other interface methods
}
```
2. Нажмите на название группы подписок. Вы увидите продукты в разделе **Subscriptions**.
3. Убедитесь, что тестируемый продукт отмечен как **Ready to Submit**.
4. Сравните идентификатор продукта из таблицы с тем, что указан на вкладке [**Products**](https://app.adapty.io/products) в дашборде Adapty. Если идентификаторы не совпадают, скопируйте идентификатор продукта из таблицы и [создайте продукт](create-product) с ним в дашборде Adapty.
## Шаг 3. Проверьте доступность продуктов \{#step-4-check-product-availability\}
1. Вернитесь в **App Store Connect** и откройте раздел **Subscriptions**.
2. Нажмите на название группы подписок, чтобы посмотреть продукты.
3. Выберите продукт, который хотите протестировать.
4. Прокрутите до раздела **Availability** и убедитесь, что все необходимые страны и регионы указаны.
## Шаг 4. Проверьте цены продуктов \{#step-5-check-product-prices\}
1. Снова перейдите в раздел **Monetization** → **Subscriptions** в **App Store Connect**.
2. Нажмите на название группы подписок.
3. Выберите продукт, который хотите протестировать.
4. Прокрутите вниз до раздела **Subscription Pricing** и разверните секцию **Current Pricing for New Subscribers**.
5. Убедитесь, что все необходимые цены указаны.
## Шаг 5. Убедитесь, что статус приложения, банковский счёт и налоговые формы активны \{#step-5-check-app-paid-status-bank-account-and-tax-forms-are-active\}
1. На главной странице [**App Store Connect**](https://appstoreconnect.apple.com/) нажмите **Business**.
2. Выберите название вашей компании.
3. Прокрутите вниз и убедитесь, что **Paid Apps Agreement**, **Bank Account** и **Tax forms** отображаются как **Active**.
Следуя этим шагам, вы сможете устранить предупреждение `InvalidProductIdentifiers` и опубликовать свои продукты в сторе.
## Шаг 6. Пересоздайте продукт, если он завис \{#step-6-recreate-the-product-if-its-stuck\}
Шаги 1–5 могут пройти успешно — статус `Approved`, совпадающий Bundle ID, валидный API-ключ — но SDK всё равно возвращает `1000 noProductIDsFound`. В таком случае продукт может быть завис в реестре Apple. Иногда реестр продуктов Apple переходит в состояние, при котором продукт существует в UI App Store Connect, но недоступен для StoreKit при поиске.
Удалите продукт в App Store Connect и пересоздайте его с тем же идентификатором. После пересоздания подождите до 24 часов — столько может занять распространение изменений.
---
# File: cantMakePayments-unity
---
---
title: "Исправление ошибки Code-1003 cantMakePayment в Unity SDK"
description: "Устранение ошибки при проведении платежей и управлении подписками в Adapty."
---
Ошибка 1003, `cantMakePayments`, означает, что на этом устройстве нельзя совершать встроенные покупки.
Если вы столкнулись с ошибкой `cantMakePayments`, обычно это происходит по одной из следующих причин:
- Ограничения устройства: ошибка не связана с Adapty. Способы решения описаны ниже.
- Настройка Observer mode: метод `makePurchase` и Observer mode нельзя использовать одновременно. Подробнее — в соответствующем разделе ниже.
## Проблема: ограничения устройства \{#issue-device-restrictions\}
| Проблема | Решение |
|---------------------------------|-------------------------------------------------------------------------------------------------------------------|
| Ограничения Screen Time | Отключите ограничения встроенных покупок в [Screen Time](https://support.apple.com/en-us/102470) |
| Аккаунт заблокирован | Обратитесь в службу поддержки Apple для решения проблем с аккаунтом |
| Региональные ограничения | Используйте аккаунт App Store из поддерживаемого региона |
## Проблема: одновременное использование Observer mode и makePurchase \{#issue-using-both-observer-mode-and-makepurchase\}
Если вы используете `makePurchase` для обработки покупок, Observer mode не нужен. [Observer mode](observer-vs-full-mode) требуется только в том случае, если логику покупок вы реализуете самостоятельно.
Таким образом, если вы используете `makePurchase`, можно смело убрать активацию Observer mode из кода инициализации SDK.
---
# File: migration-to-unity-sdk-314
---
---
title: "Миграция Adapty Unity SDK на v3.14"
description: "Перейдите на Adapty Unity SDK v3.14 для повышения производительности и новых функций монетизации."
---
Adapty SDK 3.14.0 — это крупный релиз, который принёс ряд улучшений, однако для перехода на него могут потребоваться дополнительные шаги с вашей стороны:
1. Отдельный обработчик событий пейвола.
2. Переименование `AdaptyUI.CreateView` в `AdaptyUI.CreatePaywallView` и связанных методов.
3. Обновление метода `MakePurchase` для использования `AdaptyPurchaseParameters` вместо отдельных параметров.
4. Замена `SetFallbackPaywalls` на метод `SetFallback`.
5. Обновление доступа к свойствам пейвола через `AdaptyPlacement`.
6. Обновление доступа к Remote Config через объект `AdaptyRemoteConfig`.
7. Замена `VendorProductIds` на `ProductIdentifiers` в модели `AdaptyPaywall`.
8. Обновление политики получения пейвола в `GetPaywall` для использования `AdaptyFetchPolicy`.
## Отдельный слушатель событий для пейвола \{#separate-event-listener-for-paywall-events\}
Если вы отображаете пейволы, созданные с помощью [Paywall Builder](adapty-paywall-builder), события пейвола теперь используют специальный интерфейс `AdaptyPaywallsEventsListener` и метод `SetPaywallsEventsListener`. Основной интерфейс `AdaptyEventListener` по-прежнему используется для обновлений профиля и данных об установке.
```diff showLineNumbers
using UnityEngine;
using AdaptySDK;
public class AdaptyListener : MonoBehaviour,
- AdaptyEventListener {
+ AdaptyEventListener,
+ AdaptyPaywallsEventsListener {
void Start() {
Adapty.SetEventListener(this);
+ Adapty.SetPaywallsEventsListener(this);
}
// AdaptyEventListener methods
public void OnLoadLatestProfile(AdaptyProfile profile) { }
public void OnInstallationDetailsSuccess(AdaptyInstallationDetails details) { }
public void OnInstallationDetailsFail(AdaptyError error) { }
+ // AdaptyPaywallsEventsListener methods
+ // Implement paywall event handlers here
}
```
[Подробнее об обработке событий пейвола](unity-handling-events).
## Переименование методов создания и отображения представления \{#rename-view-creation-and-presentation-methods\}
Методы создания и отображения представления были переименованы:
```diff showLineNumbers
using AdaptySDK;
- AdaptyUI.CreateView(paywall, parameters, (view, error) => {
+ AdaptyUI.CreatePaywallView(paywall, parameters, (view, error) => {
if (error != null) {
// handle the error
return;
}
- AdaptyUI.PresentView(view, (error) => {
+ AdaptyUI.PresentPaywallView(view, (error) => {
// handle the error
});
});
}
```
Аналогично был переименован метод закрытия:
```diff showLineNumbers
- AdaptyUI.DismissView(view, (error) => {
+ AdaptyUI.DismissPaywallView(view, (error) => {
// handle the error
});
```
## Обновление метода MakePurchase \{#update-makepurchase-method\}
Метод `MakePurchase` теперь принимает `AdaptyPurchaseParameters` вместо отдельных аргументов `subscriptionUpdateParams` и `isOfferPersonalized`. Это обеспечивает более строгую типизацию и упрощает добавление новых параметров покупки в будущем.
```diff showLineNumbers
using AdaptySDK;
void MakePurchase(
AdaptyPaywallProduct product,
AdaptySubscriptionUpdateParameters subscriptionUpdate,
bool? isOfferPersonalized
) {
- Adapty.MakePurchase(product, subscriptionUpdate, isOfferPersonalized, (result, error) => {
+ var parameters = new AdaptyPurchaseParametersBuilder()
+ .SetSubscriptionUpdateParams(subscriptionUpdate)
+ .SetIsOfferPersonalized(isOfferPersonalized)
+ .Build();
+
+ Adapty.MakePurchase(product, parameters, (result, error) => {
switch (result.Type) {
case AdaptyPurchaseResultType.Pending:
// handle pending purchase
break;
case AdaptyPurchaseResultType.UserCancelled:
// handle purchase cancellation
break;
case AdaptyPurchaseResultType.Success:
var profile = result.Profile;
// handle successful purchase
break;
default:
break;
}
});
}
```
Если дополнительные параметры не нужны, можно использовать упрощённый вариант:
```csharp showLineNumbers
using AdaptySDK;
void MakePurchase(AdaptyPaywallProduct product) {
Adapty.MakePurchase(product, (result, error) => {
// handle purchase result
});
}
```
## Обновление метода для резервных пейволов \{#update-fallback-method\}
:::important
При обновлении до Unity SDK 3.14 вам потребуется загрузить новые резервные файлы из дашборда Adapty и заменить существующие в вашем проекте.
:::
Метод для настройки резервных пейволов был обновлён. Метод `SetFallbackPaywalls` переименован в `SetFallback`:
```diff showLineNumbers
using AdaptySDK;
void SetFallBackPaywalls() {
#if UNITY_IOS
var assetId = "adapty_fallback_ios.json";
#elif UNITY_ANDROID
var assetId = "adapty_fallback_android.json";
#else
var assetId = "";
#endif
- Adapty.SetFallbackPaywalls(assetId, (error) => {
+ Adapty.SetFallback(assetId, (error) => {
// handle the error
});
}
```
Ознакомьтесь с полным примером кода на странице [Использование резервных пейволов в Unity](unity-use-fallback-paywalls).
## Обновление доступа к свойствам пейвола \{#update-paywall-property-access\}
Следующие свойства перенесены из `AdaptyPaywall` в `AdaptyPlacement`:
```diff showLineNumbers
using AdaptySDK;
void ProcessPaywall(AdaptyPaywall paywall) {
- var abTestName = paywall.ABTestName;
- var audienceName = paywall.AudienceName;
- var revision = paywall.Revision;
- var placementId = paywall.PlacementId;
+ var abTestName = paywall.Placement.ABTestName;
+ var audienceName = paywall.Placement.AudienceName;
+ var revision = paywall.Placement.Revision;
+ var placementId = paywall.Placement.Id;
}
```
## Обновление доступа к Remote Config \{#update-remote-config-access\}
Свойства Remote Config были реструктурированы в объект `AdaptyRemoteConfig` для лучшей организации:
```diff showLineNumbers
using AdaptySDK;
void ProcessRemoteConfig(AdaptyPaywall paywall) {
- var remoteConfigString = paywall.RemoteConfigString;
- var locale = paywall.Locale;
- var remoteConfigDict = paywall.RemoteConfig;
+ var remoteConfigString = paywall.RemoteConfig.Data;
+ var locale = paywall.RemoteConfig.Locale;
+ var remoteConfigDict = paywall.RemoteConfig.Dictionary;
}
```
## Обновление использования модели AdaptyPaywall \{#update-adaptypaywall-model-usage\}
Свойство `VendorProductIds` устарело и заменено на `ProductIdentifiers`. Новое свойство возвращает объекты `AdaptyProductIdentifier` вместо обычных строк, предоставляя более структурированную информацию о продуктах.
```diff showLineNumbers
using AdaptySDK;
void ProcessPaywallProducts(AdaptyPaywall paywall) {
- var productIds = paywall.VendorProductIds;
- foreach (var vendorId in productIds) {
- // use vendorId
- }
+ var productIdentifiers = paywall.ProductIdentifiers;
+ foreach (var productId in productIdentifiers) {
+ var vendorId = productId.VendorProductId;
+ // use vendorId
+ }
}
```
Объект `AdaptyProductIdentifier` предоставляет доступ к идентификатору продукта вендора через свойство `VendorProductId`, сохраняя ту же функциональность и обеспечивая лучшую структуру для будущих улучшений.
## Обновление политики загрузки в GetPaywall \{#update-getpaywall-fetch-policy\}
Тип параметра `fetchPolicy` в методе `GetPaywall` изменён с `AdaptyPaywallFetchPolicy` на `AdaptyPlacementFetchPolicy`. Это изменение унифицирует использование политики загрузки во всём SDK.
```diff showLineNumbers
using AdaptySDK;
void GetPaywall(string placementId) {
- Adapty.GetPaywall(placementId, AdaptyPaywallFetchPolicy.ReloadRevalidatingCacheData, null, (paywall, error) => {
+ Adapty.GetPaywall(placementId, AdaptyPlacementFetchPolicy.ReloadRevalidatingCacheData, null, (paywall, error) => {
// handle the result
});
}
```
---
# File: migration-to-unity-sdk-34
---
---
title: "Migrate Adapty Unity SDK to v. 3.4"
description: "Перейдите на Adapty Unity SDK v3.4 для повышения производительности и доступа к новым функциям монетизации."
---
Adapty SDK 3.4.0 — это мажорный релиз, который включает улучшения, требующие выполнения шагов миграции с вашей стороны.
## Обновите файлы резервного пейвола \{#update-fallback-paywall-files\}
Обновите файлы резервного пейвола, чтобы обеспечить совместимость с новой версией SDK:
1. [Скачайте обновлённые файлы резервного пейвола](fallback-paywalls) из дашборда Adapty.
2. [Замените существующие резервные пейволы в своём мобильном приложении](unity-use-fallback-paywalls) на новые файлы.
## Обновите реализацию Observer Mode \{#update-implementation-of-observer-mode\}
Если вы используете Observer Mode, убедитесь, что его реализация обновлена.
Раньше для передачи транзакций в Adapty использовались разные методы. В новой версии для этого нужно использовать метод `reportTransaction` — он работает одинаково на Android и iOS. Метод явно сообщает Adapty о каждой транзакции, гарантируя её распознавание. Если при покупке использовался пейвол, передайте variation ID, чтобы связать транзакцию с ним.
:::warning
**Не пропускайте отчёт о транзакции!**
Если не вызвать `reportTransaction`, Adapty не распознает транзакцию — она не появится в аналитике и не будет отправлена в интеграции.
:::
```diff showLineNumbers
- #if UNITY_ANDROID && !UNITY_EDITOR
- Adapty.RestorePurchases((profile, error) => {
- // handle the error
- });
- #endif
Adapty.ReportTransaction(
"YOUR_TRANSACTION_ID",
"PAYWALL_VARIATION_ID", // optional
(error) => {
// handle the error
});
```
---
# File: migration-to-unity330
---
---
title: "Миграция Adapty Unity SDK на v3.3"
description: "Выполните миграцию на Adapty Unity SDK v3.3 для повышения производительности и новых функций монетизации."
---
Adapty SDK 3.3.0 — это мажорный релиз, который принёс ряд улучшений, однако для перехода на него может потребоваться выполнить несколько шагов миграции.
1. Обновитесь до Adapty SDK v3.3.x.
2. Переименованы несколько классов, свойств и методов в модулях Adapty и AdaptyUI Adapty SDK.
3. Теперь метод `SetLogLevel` принимает callback в качестве аргумента.
4. Теперь метод `PresentCodeRedemptionSheet` принимает callback в качестве аргумента.
5. Изменён способ создания представления пейвола.
6. Метод `GetProductsIntroductoryOfferEligibility` удалён.
7. Сохраняйте резервные пейволы в отдельные файлы (по одному на платформу) в `Assets/StreamingAssets/` и передавайте имена файлов в метод `SetFallbackPaywalls`.
8. Обновлено выполнение покупки.
9. Обновлена обработка событий Paywall Builder.
10. Обновлена обработка ошибок пейвола Paywall Builder.
11. Обновлены конфигурации интеграций для Adjust, Amplitude, AppMetrica, Appsflyer, Branch, Firebase и Google Analytics, Mixpanel, OneSignal, Pushwoosh.
13. Обновлена реализация режима Observer.
14. Обновлена инициализация плагина Unity с явным вызовом `Activate`.
## Обновление Adapty Unity SDK до версии 3.3.x \{#upgrade-adapty-unity-sdk-to-33x\}
До этой версии Adapty SDK был основным и обязательным SDK для корректной работы Adapty в вашем приложении, а AdaptyUI SDK — опциональным, который требовался только при использовании Adapty Paywall Builder.
Начиная с версии 3.3.0, AdaptyUI SDK объявлен устаревшим, а AdaptyUI объединён с Adapty SDK в виде модуля. В связи с этими изменениями вам нужно удалить AdaptyUI SDK и переустановить Adapty SDK.
1. Удалите зависимости пакетов **AdaptySDK** и **AdaptyUISDK** из вашего проекта.
2. Удалите папки **AdaptySDK** и **AdaptyUISDK**.
3. Повторно импортируйте пакет AdaptySDK, как описано на странице [Установка и настройка Adapty SDK для Unity](sdk-installation-unity).
## Переименования \{#renamings\}
1. Переименования в модуле Adapty:
| Старая версия | Новая версия |
| ------------------------- | ------------------------ |
| Adapty.sdkVersion | Adapty.SDKVersion |
| Adapty.LogLevel | AdaptyLogLevel |
| Adapty.Paywall | AdaptyPaywall |
| Adapty.PaywallFetchPolicy | AdaptyPaywallFetchPolicy |
| PaywallProduct | AdaptyPaywallProduct |
| Adapty.Profile | AdaptyProfile |
| Adapty.ProfileParameters | AdaptyProfileParameters |
| ProfileGender | AdaptyProfileGender |
| Error | AdaptyError |
2. Переименования в модуле AdaptyUI:
| Старая версия | Новая версия |
| ------------------ | ------------------ |
| CreatePaywallView | CreateView |
| PresentPaywallView | PresentView |
| DismissPaywallView | DismissView |
| AdaptyUI.View | AdaptyUIView |
| AdaptyUI.Action | AdaptyUIUserAction |
## Изменение метода SetLogLevel \{#change-the-setloglevel-method\}
Теперь метод `SetLogLevel` принимает callback в качестве аргумента.
```diff showLineNumbers
- Adapty.SetLogLevel(Adapty.LogLevel.Verbose);
+ Adapty.SetLogLevel(Adapty.LogLevel.Verbose, null); // or you can pass the callback to handle the possible error
```
## Изменение метода PresentCodeRedemptionSheet \{#change-the-presentcoderedemptionsheet-method\}
Теперь метод `PresentCodeRedemptionSheet` принимает callback в качестве аргумента.
```diff showLineNumbers
- Adapty.PresentCodeRedemptionSheet();
+ Adapty.PresentCodeRedemptionSheet(null); // or you can pass the callback to handle the possible error
```
## Изменение способа создания вида пейвола \{#change-how-the-paywall-view-is-created\}
Полный пример кода см. в разделе [Получение конфигурации вида пейвола, созданного с помощью Paywall Builder](unity-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder).
```diff showLineNumbers
+ var parameters = new AdaptyUICreateViewParameters()
+ .SetPreloadProducts(true);
- AdaptyUI.CreatePaywallView(
+ AdaptyUI.CreateView(
paywall,
- preloadProducts: true,
+ parameters,
(view, error) => {
// use the view
});
```
## Удаление метода GetProductsIntroductoryOfferEligibility \{#remove-the-getproductsintroductoryoffereligibility-method\}
До Adapty iOS SDK 3.3.0 объект продукта всегда содержал офферы, независимо от того, имел ли пользователь право на их получение. Вам приходилось вручную проверять это право перед использованием оффера.
Теперь объект продукта содержит оффер только в том случае, если пользователь имеет право на его получение. Это означает, что проверка права больше не нужна — если оффер присутствует, пользователь имеет на него право.
## Обновлённый метод передачи резервных пейволов \{#update-method-for-providing-fallback-paywalls\}
До этой версии резервные пейволы передавались в виде сериализованного JSON. Начиная с версии 3.3.0, механизм изменился:
1. Сохраните резервные пейволы в файлы в `/Assets/StreamingAssets/` — один файл для Android и один для iOS.
2. Передайте имена файлов в метод `SetFallbackPaywalls`.
Ваш код изменится следующим образом:
```diff showLineNumbers
using AdaptySDK;
void SetFallBackPaywalls() {
+ #if UNITY_IOS
+ var assetId = "adapty_fallback_ios.json";
+ #elif UNITY_ANDROID
+ var assetId = "adapty_fallback_android.json";
+ #else
+ var assetId = "";
+ #endif
- Adapty.SetFallbackPaywalls("FALLBACK_PAYWALLS_JSON_STRING", (error) => {
+ Adapty.SetFallbackPaywalls(assetId, (error) => {
// handle the error
});
}
```
Полный пример кода смотрите на странице [Использование резервных пейволов в Unity](unity-use-fallback-paywalls).
## Обновление процесса покупки \{#update-making-purchase\}
Ранее отменённые и ожидающие покупки считались ошибками и возвращали коды `PaymentCancelled` и `PendingPurchase` соответственно.
Теперь для обработки отменённых, успешных и ожидающих покупок используется новый класс `AdaptyPurchaseResultType`. Обновите код покупки следующим образом:
```diff showLineNumbers
using AdaptySDK;
void MakePurchase(AdaptyPaywallProduct product) {
- Adapty.MakePurchase(product, (profile, error) => {
- // handle successfull purchase
+ Adapty.MakePurchase(product, (result, error) => {
+ switch (result.Type) {
+ case AdaptyPurchaseResultType.Pending:
+ // handle pending purchase
+ break;
+ case AdaptyPurchaseResultType.UserCancelled:
+ // handle purchase cancellation
+ break;
+ case AdaptyPurchaseResultType.Success:
+ var profile = result.Profile;
+ // handle successful purchase
+ break;
+ default:
+ break;
}
});
}
```
Ознакомьтесь с финальным примером кода на странице [Совершение покупок в мобильном приложении](unity-making-purchases).
## Обновите обработку событий Paywall Builder \{#update-handling-of-paywall-builder-events\}
Отменённые и ожидающие покупки больше не считаются ошибками — все эти случаи обрабатываются методом `PaywallViewDidFinishPurchase`.
1. Удалите обработку события отменённой покупки.
2. Обновите обработку события успешной покупки следующим образом:
```diff showLineNumbers
- public void OnFinishPurchase(
- AdaptyUI.View view,
- Adapty.PaywallProduct product,
- Adapty.Profile profile
- ) { }
+ public void PaywallViewDidFinishPurchase(
+ AdaptyUIView view,
+ AdaptyPaywallProduct product,
+ AdaptyPurchaseResult purchasedResult
+ ) { }
```
3. Обновите обработку действий:
```diff showLineNumbers
- public void OnPerformAction(
- AdaptyUI.View view,
- AdaptyUI.Action action
- ) {
+ public void PaywallViewDidPerformAction(
+ AdaptyUIView view,
+ AdaptyUIUserAction action
+ ) {
switch (action.Type) {
- case AdaptyUI.ActionType.Close:
+ case AdaptyUIUserActionType.Close:
view.Dismiss(null);
break;
- case AdaptyUI.ActionType.OpenUrl:
+ case AdaptyUIUserActionType.OpenUrl:
var urlString = action.Value;
if (urlString != null {
Application.OpenURL(urlString);
}
default:
// handle other events
break;
}
}
```
4. Обновите обработку начала покупки:
```diff showLineNumbers
- public void OnSelectProduct(
- AdaptyUI.View view,
- Adapty.PaywallProduct product
- ) { }
+ public void PaywallViewDidSelectProduct(
+ AdaptyUIView view,
+ string productId
+ ) { }
```
5. Обновите обработку ошибки покупки:
```diff showLineNumbers
- public void OnFailPurchase(
- AdaptyUI.View view,
- Adapty.PaywallProduct product,
- Adapty.Error error
- ) { }
+ public void PaywallViewDidFailPurchase(
+ AdaptyUIView view,
+ AdaptyPaywallProduct product,
+ AdaptyError error
+ ) { }
```
6. Обновите обработку события успешного восстановления покупок:
Ознакомьтесь с финальным примером кода на странице [Обработка событий пейвола](unity-handling-events).
## Обновление обработки ошибок пейвола в Paywall Builder \{#update-handling-of-paywall-builder-paywall-errors\}
Обработка ошибок также изменилась — обновите свой код согласно инструкциям ниже.
1. Обновите обработку ошибок загрузки продуктов:
```diff showLineNumbers
- public void OnFailLoadingProducts(
- AdaptyUI.View view,
- Adapty.Error error
- ) { }
+ public void PaywallViewDidFailLoadingProducts(
+ AdaptyUIView view,
+ AdaptyError error
+ ) { }
```
2. Обновите обработку ошибок рендеринга:
```diff showLineNumbers
- public void OnFailRendering(
- AdaptyUI.View view,
- Adapty.Error error
- ) { }
+ public void PaywallViewDidFailRendering(
+ AdaptyUIView view,
+ AdaptyError error
+ ) { }
```
## Обновление конфигурации SDK сторонних интеграций \{#update-third-party-integration-sdk-configuration\}
Начиная с Adapty Unity SDK 3.3.0, публичный API метода `updateAttribution` обновлён. Ранее он принимал словарь `[AnyHashable: Any]`, позволяя передавать объекты атрибуции напрямую из различных сервисов. Теперь он требует `[String: any Sendable]`, поэтому перед передачей объекты атрибуции необходимо конвертировать.
Чтобы интеграции корректно работали с Adapty Unity SDK 3.3.0 и выше, обновите конфигурации SDK для следующих интеграций, как описано в разделах ниже.
### Adjust
Обновите код мобильного приложения, как показано ниже. Полный пример кода смотрите в разделе [Настройка SDK для интеграции с Adjust](adjust#connect-your-app-to-adjust).
```diff showLineNumbers
- using static AdaptySDK.Adapty;
using AdaptySDK;
Adjust.GetAdid((adid) => {
- Adjust.GetAttribution((attribution) => {
- Dictionary