5.0.0
RuStore позволяет интегрировать платежи в мобильное приложение.
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
Пример реализации
Ознакомьтесь с приложением-примером чтобы узнать, как правильно интегрировать SDK платежей.
Условия работы платежей
- Загружены данные о приложении в разделе Push-уведомления > Проекты из Консоль RuStore.
Обратите внимание, что Billing SDK не поддерживает работу в ТВ-версии RuStore.
Приложение прошло модерацию (публиковать приложение необязательно).
.
- Подпись и package name различных типов сборок вашего приложения (debug, release и т.д.) могут отличаться друг от друга. В таком случае вы должны создать в разделе Push-уведомления > Проекты из Консоль RuStore проект под каждый тип сборки..
- На устройстве пользователя установлена актуальная версия RuStore.
- Пользователь авторизован в RuStore.
- Пользователь и приложение не должны быть заблокированы в RuStore.
Для приложения включена возможность покупок в RuStore Консоли.
.
Сервис имеет некоторые ограничения на работу за пределами России.
Подготовка к работе
- Скопируйте проекты плагина и приложения-примера из официального репозитория RuStore на GitFlic.
- Откройте в вашей IDE проект Android из папки
godot_plugin_libraries
. - Поместите в папку
godot_plugin_libraries/libs
пакетgodot-lib.xxx.yyy.template_release.aar
, гдеxxx.yyy
версия вашей редакции Godot Engine. - Выполните сборку проекта командой
gradle assemble
.
При успешном выполнении сборки в папке godot_example/android/plugins
будут созданы файлы:
RuStoreGodotBilling.gdap
;RuStoreGodotBilling.aar
;RuStoreGodotCore.gdap
;RuStoreGodotCore.aar
.
Обратите особое внимание, что библиотеки плагинов должны быть собраны под вашу версию Godot Engine.
- Скопируйте содержимое папки
godot_example/android/plugins
в папкуyour_project/android/plugins
. - В пресете сборки Android в списке Плагины отметьте плагины Ru Store Godot Billing и Ru Store Godot Core.
Обработка deeplink
Использование deeplink в RuStore SDK позволяет эффективно взаимодействовать со сторонними приложениями, например, при проведении платежей через банковские приложения (СБП, SberPay, T-Pay и др.). Это позволяет перевести пользователя на экран оплаты, а после завершения транзакции — вернуть в ваше приложение.
Для настройки работы с deeplink в вашем приложении и RuStore SDK, укажите deeplinkScheme
внутри вашего AndroidManifest
файла и переопределите метод onNewIntent
вашего Activity
.
<activity
android:name=".GodotApp"
android:label="@string/godot_project_name_string"
android:theme="@style/GodotAppSplashTheme"
android:excludeFromRecents="false"
android:exported="true"
android:screenOrientation="landscape"
android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
android:resizeableActivity="false"
tools:ignore="UnusedAttribute" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- your app scheme -->
<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="yourappscheme" />
</intent-filter>
</activity>
Вместо yourappscheme
из примера выше укажите название своей схемы. Например, ru.package.name.rustore.scheme
.
Схема, указанная в AndroidManifest
файле должна совпадать со схемой,
которую вы указываете в методе create
RuStore SDK платежей.
Инициализация
Перед вызовом методов библиотеки необходимо выполнить её инициализацию.
Для инициализации вызовите методinit
.
const APPLICATION_ID = "123456"
const DEEPLINK_SCHEME = "yourappscheme"
const DEBUG_LOGS = false
var _billing_client: RuStoreGodotBillingClient = null
func _ready():
_billing_client = RuStoreGodotBillingClient.get_instance()
_billing_client.init(APPLICATION_ID, DEEPLINK_SCHEME, DEBUG_LOGS)
-
APPLICATION_ID
— идентификатор приложения из RuStore консоли.
Где в RuStore Консоль отображаются идентификаторы приложений?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Скопируйте идентификатор из URL-адреса страницы приложения — это набор цифр между
apps/
и/versions
. Например, для URL-адресаhttps://console.rustore.ru/apps/123456/versions
ID приложения —123456
.
-
DEEPLINK_SCHEME
— схема deeplink, необходимая для возврата в ваше приложение после оплаты через стороннее приложение (например, SberPay или СБП). SDK генерирует свой хост к данной схеме. -
DEBUG_LOGS
— флаг, регулирующий ведение журнала событий. Укажите значениеtrue
, если хотите, чтобы события попадали в журнал. В ином случае укажитеfalse
.
ApplicationId
, указанный вbuild.gradle
, должен совпадать сapplicationId
APK-файла, который вы публиковали в системе RuStore Консоль.- Схема deeplink, передаваемая в
deeplinkScheme
, должна совпадать со схемой, указанной вAndroidManifest.xml
в разделе Обработка deeplink. - Подпись
keystore
должна совпадать с подписью, которой было подписано приложение, опубликованное в системе Консоль RuStore. Убедитесь, что используемыйbuildType
(пр.debug
) использует такую же подпись, что и опубликованное приложение (пр.release
).
После инициализации плагина выполняется подключение ко всем доступным сигналам.
Как работают платежи
Проверка доступности работы с платежами
Во время проверки доступности платежей проверяются следующие условия.
- На устройстве пользователя установлена актуальная версия RuStore.
- Приложение RuStore поддерживает функциональность платежей.
- Пользователь авторизован в RuStore.
- Пользователь и приложение не должны быть заблокированы в RuStore.
Для приложения включена возможность покупок в RuStore Консоли.
.
Метод устарел и не рекомендуется к испол ьзованию.
Для проверки доступности платежей используйте метод
check_purchases_availability
.
Перед использованием метода необходимо единожды выполнить подписку на события:
on_check_purchases_availability_success
;on_check_purchases_availability_failure
.
func _ready():
# Инициализация _billing_client
_billing_client.on_check_purchases_availability_success(_on_check_purchases_availability_success)
_billing_client.on_check_purchases_availability_failure(_on_check_purchases_availability_failure)
func _on_check_purchases_availability_success(result: RuStoreFeatureAvailabilityResult):
pass
func _on_check_purchases_availability_failure(error: RuStoreError):
pass
_billing_client.check_purchases_availability()
Обратный вызов (callback) on_check_purchases_availability_success
возвращает объект RuStoreFeatureAvailabilityResult
с информацией о доступности сервиса.
class_name RuStoreFeatureAvailabilityResult extends Object
var isAvailable: bool
var cause: RuStoreError
func _init(json: String = ""):
if json == "":
isAvailable = false
cause = RuStoreError.new()
else:
var obj = JSON.parse_string(json)
isAvailable = obj["isAvailable"]
cause = RuStoreError.new(json)
-
isAvailable
— выполнение условий выполнения платежей (true
/false
). -
cause
— информация об ошибке.
Обратный вызов (callback) on_check_purchases_availability_failure
возвращает объект RuStoreError
со всеми прочими ошибками, например — «Нет соединения с интернетом».
Работа с SDK
Получение списка продуктов
Вы проверили, что платежи доступны и пользователи могут совершать покупки. Теперь можно получить список продуктов. Используйте методget_products
, чтобы получить информацию о продуктах, добавленных в ваше приложение через RuStore Консоль.
Перед использованием метода необходимо единожды выполнить подписку на события:
on_get_products_success
;on_get_products_failure
.
func _ready():
# Инициализация _billing_client
_billing_client.on_get_products_success(_on_get_products_success)
_billing_client.on_get_products_failure(_on_get_products_failure)
func _on_get_products_success(products: Array):
pass
func _on_get_products_failure(error: RuStoreError):
pass
const PRODUCT_IDS = [
"123",
"non_con",
"con",
"sub"]
_billing_client.get_products(PRODUCT_IDS)
PRODUCT_IDS
— список идентификаторов продуктов. В нём не должно быть более 100 позиций.
Чтобы указать id
продуктов, которые нужны для работы метода, выполните следующие действия.
- Откройте RuStore Консоль.
- Перейдите на вкладку Приложения.
- Выберите нужное приложение.
- В левом боковом меню выберите раздел Монетизация.
- Выберите тип товара: Подписки или Разовые покупки.
- Скопируйте идентификаторы нужных товаров. Это и есть
id
продуктов.
Обратный вызов (callback) on_get_products_success
возвращает список объектов RuStoreProduct
с информацией о продуктах.
class_name RuStoreProduct extends Object
var productId: String = ""
var productStatus: ERuStoreProductStatus.Item = 0
var productType: ERuStoreProductType.Item = 0
var priceLabel: String = ""
var price: int = 0
var currency: String = ""
var language: String = ""
var title: String = ""
var description: String = ""
var imageUrl: String = ""
var promoImageUrl: String = ""
var subscription: RuStoreProductSubscription = null
func _init(json: String = ""):
if json != "":
var obj = JSON.parse_string(json)
productId = obj["productId"]
productStatus = ERuStoreProductStatus.Item.get(obj["productStatus"])
if obj.has("productType"):
productType = ERuStoreProductType.Item.get(obj["productType"])
if obj.has("priceLabel"):
priceLabel = obj.get("priceLabel")
if obj.has("price"):
price = int(obj["price"])
if obj.has("currency"):
currency = obj.get("currency")
if obj.has("language"):
language = obj.get("language")
if obj.has("title"):
title = obj.get("title")
if obj.has("description"):
description = obj.get("description")
if obj.has("imageUrl"):
imageUrl = ""#obj["imageUrl"]
if obj.has("promoImageUrl"):
promoImageUrl = ""#obj["promoImageUrl"]
if obj.has("subscription"):
subscription = RuStoreProductSubscription.new(str(obj["subscription"]))
Ниже представлены доступные поля продукта.
-
productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр). -
productType
— тип продукта (потребляемый / непотребляемый / подписка):CONSUMABLE
/NON-CONSUMABE
/SUBSCRIPTION
:NON_CONSUMABLE
— непотребляемый (можно купить один раз, например: отключение рекламы в приложении);CONSUMABLE
— потребляемый (можно купить много раз, например: кристаллы в приложении);SUBSCRIPTION
— подписка (можно купить на период времени, например: подписка в стриминговом сервисе).
-
productStatus
— статус продукта:ACTIVE
— продукт доступен для покупки;INACTIVE
— продукт недоступен для покупки.
-
priceLable
— отформатированная цена товара, включая валютный знак на языкеlanguage
. -
price
— цена в минимальных единицах (в копейках). -
currency
— код валюты ISO 4217. -
language
— язык, указанный с помощью BCP 47 кодирования. -
title
— название продукта на языкеlanguage
. -
description
— описание на языкеlanguage
. -
imageUrl
— ссылка на картинку. -
promoImageUrl
— ссылка на промокартинку. -
subscription
— описание подписки, возвращается только для продуктов с типомsubscription
.
Структура подписки
class_name RuStoreProductSubscription extends Object
var subscriptionPeriod: RuStoreSubscriptionPeriod = null
var freeTrialPeriod: RuStoreSubscriptionPeriod = null
var gracePeriod: RuStoreSubscriptionPeriod = null
var introductoryPrice: String = ""
var introductoryPriceAmount: String = ""
var introductoryPricePeriod: RuStoreSubscriptionPeriod = null
func _init(json: String = ""):
if json != "":
var obj = JSON.parse_string(json)
if obj.has("subscriptionPeriod"):
subscriptionPeriod = RuStoreSubscriptionPeriod.new(str(obj["subscriptionPeriod"]))
if obj.has("freeTrialPeriod"):
freeTrialPeriod = RuStoreSubscriptionPeriod.new(obj["freeTrialPeriod"])
if obj.has("gracePeriod"):
gracePeriod = RuStoreSubscriptionPeriod.new(obj["gracePeriod"])
if obj.has("introductoryPrice"):
introductoryPrice = obj["introductoryPrice"]
if obj.has("introductoryPriceAmount"):
introductoryPriceAmount = obj["introductoryPriceAmount"]
if obj.has("introductoryPricePeriod"):
introductoryPricePeriod = RuStoreSubscriptionPeriod.new(obj["introductoryPricePeriod"])
subscriptionPeriod
— период подписки.freeTrialPeriod
— пробный период подписки.gracePeriod
— льготный период подписки.introductoryPrice
— отформатированная вступительная цена подписки, включая знак валюты, на языкеproduct:language
.introductoryPriceAmount
— вступительная цена в минимальных единицах валюты (в копейках).introductoryPricePeriod
— расчётный период вступительной цены.
Структура периода подписки
class_name RuStoreSubscriptionPeriod extends Object
var days: int = 0
var months: int = 0
var years: int = 0
func _init(json: String = ""):
if json != "":
var obj = JSON.parse_string(json)
days = int(obj["days"])
months = int(obj["months"])
years = int(obj["years"])
days
— количество дней.months
— количество месяцев.years
— количество лет.
Обратный вызов (callback) on_get_products_failure
возвращает объект RuStoreError
с информацией об ошибке. Структура ошибки описана в разделе Обработка ошибок.
Покупка продукта
Для вызова покупки продукта используйте методpurchaseProduct
.
Перед использованием метода необходимо единожды выполнить подписку на события:
on_purchase_product_success
;on_purchase_product_failure
func _ready():
# Инициализация _billing_client
_billing_client.on_purchase_product_success(_on_purchase_product_success)
_billing_client.on_purchase_product_failure(_on_purchase_product_failure)
func _on_purchase_product_success(result: RuStorePaymentResult):
pass
func _on_purchase_product_failure(error: RuStoreError):
pass
const PRODUCT_ID = "123"
const PARAMS = {
"order_id": "example_id",
"quantity": 1,
"payload": "Some payload"
}
_billing_client.purchase_product(PRODUCT_ID, PARAMS)
-
PRODUCT_ID
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр); -
PARAMS
— опциональные параметры:orderId
— идентификатор заказа, создаётся на стороне AnyApp. (необязательно — если не указан, то генерируется автоматически);quantity
— количество продукта (необязательный параметр — если не указывать, будет использоваться значение1
) (необязательно);developerPayload
— строка с дополнительной информацией о заказе, которую вы можете установить при инициализации процесса покупки.
Обратный вызов on_purchase_product_success
возвращает объект наследник класса RuStorePaymentResult
с информацией о покупке.
Success
— результат успешного завершения покупки цифрового товара.Failure
— при отправке запроса на оплату или получения статуса оплаты возникла проблема, невозможно установить статус покупки.Cancelled
— запрос на покупку отправлен, при этом пользователь закрыл «платёжную шторку» на своём устройстве, и результат оплаты неизвестен.InvalidPaymentState
— ошибка работы SDK платежей. Может возникнуть, в случае некорректного обратного deeplink.
class_name RuStorePaymentResult extends Object
class Success extends RuStorePaymentResult:
var orderId: String = ""
var purchaseId: String = ""
var productId: String = ""
var invoiceId: String = ""
var subscriptionToken: String = ""
func _init(json: String = ""):
if json != "":
var obj = JSON.parse_string(json)
if obj.has("orderId"):
purchaseId = obj["orderId"]
purchaseId = obj["purchaseId"]
productId = obj["productId"]
invoiceId = obj["invoiceId"]
if obj.has("subscriptionToken"):
purchaseId = obj["subscriptionToken"]
orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов (необязательно — если не указан, то генерируется автоматически);purchaseId
— идентификатор покупки;productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр);invoiceId
— идентификатор счёта;subscriptionToken
— токен подписки. Состоит изinvoiceId
покупки иuserId
RuStore, записанных через точку:invoiceId.userId
.
class Cancelled extends RuStorePaymentResult:
var purchaseId: String
func _init(json: String = ""):
if json != "":
var obj = JSON.parse_string(json)
purchaseId = obj["purchaseId"]
purchaseId
— идентификатор покупки.
class Failure extends RuStorePaymentResult:
var purchaseId: String = ""
var invoiceId: String = ""
var orderId: String = ""
var quantity: int = 0
var productId: String = ""
var errorCode: int = 0
func _init(json: String = ""):
if json != "":
var obj = JSON.parse_string(json)
if obj.has("purchaseId"): purchaseId = obj["purchaseId"]
if obj.has("invoiceId"): invoiceId = obj["invoiceId"]
if obj.has("orderId"): orderId = obj["orderId"]
if obj.has("quantity"): quantity = int(obj["quantity"])
if obj.has("productId"): productId = obj["productId"]
if obj.has("errorCode"): errorCode = int(obj["errorCode"])
purchaseId
— идентификатор покупки.invoiceId
— идентификатор счёта.orderId
— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.quantity
— количество продукта (необязательный параметр — если не указывать, будет использоваться значение1
).productId
— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).errorCode
— код ошибки.
class InvalidPaymentState extends RuStorePaymentResult:
pass
Обратный вызов (callback) on_purchase_product_failure
возвращает объект RuStoreError
с информацией об ошибке. Структура ошибки описана в разделе Обработка ошибок.