SDK Платежи in-app и подписки для Godot (версия 8.0.0)
RuStore позволяет интегрировать платежи в мобильное приложение.
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
Подготовка к работе
Библиотеки плагинов в репозитории собраны для Godot Engine 4.2.1. Если вы используете другую версию Godot Engine, выполните шаги раздела Пересборка плагина.
- Скопируйте проекты плагина и приложения-примера из официального репозитория RuStore на GitFlic.
- Скопируйте содержимое папки
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. |
Установлен | Выполняется проверка следующих условий.
Если все указанные выше условия выполняются, в событии В противном случае возвращается Прочие ошибки возвращаются в событии |
Метод устарел и не рекомендуется к использованию.
Для проверки доступности платежей используйте метод
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: RuStorePurchaseAvailabilityResult):
pass
func _on_check_purchases_availability_failure(error: RuStoreError):
pass
_billing_client.check_purchases_availability()
Обратный вызов (callback) on_check_purchases_availability_success
возвращает объект RuStorePurchaseAvailabilityResult
с информацией о доступности сервиса.
class_name RuStorePurchaseAvailabilityResult extends Object
var isAvailable: bool
var cause: RuStoreError
-
isAvailable
— выполнение условий выполнения платежей (true
/false
). -
cause
— информация об ошибке.
Обратный вызов (callback) on_check_purchases_availability_failure
возвращает объект RuStoreError
со всеми прочими ошибками, например — «Нет соединения с интернетом».
Работа с SDK
Определение наличия авторизации у пользователя
В BillingClient есть возможность определить, является ли пользователь авторизованным. Для определения наличия авторизации у пользователя требуется вызвать метод get_authorization_status
.
Перед использованием метода необходимо единожды выполнить подписку на события:
on_get_authorization_status_success
;on_get_authorization_status_failure
.
func _ready():
# Инициализация _billing_client
_billing_client.on_get_authorization_status_success.connect(_on_get_authorization_status_success)
_billing_client.on_get_authorization_status_failure.connect(_on_get_authorization_status_failure)
func _on_get_authorization_status_success(result: RuStoreBillingUserAuthorizationStatus):
pass
func _on_get_authorization_status_failure(error: RuStoreError):
pass
_billing_client.get_authorization_status()
Структура ответа
class_name RuStoreBillingUserAuthorizationStatus extends Object
var authorized: bool = false
authorized
— значение статуса авторизации у пользователя. Если true
, то пользователь авторизован в RuStore. Если false
, то пользователь не авторизован.
В случае использования SDK вне RuStore результат true
также может вернуться, если в процессе оплаты пользователь авторизовался через VK ID и с момента авторизации прошло менее 15 минут.
Получение списка продуктов
Вы проверили, что платежи доступны и пользователи могут совершать покупки. Теперь можно получить список продуктов. И спользуйте метод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)