Типы событий и поля вебхуков
Adapty отправляет вебхуки в ответ на события подписки. В этом разделе описаны типы событий и данные, содержащиеся в каждом вебхуке.
Типы событий для вебхуков
Вы можете отправлять на вебхук все типы событий или выбрать только нужные. В разделе Потоки событий описано, какие данные поступают и как строить бизнес-логику на их основе. Ненужные типы событий можно отключить при настройке интеграции с вебхуком. Там же можно заменить стандартные идентификаторы событий Adapty на собственные.
| Event name | Description |
|---|---|
| subscription_started | Срабатывает, когда пользователь активирует платную подписку без пробного периода, то есть с него сразу списывается оплата. |
| subscription_renewed | Происходит при продлении подписки и списании оплаты с пользователя. Это событие фиксируется начиная со второго платежа — как для пробных, так и для обычных подписок. |
| subscription_renewal_cancelled | Пользователь отключил автопродление подписки. Доступ к премиум-функциям сохраняется до конца оплаченного периода. |
| subscription_renewal_reactivated | Срабатывает, когда пользователь повторно включает автопродление подписки. |
| subscription_expired | Срабатывает, когда подписка полностью завершается после отмены. Например, если пользователь отменил подписку 12 декабря, но она активна до 31 декабря, событие фиксируется 31 декабря, когда подписка истекает. |
| subscription_paused | Происходит, когда пользователь активирует паузу подписки (только Android). |
| subscription_deferred | Срабатывает, когда покупка подписки откладывается, — пользователь может перенести платёж, сохраняя доступ к премиум-функциям. Функция доступна через Google Play Developer API и может использоваться для пробных периодов или в поддержку пользователей, испытывающих финансовые трудности. |
| non_subscription_purchase | Любая покупка без подписки: пожизненный доступ или расходуемые покупки, например внутриигровые монеты. |
| trial_started | Срабатывает, когда пользователь активирует пробную подписку. |
| trial_converted | Происходит, когда пробный период заканчивается и с пользователя списывается первый платёж. Например, если пробный период действует до 14 января, но оплата проходит 7 января, событие фиксируется 7 января. |
| trial_renewal_cancelled | Пользователь отключил автопродление подписки в течение пробного периода. Доступ к премиум-функциям сохраняется до конца пробного периода, но оплата не будет списана и подписка не активируется. |
| trial_renewal_reactivated | Происходит, когда пользователь повторно включает автопродление подписки в течение пробного периода. |
| trial_expired | Срабатывает, когда пробный период заканчивается без перехода в подписку. |
| entered_grace_period | Происходит, когда попытка оплаты завершается неудачей и пользователь переходит в льготный период (если он включён). В течение этого времени доступ к премиум-функциям сохраняется. |
| billing_issue_detected | Срабатывает при возникновении проблемы с оплатой во время попытки списания (например, недостаточно средств на карте). |
| subscription_refunded | Срабатывает при возврате средств за подписку (например, через службу поддержки Apple). |
| non_subscription_purchase_refunded | Срабатывает при возврате средств за покупку без подписки. |
| access_level_updated | Происходит при обновлении уровня доступа пользователя. |
Структура события webhook
Adapty будет отправлять только те события, которые вы выбрали в разделе Events names на странице Integrations -> Webhooks.
События вебхука сериализуются в JSON. Тело POST-запроса к вашему серверу будет содержать сериализованное событие, обёрнутое в структуру, описанную ниже. Все события следуют одной и той же структуре, но их поля различаются в зависимости от типа события, стора и вашей конфигурации. Пользовательские атрибуты — это пользовательские атрибуты, которые вы настроили, поэтому они содержат то, что вы сконфигурировали. Поля данных атрибуции одинаковы для всех типов событий, однако список атрибуций зависит от того, какие источники атрибуции вы используете в мобильном приложении. Ниже приведён пример события:
{
"profile_id": "00000000-0000-0000-0000-000000000000",
"customer_user_id": "UserIdInYourSystem",
"idfv": "00000000-0000-0000-0000-000000000000",
"idfa": "00000000-0000-0000-0000-000000000000",
"advertising_id": "00000000-0000-0000-0000-000000000000",
"profile_install_datetime": "2000-01-31T00:00:00.000000+0000",
"user_agent": "ExampleUserAgent/1.0 (Device; OS Version) Browser/Engine",
"email": "[email protected]",
"event_type": "subscription_started",
"event_datetime": "2000-01-31T00:00:00.000000+0000",
"event_properties": {
"store": "play_store",
"currency": "USD",
"price_usd": 4.99,
"profile_id": "00000000-0000-0000-0000-000000000000",
"cohort_name": "All Users",
"environment": "Production",
"price_local": 4.99,
"base_plan_id": "b1",
"developer_id": "onboarding_placement",
"ab_test_name": "onboarding_ab_test",
"ab_test_revision": 1,
"paywall_name": "UsedPaywall",
"proceeds_usd": 4.2315,
"variation_id": "00000000-0000-0000-0000-000000000000",
"purchase_date": "2024-11-15T10:45:36.181000+0000",
"store_country": "AR",
"event_datetime": "2000-01-31T00:00:00.000000+0000",
"proceeds_local": 4.2415,
"tax_amount_usd": 0,
"transaction_id": "0000000000000000",
"net_revenue_usd": 4.2415,
"profile_country": "AR",
"paywall_revision": "1",
"profile_event_id": "00000000-0000-0000-0000-000000000000",
"tax_amount_local": 0,
"net_revenue_local": 4.2415,
"vendor_product_id": "onemonth_no_trial",
"profile_ip_address": "10.10.1.1",
"consecutive_payments": 1,
"rate_after_first_year": false,
"original_purchase_date": "2000-01-31T00:00:00.000000+0000",
"original_transaction_id": "0000000000000000",
"subscription_expires_at": "2000-01-31T00:00:00.000000+0000",
"profile_has_access_level": true,
"profile_total_revenue_usd": 4.99,
"promotional_offer_id": null,
"store_offer_category": null,
"store_offer_discount_type": null
},
"event_api_version": 1,
"profiles_sharing_access_level": [{"profile_id": "00000000-0000-0000-0000-000000000000", "customer_user_id": "UserIdInYourSystem"}],
"attributions": {
"appsflyer": {
"ad_set": "Keywords 1.12",
"status": "non_organic",
"channel": "Google Ads",
"ad_group": null,
"campaign": "Social media influencers - Rest of the world",
"creative": null,
"created_at": "2000-01-31T00:00:00.000000+0000"
}
},
"user_attributes": {"Favourite_color": "Violet", "Pet_name": "Fluffy"},
"integration_ids": {"firebase_app_instance_id": "val1", "branch_id": "val2", "one_signal_player_id": "val3"},
"play_store_purchase_token": {
"product_id": "product_123",
"purchase_token": "token_abc_123",
"is_subscription": true
}
}
Поля события
Параметры события одинаковы для всех типов событий.
| Поле | Тип | Описание |
|---|---|---|
| advertising_id | UUID | Рекламный идентификатор (только Android). |
| attributions | JSON | Данные атрибуции. Включается, если в настройках вебхука включён параметр Send Attribution. |
| customer_user_id | String | ID пользователя из вашего приложения (UUID, email или другой идентификатор), если вы задали его в коде приложения при идентификации пользователей. Если пользователи в коде приложения не идентифицируются или конкретный пользователь анонимен (не вошёл в систему), поле равно null. |
| String | Email пользователя, если вы передали его с помощью метода updateProfile в SDK Adapty или при создании/обновлении профилей через серверный API. Если значение email не передаётся в SDK или метод API, поле равно null. | |
| event_api_version | Integer | Версия API Adapty (текущая: 1). |
| event_datetime | ISO 8601 | Временная метка события в формате ISO 8601 (например, 2020-07-10T15:00:00.000000+0000). |
| event_properties | JSON | Свойства события. |
| event_type | String | Название события в формате Adapty. Полный список см. в разделе Типы событий вебхука. |
| idfa | UUID | Рекламный идентификатор (только Apple). IDFA в профиле в дашборде Adapty. Может быть null, если недоступен из-за ограничений отслеживания, детского режима или настроек конфиденциальности. |
| idfv | UUID | Идентификатор для поставщиков (IDFV), уникальный для каждого разработчика. IDFV в профиле в дашборде Adapty. |
| integration_ids | JSON | ID пользователя для интеграций, если вы задали их с помощью метода setIntegrationIdentifier в SDK Adapty или при создании/обновлении профилей через серверный API. null, если недоступны или интеграции отключены. |
| play_store_purchase_token | JSON | Токен покупки в Play Store. Включается, если в настройках вебхука включён параметр Send Play Store purchase token. |
| profile_id | UUID | ID профиля, автоматически генерируемый Adapty для каждого профиля. Один Apple/Google ID может быть связан с разными profile_id, если вы не идентифицируете пользователей или разрешаете покупки до входа в систему. Подробнее о том, как Adapty работает с родительскими и дочерними профилями. |
| profile_install_datetime | ISO 8601 | Временная метка установки в формате ISO 8601 (например, 2020-07-10T15:00:00.000000+0000). |
| profiles_sharing_access_level | JSON | Список пользователей, совместно использующих уровень доступа, за исключением текущего профиля. Если для вашего приложения включён совместный доступ, список содержит другие профили, связанные с тем же Apple/Google ID. Формат:
|
| user_agent | String | User-agent браузера устройства. |
| user_attributes | JSON | Пользовательские данные, которые вы можете задать для обогащения профилей информацией, специфичной для вашего приложения. Обычно используются для отслеживания предпочтений пользователя (например, тема, язык) или поведенческих флагов (завершение онбординга, использование функций). Формат — пары «ключ — значение», где ключи являются строками, а значения могут быть строками или числами (например, {"Favourite_color": "Violet", "Pet_name": "Fluffy"}). Пользовательские атрибуты можно задавать вручную в дашборде Adapty для отдельных профилей, программно с помощью метода updateProfile в SDK Adapty или через серверный API при создании/обновлении профилей. Включается, если в настройках вебхука включён параметр Send User Attributes. Хотя в коде мобильного приложения значения пользовательских атрибутов можно задавать как числа с плавающей точкой или строки, атрибуты, полученные через серверный API или при историческом импорте, могут приходить в других форматах. В таком случае булевы и целочисленные значения будут преобразованы в числа с плавающей точкой. |
Атрибуции
Чтобы отправлять данные атрибуции, включите опцию Send Attribution на странице Integrations -> Webhooks. Если вы включили отправку данных атрибуции и настроили интеграции атрибуции, приведённые ниже данные будут отправляться с каждым событием для всех источников. Одни и те же данные атрибуции передаются со всеми типами событий.
{
"attributions": {
"appsflyer": {
"ad_set": "sample_ad_set_123",
"status": "non_organic",
"channel": "sample_channel",
"ad_group": "sample_ad_group_456",
"campaign": "sample_ios_campaign",
"creative": "sample_creative_789",
"created_at": "2000-01-31T00:00:00.000000+0000",
"network_user_id": "0000000000000-0000000"
}
}
}
| Название поля | Тип поля | Описание |
|---|---|---|
| ad_set | String | Набор объявлений атрибуции. |
| status | String | Может быть organic, non_organic, или unknown. |
| channel | String | Название маркетингового канала. |
| ad_group | String | Группа объявлений атрибуции. |
| campaign | String | Название маркетинговой кампании. |
| creative | String | Ключевое слово креатива атрибуции. |
| created_at | ISO 8601 date | Дата и время создания записи атрибуции. |
| network_user_id | String | ID пользователя, присвоенный источником атрибуции. |
Идентификаторы интеграций
Следующие идентификаторы интеграций используются в событиях:
adjust_device_idairbridge_device_idamplitude_device_idamplitude_user_idappmetrica_device_idappmetrica_profile_idappsflyer_idbranch_idfacebook_anonymous_idfirebase_app_instance_idmixpanel_user_idpushwoosh_hwidone_signal_player_idone_signal_subscription_idtenjin_analytics_installation_idposthog_distinct_user_id
Токен покупки Play Store
Это поле содержит все данные, необходимые для повторной валидации покупки. Оно отправляется только если опция Send Play Store purchase token включена в настройках интеграции с Webhook.
| Поле | Тип | Описание |
|---|---|---|
| product_id | String | Уникальный идентификатор продукта (SKU), приобретённого в Play Store. |
| purchase_token | String | Токен, сгенерированный Google Play для уникальной идентификации транзакции покупки. |
| is_subscription | Boolean | Указывает, является ли купленный продукт подпиской (true) или разовой покупкой (false). |
Свойства событий
Свойства событий могут различаться в зависимости от типа события и даже между событиями одного типа. Например, событие из App Store не будет включать специфичные для Android свойства, такие как base_plan_id.
Событие Access Level Updated имеет особые свойства, поэтому мы вынесли его в отдельный раздел. Аналогично мы выделили дополнительные свойства событий, связанных с налогами и выручкой, поскольку они характерны лишь для определённых типов событий.
Для большинства типов событий
Свойства событий для большинства типов одинаковы (за исключением события Access Level Updated, которое описано в отдельном разделе). Ниже приведена полная таблица свойств с указанием того, к каким событиям они относятся.
| Поле | Тип | Описание |
|---|---|---|
| ab_test_name | String | Название A/B-теста Adapty, в котором произошла транзакция. |
| ab_test_revision | Integer | Ревизия A/B-теста, в котором произошла транзакция. |
| base_plan_id | String | Идентификатор базового плана в Google Play Store или идентификатор цены в Stripe. |
| cancellation_reason | String | Возможные причины отмены: Присутствует в следующих типах событий: subscription_cancelled, subscription_refunded и trial_cancelled. |
| cohort_name | String | Название аудитории, которая определила, какой пейвол был показан пользователю. |
| consecutive_payments | Integer | Количество периодов, в течение которых пользователь непрерывно подписан. Включает текущий период. |
| currency | String | Локальная валюта. |
| developer_id | String | Идентификатор плейсмента, в котором произошла транзакция. |
| environment | String | Возможные значения: Sandbox или Production. |
| event_datetime | ISO 8601 date | Дата и время события. Совпадает со значением на корневом уровне события. |
| original_purchase_date | ISO 8601 date | Для возобновляемых подписок исходная покупка — это первая транзакция в цепочке; её ID (original transaction ID) связывает всю цепочку продлений, а последующие транзакции являются её продолжением. Дата исходной покупки — это дата и время этой первой транзакции. |
| original_transaction_id | String | Для возобновляемых подписок — идентификатор исходной транзакции, связывающий цепочку продлений. Исходная транзакция — первая в цепочке; последующие транзакции являются её продолжением. Если продлений не было, |
| paywall_name | String | Название пейвола, в котором произошла транзакция. |
| paywall_revision | String | Ревизия пейвола, в котором произошла транзакция. Значение по умолчанию — 1. |
| price_local | Float | Цена продукта до вычета комиссии Apple/Google в локальной валюте. |
| price_usd | Float | Цена продукта до вычета комиссии Apple/Google в USD. |
| profile_country | String | Определяется Adapty на основе IP-адреса профиля. |
| profile_event_id | UUID | Уникальный идентификатор события, который можно использовать для дедупликации. |
| profile_has_access_level | Boolean | Булево значение, указывающее, есть ли у профиля активный уровень доступа. |
| profile_id | UUID | Идентификатор профиля, сгенерированный Adapty. Совпадает со значением на корневом уровне события. |
| profile_ip_address | String | IP-адрес профиля (может быть IPv4 или IPv6; при наличии предпочитается IPv4). null, если в настройках приложения отключён параметр Collect users’ IP addresses. |
| profile_total_revenue_usd | Float | Общий доход по профилю с учётом вычета возвратов. |
| promotional_offer_id | String | Идентификатор promotional offer в Adapty. Вы задаёте этот ID при создании офера в дашборде. |
| purchase_date | ISO 8601 date | Дата и время покупки продукта. |
| rate_after_first_year | Boolean | Булево значение, указывающее, что подписка соответствует условиям сниженной комиссии (как правило, 15%) после одного года непрерывных продлений. Размер комиссии зависит от участия в программах и страны. Подробнее см. в разделе Комиссия стора и налоги. |
| store | String | Стор, в котором был куплен продукт. Стандартные значения: app_store, play_store, stripe, paddle. Если вы устанавливаете транзакции через собственный стор с помощью серверного API, используется значение из параметра store. |
| store_country | String | Страна, переданная нам сторем. |
| store_offer_category | String | Применённая категория офера. Возможные значения: introductory, promotional, winback. |
| store_offer_discount_type | String | Применённый тип офера. Возможные значения: free_trial, pay_as_you_go, pay_up_front. |
| subscription_expires_at | ISO 8601 date | Дата истечения срока действия подписки. Обычно в будущем. |
| transaction_id | String | Уникальный идентификатор транзакции. |
| trial_duration | String | Длительность пробного периода в днях. Передаётся в формате « days», например «7 days». Присутствует только в событиях, связанных с пробным периодом: trial_started, trial_converted, trial_cancelled. |
| variation_id | UUID | Уникальный идентификатор пейвола, в котором была совершена покупка. |
| vendor_product_id | String | Идентификатор продукта в Apple App Store, Google Play Store или Stripe. |
Дополнительные свойства события, связанные с налогами и выручкой
Перечисленные ниже свойства событий, связанные с налогами и выручкой, — это дополнительные поля, которые применяются только к определённым типам событий. Это означает, что указанные типы событий включают свойства событий для большинства типов событий, а также дополнительные поля, перечисленные ниже.
Типы событий, которые содержат свойства событий, связанные с налогами и выручкой:
subscription_renewedsubscription_initial_purchasesubscription_refundednon_subscription_purchase| Поле | Тип | Описание | | :-------------------- | :---- | :----------------------------------------------------------- | | net_revenue_local | Float | Чистая выручка (доход после вычета комиссии Apple/Google и налогов) в локальной валюте. | | net_revenue_usd | Float | Чистая выручка (доход после вычета комиссии Apple/Google и налогов) в USD. | | proceeds_local | Float | Цена продукта после вычета комиссии Apple/Google в локальной валюте. | | proceeds_usd | Float | Цена продукта после вычета комиссии Apple/Google. | | tax_amount_local | Float | Сумма удержанного налога в локальной валюте. | | tax_amount_usd | Float | Сумма удержанного налога в USD. |
Для события Access Level Updated
Событие Access Level Updated — это специфическое webhook-событие, которое генерируется только когда интеграция Webhook активна и данный тип события включён. Если оно включено, событие отправляется на настроенный Webhook и отображается в Event Feed. Если не включено, событие не создаётся.
Если вы включили совместное использование уровней доступа, событие access level updated будет отправлено для всех профилей, использующих общий уровень доступа.
Используйте это событие, чтобы обновить уровень доступа пользователя в своей базе данных, предоставить или отозвать доступ к премиум-функциям на бэкенде и синхронизировать доступ между устройствами и платформами.
| Свойство | Тип | Описание |
|---|---|---|
| ab_test_name | String | Название A/B-теста, в рамках которого была совершена транзакция. |
| access_level_id | String | Идентификатор уровня доступа. |
| activated_at | ISO 8601 date | Дата и время последней активации доступа. |
| active_introductory_offer_type | String | Тип применённого introductory offer. Возможные значения: free_trial, pay_as_you_go, pay_up_front. |
| active_promotional_offer_id | String | Идентификатор promotional offer, указанный в разделе Product дашборда Adapty. |
| active_promotional_offer_type | String | Тип применённого promotional offer. Возможные значения: free_trial, pay_as_you_go, pay_up_front. |
| base_plan_id | String | Идентификатор базового плана в Google Play Store или идентификатор цены в Stripe. |
| billing_issue_detected_at | ISO 8601 date | Дата и время обнаружения проблемы с оплатой. |
| cancellation_reason | String | Возможные причины отмены: voluntarily_cancelled, billing_error, price_increase, product_was_not_available, refund, cancelled_by_developer, new_subscription_replace, upgraded, unknown, adapty_revoked. |
| cohort_name | String | Название аудитории, к которой относится профиль. |
| currency | String | Местная валюта (по умолчанию USD). |
| developer_id | String | Идентификатор плейсмента, в рамках которого была совершена транзакция. |
| environment | String | Возможные значения: Sandbox или Production. |
| event_datetime | ISO 8601 date | Дата и время события. |
| expires_at | ISO 8601 date | Дата и время истечения доступа. |
| is_active | Boolean | Признак активности уровня доступа. |
| is_in_grace_period | Boolean | Признак того, что профиль находится в льготном периоде. |
| is_lifetime | Boolean | Признак того, что уровень доступа является пожизненным. |
| is_refund | Boolean | Признак того, что транзакция является возвратом средств. |
| original_purchase_date | ISO 8601 date | Для возобновляемых подписок оригинальная покупка — это первая транзакция в цепочке; её идентификатор (original transaction ID) связывает все последующие продления. Дата оригинальной покупки — это дата и время этой первой транзакции. |
| original_transaction_id | String | Для возобновляемых подписок — идентификатор оригинальной транзакции, связывающий цепочку продлений. Оригинальная транзакция является первой в цепочке; последующие транзакции являются её продолжением. Если продлений не было, |
| paywall_name | String | Название пейвола, в рамках которого была совершена транзакция. |
| paywall_revision | String | Ревизия пейвола, в рамках которого была совершена транзакция. Значение по умолчанию — 1. |
| profile_country | String | Определяется Adapty на основе IP-адреса профиля. |
| profile_event_id | UUID | Уникальный идентификатор события, который можно использовать для дедупликации. |
| profile_has_access_level | Boolean | Признак наличия у профиля активного уровня доступа. |
| profile_id | UUID | Внутренний идентификатор профиля пользователя в Adapty. |
| profile_ip_address | String | IP-адрес профиля пользователя. |
| profile_total_revenue_usd | Float | Общий доход по профилю с учётом возвратов. |
| purchase_date | ISO 8601 date | Дата и время покупки продукта. |
| renewed_at | ISO 8601 date | Дата и время следующего продления доступа. |
| starts_at | ISO 8601 date | Дата и время начала действия уровня доступа. |
| store | String | Стор, в котором был куплен продукт. Стандартные значения: app_store, play_store, stripe, paddle. Если вы задаёте пользовательские транзакции стора через серверный API, используется значение из параметра store. |
| store_country | String | Страна, переданная в Adapty магазином приложений. |
| subscription_expires_at | ISO 8601 date | Дата истечения срока действия подписки. |
| transaction_id | String | Уникальный идентификатор транзакции. |
| trial_duration | String | Продолжительность пробного периода в днях (например, «7 days»). |
| variation_id | UUID | Идентификатор варианта, используемый для атрибуции покупок к данному пейволу. |
| vendor_product_id | String | Идентификатор продукта в сторе (Apple/Google/Stripe). |
| will_renew | Boolean | Признак того, что платный уровень доступа будет продлён. |
Обратите внимание, что эта структура может расширяться со временем — по мере добавления новых данных нами или сторонними сервисами, с которыми мы интегрированы. Убедитесь, что ваш код, обрабатывающий эту структуру, достаточно устойчив и опирается на конкретные поля, а не на всю структуру целиком.