Совершение покупок в мобильном приложении через Capacitor SDK
Отображение пейволов в вашем мобильном приложении — необходимый шаг для предоставления пользователям доступа к премиум-контенту или сервисам. Однако само по себе отображение пейвола поддерживает покупки только в том случае, если Adapty отрисовывает экран — то есть когда используется флоу или пейвол из старого Paywall Builder.
Если вы отрисовываете экран самостоятельно, для совершения покупки и открытия нужного контента необходимо использовать отдельный метод .makePurchase(). Именно через него пользователи взаимодействуют с пейволами и выполняют нужные транзакции.
Если ваш пейвол содержит активный promotional offer для продукта, который пользователь хочет купить, Adapty автоматически применит его в момент покупки.
Убедитесь, что вы выполнили начальную настройку, не пропустив ни одного шага. Без неё мы не сможем валидировать покупки.
Совершение покупки
Adapty отображает ваш экран? Для флоу или пейвола, созданного с помощью Paywall Builder, покупки обрабатываются автоматически — этот шаг можно пропустить.
Нужна пошаговая инструкция? Ознакомьтесь с гайдом по быстрому старту — там есть полное руководство по реализации с подробным контекстом.
try {
const result = await adapty.makePurchase({ product });
if (result.type === 'success') {
const isSubscribed = result.profile?.accessLevels?.['YOUR_ACCESS_LEVEL']?.isActive;
if (isSubscribed) {
// Grant access to the paid features
console.log('User is now subscribed!');
}
} else if (result.type === 'user_cancelled') {
console.log('Purchase cancelled by user');
} else if (result.type === 'pending') {
console.log('Purchase is pending');
}
} catch (error) {
console.error('Purchase failed:', error);
}
| Параметр | Наличие | Описание |
|---|---|---|
| product | required | Объект AdaptyPaywallProduct, полученный из флоу через getPaywallProducts. |
Параметры ответа:
| Параметр | Описание |
|---|---|
| result | Объект AdaptyPurchaseResult с полем type, указывающим результат покупки ('success', 'user_cancelled' или 'pending'), и полем profile, содержащим обновлённый AdaptyProfile при успешной покупке. |
Смена подписки при совершении покупки
Когда пользователь выбирает новую подписку вместо продления текущей, поведение зависит от стора:
- В App Store подписка обновляется автоматически в рамках группы подписок. Если пользователь приобретает подписку из одной группы, уже имея активную подписку из другой, обе подписки будут активны одновременно.
- В Google Play подписка не обновляется автоматически. Вам нужно будет управлять переходом в коде мобильного приложения, как описано ниже.
Чтобы заменить одну подписку на другую в Android, вызовите метод .makePurchase() с дополнительным параметром:
try {
const result = await adapty.makePurchase({
product,
params: {
android: {
subscriptionUpdateParams: {
oldSubVendorProductId: 'old_product_id',
prorationMode: 'charge_prorated_price'
},
isOfferPersonalized: true
}
}
});
if (result.type === 'success') {
const isSubscribed = result.profile?.accessLevels?.['YOUR_ACCESS_LEVEL']?.isActive;
if (isSubscribed) {
// Grant access to the paid features
console.log('Subscription updated successfully!');
}
} else if (result.type === 'user_cancelled') {
console.log('Purchase cancelled by user');
} else if (result.type === 'pending') {
console.log('Purchase is pending');
}
} catch (error) {
console.error('Purchase failed:', error);
}
Дополнительный параметр запроса:
| Параметр | Наличие | Описание |
|---|---|---|
| params | опционально | Объект типа MakePurchaseParamsInput, содержащий платформо-зависимые параметры покупки. |
Структура MakePurchaseParamsInput включает:
{
android: {
subscriptionUpdateParams: {
oldSubVendorProductId: 'old_product_id',
prorationMode: 'charge_prorated_price'
},
isOfferPersonalized: true
}
}
Подробнее о подписках и режимах замены можно прочитать в документации Google для разработчиков:
- О режимах замены
- Рекомендации Google по режимам замены
- Режим замены
CHARGE_PRORATED_PRICE. Примечание: этот метод доступен только для повышения уровня подписки. Понижение уровня не поддерживается. - Режим замены
DEFERRED. Примечание: фактическая смена подписки произойдёт только по окончании текущего расчётного периода.
Управление предоплаченными планами (Android)
Если пользователи вашего приложения могут приобретать предоплаченные планы (например, покупать неавтоматически возобновляемую подписку на несколько месяцев), вы можете включить ожидающие транзакции для таких планов.
await adapty.activate({
apiKey: 'YOUR_PUBLIC_SDK_KEY',
params: {
android: {
pendingPrepaidPlansEnabled: true,
},
}
});
Активация промокодов в iOS
Об offer-кодах
Offer-коды позволяют предоставлять скидки или бесплатные пробные периоды конкретным пользователям. В отличие от обычных предложений, которые применяются автоматически, offer-коды распространяются за пределами приложения — через email-рассылки, соцсети или печатные материалы. Пользователи активируют их, вводя код в App Store, переходя по ссылке для активации или через диалог внутри приложения.
Чтобы настроить offer-коды, откройте подписку в App Store Connect и перейдите в раздел Offer Codes. Вы можете создать три вида offer-кодов:
- Free — подписка бесплатна в течение заданного срока, следующее продление — по полной цене.
- Pay as you go — пользователь платит сниженную цену за каждый расчётный период в течение заданного срока, затем подписка продлевается по полной цене.
- Pay up front — пользователь единовременно платит сниженную цену за весь срок предложения, затем подписка продлевается по полной цене.
Добавлять offer-коды в Adapty не нужно. Apple помечает каждую транзакцию в течение периода предложения категорией offer-кода. Это касается как первоначальной активации, так и всех последующих продлений со скидкой. Adapty обнаруживает метку и записывает каждую транзакцию с категорией предложения offer_code. Когда период предложения заканчивается и подписка продлевается по полной цене, метка больше не проставляется. Вы можете фильтровать аналитику по типу предложения Offer Code в дашборде Adapty.
Устранение расхождений в выручке
Если транзакция по offer-коду отображается в Adapty по полной цене продукта вместо сниженной, проверьте следующее в App Store Connect:
- Для offer-кода настроены корректные цены для всех регионов, где пользователи могут его активировать.
- Цена предложения задана для конкретной страны или региона пользователя. Apple передаёт региональную цену в транзакции. Если для предложения не указана региональная цена, Apple может передать полную цену продукта.
Вы можете фильтровать и проверять транзакции по offer-кодам в дашборде Adapty с помощью фильтров по типу предложения Offer Code и Offer Discount Type.
Устаревшие промокоды (deprecated)
Apple отказалась от промокодов для встроенных покупок в марте 2026 года. Offer-коды заменяют их с расширенными возможностями: настраиваемые условия применения, сроки действия и до 1 миллиона кодов в квартал. Если вы ранее использовали промокоды для встроенных покупок, перейдите на offer-коды в App Store Connect.
Устаревшие промокоды (не более 100 на приложение на версию) предоставляли бесплатный доступ к подписке. В отличие от offer-кодов, Apple не включала информацию о скидке в транзакции по промокодам — в чеке передавалась полная цена продукта. В результате Adapty записывал эти транзакции по полной цене, что приводило к расхождениям в выручке между аналитикой Adapty и App Store Connect.
Если вы видите исторические транзакции по полной цене, которые должны были быть бесплатными, скорее всего, они относятся к устаревшим промокодам. Поскольку такие коды теперь устарели, переходите на offer-коды для точного учёта выручки.
Чтобы отобразить экран активации промокода в вашем приложении:
try {
await adapty.presentCodeRedemptionSheet();
} catch (error) {
console.error('Failed to present code redemption sheet:', error);
}
По нашим наблюдениям, экран активации промокода в некоторых приложениях может работать нестабильно. Рекомендуем перенаправлять пользователя напрямую в App Store.
Чтобы сделать это, нужно открыть URL следующего формата:
https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}
Продвигаемые встроенные покупки из App Store
Ваше приложение может перехватывать продвигаемые встроенные покупки начиная с версии SDK 4.1.1 на iOS 16.4 и выше. На версиях ниже iOS 16.4 событие не срабатывает, и продвигаемые покупки завершаются самостоятельно. Событие также не срабатывает на Android.
Когда пользователь начинает покупку со страницы вашего приложения в App Store и транзакция переходит в приложение, SDK завершает её автоматически — экран покупки Apple появляется сразу, и Adapty обрабатывает транзакцию как обычную покупку. Никакого кода с вашей стороны не требуется.
Если продвигаемый продукт содержит предложение подписки, SDK применяет его при покупке автоматически. Предложение считывается из намерения покупки App Store, которое предоставляет его начиная с iOS 18.0 и выше. На iOS 16.4–17.x покупка проходит по базовой цене.
Чтобы самостоятельно управлять завершением покупки — например, сначала показать свой экран — подпишитесь на событие 'onPromotedPurchaseReceived' и передайте продукт в makePromotedPurchase:
const listener = await adapty.addListener('onPromotedPurchaseReceived', async ({ product }) => {
const result = await adapty.makePromotedPurchase({ product });
// process the purchase result
});
Пока ваш обработчик зарегистрирован, SDK прекращает самостоятельно завершать promoted purchases. Если ваш обработчик никогда не вызывает makePromotedPurchase, покупка не произойдёт: App Store передаёт продукт вашему приложению и ждёт.
makePromotedPurchase не принимает параметры покупки — promoted product поступает из App Store, а не из пейвола, поэтому не содержит контекста пейвола. Метод возвращает тот же AdaptyPurchaseResult, что и makePurchase.
Вызов adapty.removeAllListeners() удаляет слушатель промо-покупок вместе со всеми остальными, после чего SDK снова берёт на себя автоматическое завершение. Зарегистрируйте слушатель повторно, если приложение по-прежнему должно управлять завершением самостоятельно.