BillingClient SDK помечён как устаревший. BillingClient SDK продолжает свою работу, но устранение неисправностей, влияющих на работу платежей, может занимать больше времени. Новая функциональность добавляться не будет.
Рекомендуем использовать Pay SDK в проектах. Для перехода на Pay SDK воспользуйтесь инструкцией по миграции
SDK Платежи in-app и подписки для Godot (версия 10.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 в вашем приложении выполните два основных шага:
1. Измените код игровой активити.
- Откройте файл
GodotApp.java
расположенный по пути*your_project*/android/build/src/com/godot/game
. - Переопределите методы
onCreate
иonNewIntent
для обработки входящих intent'ов, используя приведённый ниже код.
package com.godot.game;
import android.content.Intent;
import android.os.Bundle;
import java.util.concurrent.Executors;
import org.godotengine.godot.GodotActivity;
import ru.rustore.godot.billing.IntentEventBus;
public class GodotApp extends GodotActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.GodotAppMainTheme);
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
handleIntent(getIntent());
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent) {
Executors.newSingleThreadExecutor().execute(() -> {
IntentEventBus.INSTANCE.emit(intent);
});
}
}
2. Обновите AndroidManifest.xml.
- Установите атрибут
launchMode
игровой активити в значениеsingleTop
. - Создайте
activity-alias
указав в атрибутеtargetActivity
класс игровой активити. - Внутри
activity-alias
объявитеintent-filter
с указанием значения вашейDeeplink Scheme
.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.godot.game"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto" >
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true" />
<uses-feature
android:glEsVersion="0x00030000"
android:required="true" />
<application
android:label="@string/godot_project_name_string"
android:allowBackup="false"
android:icon="@mipmap/icon"
android:appCategory="game"
android:isGame="true"
android:hasFragileUserData="false"
android:requestLegacyExternalStorage="false"
tools:ignore="GoogleAppIndexingWarning" >
<meta-data
android:name="org.godotengine.editor.version"
android:value="${godotEditorVersion}" />
<!-- 1. Game Activity launchMode="singleTop" -->
<activity
android:name=".GodotApp"
android:label="@string/godot_project_name_string"
android:theme="@style/GodotAppSplashTheme"
android:launchMode="singleTop"
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>
</activity>
<!-- 2. Аctivity-alias for Game Activity -->
<activity-alias android:enabled="true"
android:exported="true"
android:name=".RuStoreDeeplink"
android:targetActivity=".GodotApp" >
<!-- 3. Deeplink intent-filter -->
<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-alias>
</application>
</manifest>
Инициализация
Перед вызовом методов библиотеки необходимо выполнить её инициализацию.
Для инициализации вызовите метод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 минут.