9.0.1
RuStore позволяет интегрировать платежи в мобильное приложение.
-
Если не знаете с чего начать, прочтите инструкцию в сцен ариях использования.
-
Если вы переходите на Pay SDK с billingClient SDK, ознакомьтесь с инструкцией по переходу. Подробности о Pay SDK можно узнать тут.
Условия работы платежей
- Для приложения включена возможность покупок в RuStore Консоли.
- Приложение не должно быть заблокировано в RuStore.
- Пользователь не должен быть заблокирован в RuStore.
Подготовка к работе
Для подключения пакета платежей к проекту выполните следующую команду.
flutter pub add flutter_rustore_pay
Инициализация
Перед вызовом методов библиотеки необходимо выполнить её инициализацию. Сама инициализация происходит автоматически, но для работы SDK в вашем файле AndroidManifest.xml
необходимо прописать console_app_id_value
.
<meta-data
android:name="console_app_id_value"
android:value="@string/CONSOLE_APPLICATION_ID" />
В strings.xml
замените строку с вашим app_id
.
<string name="CONSOLE_APPLICATION_ID">your_app_id</string>
CONSOLE_APPLICATION_ID
— идентификатор приложения из RuStore консоли.
Где в RuStore Консоль отображаются идентификаторы приложений?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Скопируйте идентификатор из URL-адреса страницы приложения — это набор цифр между
apps/
и/versions
. Например, для URL-адресаhttps://console.rustore.ru/apps/123456/versions
ID приложения —123456
.
ApplicationId
, указанный в build.gradle
, должен совпадать с applicationId
APK-файла, который вы публиковали в RuStore Консоль.
Обработка deeplinks
Обработка deeplink в RuStore SDK позволяет эффективно взаимодействовать со сторонними приложениями, при проведении платежей через б анковские приложения (СБП, SberPay, T-Pay и др.). Это позволяет перевести пользователя на экран оплаты, а после завершения транзакции — вернуть в ваше приложение.
Для настройки работы с deeplink в вашем приложении и Pay SDK, укажите deeplinkScheme
с помощью sdk_pay_scheme_value
в AndroidManifest.xml
файле.
При использовании deeplinks указание схемы является обязательным. При попытке платежа без указания схемы будет возникать ошибка.
Указание deeplinkScheme:
<activity
android:name=".sample.MainActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/SDK_PAY_SCHEME" /> />
</intent-filter>
<meta-data
android:name="sdk_pay_scheme_value"
android:value="@string/SDK_PAY_SCHEME" />
</activity>
Не забудьте указать строку с вашей SDK_PAY_SCHEME
в файле strings.xml
.
Для восстановления состояния вашего приложения при возврате с deeplink добавьте в
AndroidManifest.xml
атрибут android:launchMode="singleTask"
.
Указание launchMode:
<activity
android:name=".YourBillingActivity"
android:launchMode="singleTask"
android:exported="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
Работа с SDK
В SDK доступны следующие публичные интеракторы:
PurchaseInteractor
— интерактор, который позволяет работать с платежами и имеет несколько публичных методов:getPurchase(purchaseId: PurchaseId): Task<Purchase>
- позволяет получить информацию о покупке по её идентификатору;getPurchases(): Task<List<Purchase>>
- позволяет получить покупки пользователя. В списке возвращаются покупки в статусеCONFIRMED
для непотребляемых товаров иPAID
(статус, означающий холдирование средств и о жидающих подтверждения покупки со стороны разработчика);getPurchaseAvailability(): Task<PurchaseAvailabilityResult>
- возвращает результат доступности работы с платежами;consumePurchase(purchaseId: PurchaseId, developerPayload: DeveloperPayload? = null)
— позволяет совершить потребление покупки (только для потребляемых товаров).
ProductInteractor
— интерактор, который позволяет работать с продуктами и имеет несколько публичных методов:-
getProducts(productsId: List<ProductId>): Task<List<Product>>
— позволяет получить информацию по продуктам по их ID.
(Важно! Метод имеет ограничение в 1000 продуктов) -
purchase(params: ProductPurchaseParams): Task<ProductPurchaseResult>
— позволяет совершить покупку продукта
-
UserInteractor
- интерактор, который позволяет получить статус авторизации пользователяUserAuthorizationStatus
с помощью методаgetUserAuthorizationStatus()
. У данной модели может быть 2 состояния:AUTHORIZED
- пользователь авторизован в RuStoreUNAUTHORIZED
- пользователь неавторизован в RuStore. Данное значение также вернется если у пользователя нет установленного RuStore на девайсе.
Также доступен RuStoreUtils
— блок, включающий набор публичных методов:
isRuStoreInstalled
— проверки наличия приложения RuStore на девайсе пользователя;openRuStore
— запускает мобильное приложение RuStore;openRuStoreAuthorization
— запускает мобильное приложение RuStore для авторизации, после успешной авторизации пользователя мобильное приложение RuStore автоматически закроется;openRuStoreDownloadInstruction
— открывает веб-страницу для скачивания мобильного приложения RuStore.
Проверка доступности работы с платежами
Для проверки доступности платежей, вызовите метод getPurchaseAvailability
. При его вызове проверяются следующие условия.
- Для приложения включена возможность покупок в RuStore Консоли.
- Пользователь и приложение не должны быть заблокированы в RuStore.
PurchaseAvailabilityResponse.Available
.
В противном случае возвращается PurchaseAvailabilityResponse.Unavailable(val cause: Throwable)
, где cause
— это ошибка о невыполненном условии.
RuStorePayClient.instance.purchaseInteractor.getPurchaseAvailability().then((value) {
if (value case Available _) {
// Process purchases available
} else if (value case Unavailable unavailable) {
// Process purchases unavailable
}
});
Проверка статуса авторизации пользователя
Для проверки статуса авторизации пользователя, вызовите метод getUserAuthorizationStatus
у UserInteractor
.
Результатом выполнения метода является класс UserAuthorizationStatus
. Доступно 2 значения:
AUTHORIZED
- пользователь авторизован в RuStoreUNAUTHORIZED
- пользователь неавторизован в RuStore. Данное значение также вернется если у пользователя нет установленного RuStore на девайсе.
RuStorePayClient.instance.userInteractor.getUserAuthorizationStatus().then((value) {
if (value case Authorized _) {
// Process authorized
} else if (value case Unauthorized _) {
// Process unauthorized
}
});
Получение списка продуктов
Для получения продуктов, добавленных в ваше приложение через RuStore консоль, необходимо использовать метод getProducts
.
RuStorePayClient.instance.productInteractor.getProducts(productIds).then((response) {
for (final product in response.products) {
print(product?.productId);
}
}, onError: (err) {
print("products err: $err");
}
);
productIds: List<ProductId>
— список идентификаторов продуктов (задаются при создании продукта в консоли разработчика). Список продуктов имеет ограничение в размере 1000 элементов.
Где в RuStore Консоль отображаются идентификаторы продуктов?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Выберите Монетизация в меню слева.
- Выберите тип товара: Подписки или Разовые покупки.
- Скопируйте идентификаторы нужных товаров.
Метод возвращает список продуктов. Ниже представлена модель продукта.
class Product {
String productId;
ProductType type;
String amountLabel;
int? price;
String currency;
String imageUrl;
String title;
String? description;
}
productId
— идентификатор продукта, который был присвоен продукт у в RuStore Консоли (обязательный параметр).type
— тип продукта.CONSUMABLE/NON-CONSUMABE
(потребляемый/непотребляемый).amountLabel
— отформатированная цена покупки, включая валютный знак.price
— цена в минимальных единицах (в копейках).currency
— код валюты ISO 4217.title
— название продукта на языкеlanguage
.description
— описание на языкеlanguage
.imageUrl
— ссылка на картинку.
Структура ProductType
.
enum ProductType {
consumable,
nonConsumable,
}
consumable
— потребляемый (можно купить много раз, например: кристаллы в приложении);nonConsumable
— непотребляемый (можно купить один раз, например: отключение рекламы в приложении);
Покупка продукта
При использовании одностадийного платежа покупка не требует подтверждения, денежные средства сразу списываются со счета покупателя, а с разработчика удерживается комиссия.
В таком случае, если требуется вернуть денежные средства клиенту (например, по какой-то причине нет возможности выдать продукт), возможен только возврат средств через консоль разработчика, денежные средства возвращаются покупателю через несколько дней. Возвращается полная стоимость покупки, при этом удержанная комиссия разработчику не возмещается.
Одностадийная оплата (без холдирования средств)
Для вызова покупки продукта с выбором стадийности оплаты используйте метод purchase(id):
RuStorePayClient.instance.purchaseInteractor
.purchase(id).then((value) {
// Process success
});
- У метода есть не опциональные и опциональные параметры:
productId
- идентификатор продукта, который требуется приобрести (обязательный параметр).quantity
- количество продуктов - опционально. Если не указывать, то будет подставлено значение 1. Применимо только для покупки потребляемых товаров.orderId
- идентификатор заказа, создаётся на стороне приложения - опционально. Если не указан, то генерируется автоматически. Максимальная длина 150 символовdeveloperPayload
- дополнительная информация от разработчика приложения (опционально). Максимальная длина 250 символовappUserId
- внутренний ID пользователя в приложении - опционально. Максимальная длина 128 символовpreferredPurchaseType
- желаемый тип покупки - одностадийная (ONE_STEP
) или двухстадийная (TWO_STEP
) (опциональный параметр, по умолчаниюONE_STEP
).appUserEmail
— это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemail
при отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.
Структура PreferredPurchaseType
:
enum PreferredPurchaseType {
oneStep,
twoStep
}
Метод возвращает ProductPurchaseResult
:
Данный метод по умолчанию запускается по одностадийному сценарию оплаты (preferredPurchaseType = PreferredPurchaseType.oneStep), т.е. без холдирования средств. Для двухстадийной оплаты нужно указать preferredPurchaseType = PreferredPurchaseType.TWO_STEP. Двухстадийная оплата (т.е. оплата с холдированием средств) для данного метода - негарантированная, и напрямую будет зависеть от того, какой способом оплаты (карта, СПБ и др.) будет выбран пользователем.
Не все способы оплаты поддерживают двустадийную оплату.
Двухстадийная оплата (с холдированием средств)
В случае использования двухстадийного платежа сначала производится холд ирование средств на счете покупателя. Комиссия в этом случае не удерживается. После холдирования покупка требует подтверждения или отмены. Комиссия с разработчика удерживается при подтверждении покупки. Отмена покупки означает снятие холда - денежные средства мгновенно снова доступны покупателю.
При вызове данного метода пользователю будет доступен ограниченный набор способов оплаты - только те, которые поддерживают двухстадийную оплату
Для вызова покупки продукта используйте метод purchaseTwoStep(id)
:
RuStorePayClient.instance.purchaseInteractor.purchaseTwoStep(id).then((value) {
// Process success
});
- У метода есть не опциональные и опциональные параметры:
productId
- идентификатор продукта (обязательный параметр).quantity
- количество продуктов - опционально. Если не указывать, то будет подставлено значение 1. Применимо только для покупки потребляемых товаров.orderId
- идентификатор заказа, создаётся на стороне приложения. (опционально. Если не указан, то генерируется автоматически). Максимальная длина 150 символовdeveloperPayload
- дополнительная информация от разработчика приложения (опционально). Максимальная длина 250 символовappUserId
- внутренний ID пользователя в приложении - опционально. Максимальная длина 128 символовappUserEmail
— это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemail
при отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.
Метод возвращает ProductPurchaseResult
:
С труктура результата покупки ProductPurchaseResult:
class ProductPurchaseResult {
Success? success;
Cancelled? cancelled;
Failure? failure;
}
Структура Success
:
class Success {
String? orderId;
String purchaseId;
String productId;
String invoiceId;
PurchaseType purchaseType;
bool sandbox;
}
Структура Cancelled
:
class Cancelled {
String? purchaseId;
PurchaseType purchaseType;
}
Структура Failure
:
class Failure {
String? orderId;
String? purchaseId;
String? productId;
String? invoiceId;
int? quantity;
String errorMessage;
PurchaseType purchaseType;
bool sandbox;
}
SuccessProductPurchaseResult
- результат успешного завершения покупки цифрового товара.FailureProductPurchaseResult
- результат ошибки покупки цифрового товара.CancelProductPurchaseResult
- платёжный диалог закрыт до получения результата покупки. Состояние покупки неизвестно. Рекомендуем запросить статус покупки отдельно методом получения информации о покупке.
purchaseId
- идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупке.productId
- идентификатор приобретенного продукта, указанный при создании в консоли разработчика RuStore.invoiceId
- идентификатор счета. Используется для серверной валидации платежа, поиска платежей в консоли разработчика, а также отображается покупателю в истории платежей в мобильном приложении RuStore.orderId
- уникальный идентификатор оплаты, указанный разработчиком или сформированный автоматически (uuid).purchaseType
- тип покупки (ONE_STEP
/TWO_STEP
/UNDEFINED
- одностадийная/двухстадийная/стадийность не определена).quantity
- количество продуктов - опционально. Если не указывать, то будет подставлено значение 1. Применимо только для покупки потребляемых товаров.sandbox
- флаг, указывающий признак тестового платежа в песочнице. Если TRUE - покупка совершена в режиме тестирования.errorMessage
- сообщение с причиной ошибки.
Получение списка покупок
Для получения списка покупок пользователя используйте метод getPurchases
.
Для получения списка покупок необходимо использовать метод getPurchases({ProductType? productType})
Данный метод поддерживает опциональную фильтрацию по типу товаров (потребляемые или непотреблямые товары). По умолчанию фильтр выключен и вернет всё покупки пользователя (в не зависимости от типа товара) в статусах paid и confirmed.
Статус paid
означает успешное холдирование средств, покупка ожидает подтверждения покупки со стороны разработчика.
RuStorePayClient.instance.purchaseInteractor.getPurchases().then((purchases) {
// Process success
});
class Purchase {
String purchaseId;
String productId;
String invoiceId;
String? orderId;
PurchaseType purchaseType;
ProductType productType;
String description;
String? purchaseTime;
int price;
String amountLabel;
String currency;
int quantity;
PurchaseStatus status;
String? developerPayload;
bool sandbox;
}
purchaseId
— идентификатор покупки.productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).invoiceId
— иден тификатор счёта.orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.purchaseType
— тип покупки.productType
— тип продукта (потребляемый / непотребляемый / подписка):CONSUMABLE
/NON-CONSUMABE
/SUBSCRIPTION
.description
— описание на языкеlanguage
.purchaseTime
— время покупки.price
— цена в минимальных единицах (в копейках).amountLable
— отформатированная цена покупки, включая валютный знак.currency
— код валюты ISO 4217.quantity
— количество продукта. Необязательный параметр со стандартным значением1
. Применим только к покупке потребляемых товаров.purchaseState
— состояние покупки:INVOICE_CREATED
— создан счёт на оплату, покупка ожидает оплаты;CANCELLED
— покупка отменена покупателем;PROCESSING
— запущена оплата;-
REJECTED
— покупка отклонена (например, ввиду недостатка средств) PAID
— только для двухстадийной оплаты, промежуточный статус, средства на счёте покупателя захолдированы, покупка ожидает подтверждения от разработчика;CONFIRMED
— покупка успешно оплачена;REFUNDED
— запрос на возврат средств за покупку совершён успешно;REVERSED
— только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 6 часов, холдирование средств отменено.
developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки.
Структура PurchaseType
.
enum PurchaseType {
oneStep,
twoStep,
}
Получение сведений о покупке
Для получения информации о покупке, используйте методgetPurchase
.
RuStorePayClient.instance.purchaseInteractor.getPurchase(purchaseId).then((purchase) {
// Process success
});
Метод возвращает информацию о конкретной покупке в любом статусе. Ниже представлена модель покупки.
class Purchase {
String purchaseId;
String productId;
String invoiceId;
String? orderId;
PurchaseType purchaseType;
ProductType productType;
String description;
String? purchaseTime;
int price;
String amountLabel;
String currency;
int quantity;
PurchaseStatus status;
String? subscriptionToken;
String? developerPayload;
}
Статусная модель покупки
Статусная модель одностадийного платежа.
Статусная модель двухстадийного платежа.
Подтверждение (потребление) покупки
Подтверждения требуют только покупки, которые были запущены по двухстадийному сценарию оплаты, т.е. с
холдированием средств. Такие покупки, после успешного холдирования будут находиться в статусе PurchaseStatus.paid.
.
Для списания средств с карты покупателя требуется подтверждение покупки.
Для этого вы должны использовать метод confirmTwoStepPurchase
.
RuStorePayClient.instance.purchaseInteractor.confirmTwoStepPurchase(id).then((value) {
// Process success
});
id
— идентификатор покупки.-
developerPayload
— строка с дополнительной и нформацией о заказе, которую вы можете установить при инициализации процесса покупки
Валидация покупок на сервере
Если вам необходимо произвести валидацию успешной покупки на сервере RuStore, вы можете использовать subscriptionToken
в ProductPurchaseResult.SuccessProductPurchaseResult
, возвращаемой при успешной покупке продукта.
Также можно получить subscriptionToken
в сущности Purchase
. Сущность Purchase
можно получить, используя метод getPurchases()
.
RuStorePayClient.instance.getPurchases().then((response) {
for (final purchase in response.purchases) {
print(purchase?.subscriptionToken);
}
}, onError: (err) {
print("purchases err: $err" );
}
);
Отмена покупки
Через SDK можно отменить только те покупки, которые были запущены по двухстадийному сценарию оплаты, т.е. с холдированием средств.
Такие покупки после успешной оплаты будут находиться в статусе PurchaseStatus.paid
.
После отмены покупки будут переходить в статус PurchaseStatus.reversed
.
Используйте отмену покупки в случаях, если после оплаты (холдирования средств) вы не можете предоставить покупателю товар.
Для отмены покупки (холдирования) используйте метод cancelTwoStepPurchase
:
RuStorePayClient.instance.purchaseInteractor.cancelTwoStepPurchase(id).then((value) {
// Process success
});
id
— идентификатор покупки.
Методы утилиты RuStoreFlutterUtils (публичные методы)
Проверка наличия приложения RuStore на устройстве пользователя.
RuStorePayClient.instance.ruStoreUtils.isRuStoreInstalled().then((isInstalled) {
});
Метод возвращает логическое значение isInstalled
.
Открытие веб-страницы для скачивания приложения RuStore.
RuStorePayClient.instance.ruStoreUtils.openRuStoreDownloadInstruction()
Запуск приложения RuStore
RuStorePayClient.instance.ruStoreUtils.openRuStore()
Запуск приложения RuStore для авторизации. После успешной авторизации пользователя приложение RuStore автоматически закроется.
RuStorePayClient.instance.ruStoreUtils.openRuStoreAuthorization()
Обработка ошибок
RuStorePaymentNetworkException
— ошибка сетевого взаимодействия SDK;RuStorePaymentCommonException
— общая ошибка SDK;RuStorePayClientAlreadyExist
— ошибка повторной инициализации SDK;RuStorePayClientNotCreated
— попытка обратиться к публичным интерфейсам SDK до момента её инициализации;RuStorePayInvalidActivePurchase
— запущен процесс оплаты неизвестного типа проду кта;RuStorePayInvalidConsoleAppId
— не задан обязательный параметрconsole_app_id_value
для инициализации SDK;RuStorePaySignatureException
— неверная сигнатура ответа (возникает при попытке совершить мошеннические действия);EmptyPaymentTokenException
— ошибка получения платежного токена;RuStoreNotInstalledException
— на устройстве пользователя не установлен RuStore;RuStoreOutdatedException
— версия RuStore, установленная на устройстве пользователя, не поддерживает данный SDK;RuStoreUserUnauthorizedException
— пользователь не авторизован в RuStore;RuStoreApplicationBannedException
— приложение заблокировано в RuStore;RuStoreUserBannedException
— пользователь заблокирован в RuStore;ProductPurchaseException
— ошибка покупки продукта;ProductPurchaseCancelled
— произошла отмена покупки продукта (пользователь закрыл платежную шторку);RuStoreException
— базовая ошибка RuStore, от которой наследуются остальные ошибки.