SDK Платежи in-app для Godot (версия 10.1.0)
RuStore позволяет интегрировать платежи в мобильное приложение.
-
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
-
Если вы переходите на Pay SDK с billingClient SDK, ознакомьтесь с инструкцией по переходу. Подробности о Pay SDK можно узнать тут.
Подготовка к работе
Библиотеки плагинов в репозитории собраны для Godot Engine 4.2.1. Если вы используете другую версию Godot Engine, выполните шаги раздела Пересборка плагина.
- Скопируйте проекты плагина и приложения-примера из официального репозитория RuStore на GitFlic.
- Скопируйте содержимое папки
godot_example/android/pluginsв папкуyour_project/android/plugins. - В пресете сборки Android в списке Плагины отметьте плагины Ru Store Godot Pay и Ru Store Godot Core.
- Для Godot 4.2.2 и младше, в файле
your_project/android/build/build.gradleдобавьте секциюresolutionStrategy:
android {
...
}
configurations.all {
resolutionStrategy {
force 'androidx.core:core:1.9.0'
force 'androidx.core:core-ktx:1.9.0'
force 'androidx.lifecycle:lifecycle-runtime:2.6.2'
force 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
force 'androidx.lifecycle:lifecycle-livedata:2.6.2'
force 'androidx.lifecycle:lifecycle-livedata-core:2.6.2'
force 'androidx.lifecycle:lifecycle-viewmodel:2.6.2'
force 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
force 'androidx.lifecycle:lifecycle-process:2.6.2'
force 'androidx.lifecycle:lifecycle-livedata-core-ktx:2.6.2'
force 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2'
}
}
Инициализация SDK
Перед вызовом методов библиотеки необходимо выполнить её инициализацию. Сама инициализация происходит автоматически, но для работы SDK в вашем файле Manifest.xml необходимо прописать console_app_id_value и internal_config_key.
<!-- Initializing sdk -->
<meta-data
android:name="console_app_id_value"
android:value="@string/rustore_PayClientSettings_consoleApplicationId" />
<meta-data
android:name="internal_config_key"
android:value="@string/rustore_PayClientSettings_internalConfigKey" />
Оба значен ия должны располагаться внутри тега <application>. Также к тегу <application> добавьте аттрибут tools:replace="android:label".
<?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" />
<!-- Additional attribute tools:replace -->
<application
android:label="@string/godot_project_name_string"
tools:replace="android:label"
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}" />
<activity
android:name=".GodotApp"
android:label="@string/godot_project_name_string"
android:theme="@style/GodotAppSplashTheme"
android:launchMode="singleInstancePerTask"
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.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Initializing sdk -->
<meta-data
android:name="console_app_id_value"
android:value="@string/rustore_PayClientSettings_consoleApplicationId" />
<meta-data
android:name="internal_config_key"
android:value="@string/rustore_PayClientSettings_internalConfigKey" />
</application>
</manifest>
console_app_id_value — идентификатор приложения из RuStore консоли.
Где в RuStore Консоль отображаются идентификаторы приложений?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Скопируйте идентификатор из URL-адреса страницы приложения — это набор цифр между
apps/и/versions. Например, для URL-адресаhttps://console.rustore.ru/apps/123456/versionsID приложения —123456.

ApplicationId, указанный вbuild.gradle, должен совпадать сapplicationIdAPK-файла, который вы публиковали в RuStore Консоль.-
Подпись
keystoreдолжна совпадать с подписью, которой было подписано приложение, опубликованное в RuStore Консоль. Убедитесь, что используемыйbuildType(пр.debug) испо льзует такую же подпись, что и опубликованное приложение (пр.release).
В целях безопасности, SDK устанавливает android:usesCleartextTraffic="false" по умолчанию, чтобы предотвратить передачу данных по незащищённому HTTP и защитить от атак типа "Man-in-the-Middle". Если ваше приложение требует использования HTTP, вы можете изменить этот атрибут на true, но делайте это на свой страх и риск, так как это увеличивает шанс перехвата и подмены данных. Мы рекомендуем разрешать незащищённый трафик только в исключительных случаях и для доверенных доменов, предпочитая HTTPS для всех сетевых взаимодействий.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Initializing sdk -->
<string name="rustore_PayClientSettings_consoleApplicationId" translatable="false">198332</string>
<string name="rustore_PayClientSettings_internalConfigKey" translatable="false">godot</string>
</resources>
Обработка deeplink
Deeplink в RuStore SDK платежей нужна для корректной работы со сторонними приложениями оплаты. Она помогает пользователям быстрее совершать покупки в стороннем приложении и возвращаться в ваше приложение.
Допускаются только символы в кодировке ASCII. Формат должен соответствовать спецификации RFC-3986.
Для настройки 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 org.godotengine.godot.GodotActivity;
import ru.rustore.godot.pay.RuStoreGodotPay;
public class GodotApp extends GodotActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.GodotAppMainTheme);
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
RuStoreGodotPay.proceedIntent(getIntent());
}
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
RuStoreGodotPay.proceedIntent(intent);
}
}
Параметры метода proceedIntent:
Intent intent— интент, содержащий данные о платежной операции.SdkTheme sdkTheme— цветовая тема платежной шторки. Доступны два вариантаLIGHTиDARK(светлая и темная тема соотвественно), по умолчаниюLIGHT(необязательный параметр).Long maxRetryTimeMs— максимальное время (в миллисекундах) для повторных попыток инициализации платёжного клиента, по умолчанию 5000 мс (необязательный параметр).
2. Обновите AndroidManifest.xml.
- В секцию
<application>...</application>поместите тегmeta-dataс указанием ссылки на вашуDeeplink Scheme. - Установите атрибут
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"
tools:replace="android:label"
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}" />
<meta-data
android:name="console_app_id_value"
android:value="@string/rustore_PayClientSettings_consoleApplicationId" />
<meta-data
android:name="internal_config_key"
android:value="@string/rustore_PayClientSettings_internalConfigKey" />
<!-- 1. Deeplink scheme -->
<meta-data
android:name="sdk_pay_scheme_value"
android:value="@string/rustore_PayClientSettings_deeplinkScheme" />
<!-- 2. 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.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 3. Аctivity-alias for Game Activity -->
<activity-alias
android:enabled="true"
android:exported="true"
android:name=".RuStoreDeeplink"
android:targetActivity=".GodotApp" >
<!-- 4. 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="@string/rustore_PayClientSettings_deeplinkScheme" />
</intent-filter>
</activity-alias>
</application>
</manifest>
Значение deeplinkScheme должно располагаться в файле ресурсов, например: your_project/android/build/res/values/rustore_values.xml.
Не задавайте значение deeplinkScheme напрямую в манифесте.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Initializing sdk -->
<string name="rustore_PayClientSettings_consoleApplicationId" translatable="false">198332</string>
<string name="rustore_PayClientSettings_internalConfigKey" translatable="false">godot</string>
<!-- Deeplink scheme -->
<string name="rustore_PayClientSettings_deeplinkScheme" translatable="false">yourappscheme</string>
</resources>
Работа с SDK
Перед использованием всех методов плагина должен быть создан экземпляр объекта RuStoreGodotPayClient.
var _pay_client: RuStoreGodotPayClient = RuStoreGodotPayClient.get_instance()
Проверка доступности работы с платежами
Для проверки доступности платежей, вызовите метод get_purchase_availability. При его вызове проверяются следующие условия.
- У компании подключена монетизация через консоль разработчика RuStore.
- Приложение не должно быть заблокировано в RuStore.
- Пользователь не должен быть заблокирован в RuStore.
RuStorePayGetPurchaseAvailabilityResult.isAvailable == true.
В противном случае возвращается RuStorePayGetPurchaseAvailabilityResult.isAvailable == false и RuStorePayGetPurchaseAvailabilityResult.cause, где cause — это ошибка о невыполненном условии (возможные ошибк и описаны в разделе Обработка ошибок).
Перед использованием метода необходимо единожды выполнить подписку на события:
on_get_purchases_availability_success;on_get_purchases_availability_failure.
func _ready():
# Инициализация _pay_client
_pay_client.on_get_purchase_availability_success.connect(_on_get_purchase_availability_success)
_pay_client.on_get_purchase_availability_failure.connect(_on_get_purchase_availability_failure)
func _on_get_purchase_availability_success(result: RuStorePayGetPurchaseAvailabilityResult):
pass
func _on_get_purchase_availability_failure(error: RuStoreError):
pass
_pay_client.get_purchase_availability()
Проверка статуса авторизации пользователя
Для проверки статуса авторизации пользователя, вызовите метод get_user_authorization_status. Результатом выполнения метода является значение перечисления ERuStorePayUserAuthorizationStatus.Item:
AUTHORIZED— пользователь авторизован в RuStore.UNAUTHORIZED— пользователь неавторизован в RuStore. Данное значение также вернется если у пользователя нет установленного МП RuStore на девайсе.
Перед использованием метода необходимо единожды выполнить подписку на события:
on_get_user_authorization_status_success;on_get_user_authorization_status_failure.
func _ready():
# Инициализация _pay_client
_pay_client.on_get_user_authorization_status_success.connect(_on_get_user_authorization_status_success)
_pay_client.on_get_user_authorization_status_failure.connect(_on_get_user_authorization_status_failure)
func _on_get_user_authorization_status_success(result: ERuStorePayUserAuthorizationStatus.Item):
pass
func _on_get_user_authorization_status_failure(error: RuStoreError):
pass
_pay_client.get_user_authorization_status()
Получение списка продуктов
Для получения продуктов, добавленных в ваше приложение через RuStore консоль, необходимо использовать метод get_products.
Перед использованием метода необходимо единожды выполнить подписку на события:
on_get_products_success;on_get_products_failure.
func _ready():
# Инициализация _pay_client
_pay_client.on_get_products_success.connect(_on_get_products_success)
_pay_client.on_get_products_failure.connect(_on_get_products_failure)
func _on_get_products_success(products: Array[RuStorePayProduct]):
pass
func _on_get_products_failure(error: RuStoreError):
pass
var PRODUCT_IDS: Array[RuStorePayProductId] = [
RuStorePayProductId.new("con_1"),
RuStorePayProductId.new("non_con_1"),
]
_pay_client.get_products(PRODUCT_IDS)
product_ids — список идентификаторов продуктов (задаются при создании продукта в консоли разработчика). Список продуктов имеет ограничение в размере 1000 элемент ов.
Где в RuStore Консоль отображаются идентификаторы продуктов?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Выберите Монетизация в меню слева.
- Выберите тип товара: Подписки или Разовые покупки.
- Скопируйте идентификаторы нужных товаров.

Метод возвращает список продуктов. Ниже представлена модель продукта.
class_name RuStorePayProduct extends RefCounted
var productId: RuStorePayProductId = null
var type: ERuStorePayProductType.Item = 0
var amountLabel: RuStorePayAmountLabel = null
var price: RuStorePayPrice = null
var currency: RuStorePayCurrency = null
var title: RuStorePayTitle = null
var description: RuStorePayDescription = null
var imageUrl: RuStorePayUrl = null
var subscriptionInfo: RuStorePaySubscriptionInfo = null
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).type— тип продукта.CONSUMABLE/NON-CONSUMABLE/SUBSCRIPTION(потребляемый/непотребляемый/подписка).amountLabel— отформатированная цена покупки, включая валютный знак.price— цена в минимальных единицах (в копейках).currency— код валюты ISO 4217.title— название продукта на языкеlanguage.description— описание на языкеlanguage.imageUrl— ссылка на картинку.subscriptionInfo— информация о подписке (будет неnull, если тип продуктаSUBSCRIPTION).
subscriptionInfo— информация о подписке (будет не null, если тип продуктаSUBSCRIPTION).
class_name RuStorePaySubscriptionInfo extends RefCounted
var periods: Array[RuStorePaySubscriptionPeriod]
periods— cписок периодов подписки.
class_name RuStorePaySubscriptionPeriod extends RefCounted
class RuStorePayTrialPeriod extends RuStorePaySubscriptionPeriod:
var duration: String
var currency: String
var price: int
class RuStorePayPromoPeriod extends RuStorePaySubscriptionPeriod:
var duration: String
var currency: String
var price: int
class RuStorePayMainPeriod extends RuStorePaySubscriptionPeriod:
var duration: String
var currency: String
var price: int
class RuStorePayGracePeriod extends RuStorePaySubscriptionPeriod:
var duration: String
class RuStorePayHoldPeriod extends RuStorePaySubscriptionPeriod:
var duration: String
duration— длительность периода в формате ISO 8601.currency— код валюты ISO 4217.price— Цена в минимальных единицах валюты.
Получение списка покупок
Для получения списка покупок пользователя используйте метод get_purchases.
Перед использованием методов необходимо единожды выполнить подписку на события:
on_get_purchases_success;on_get_purchases_failure.
func _ready:
# Инициализация _pay_client
_pay_client.on_get_purchases_success.connect(_on_get_purchases_success)
_pay_client.on_get_purchases_failure.connect(_on_get_purchases_failure)
func _on_get_purchases_success(purchases: Array[RuStorePayPurchase]):
pass
func _on_get_purchases_failure(error: RuStoreError):
pass
# Инициализ ация _pay_client
# Вызов без фильтра
_pay_client.get_purchases()
# Вызов с фильтром
var product_type = ERuStorePayProductType.Item.CONSUMABLE_PRODUCT
var purchase_status = ERuStorePayPurchaseStatusFilter.Item.CONFIRMED
_pay_client.get_purchases(product_type, purchase_status)
Вызов с фильтром позволяет фильтровать покупки по типу товаров и статусу покупки:
product_type — типы товаров:
ERuStorePayProductType.Item.NON_CONSUMABLE_PRODUCT— непотребляемые товары.ERuStorePayProductType.Item.CONSUMABLE_PRODUCT— потребляемые товары.ERuStorePayProductType.Item.SUBSCRIPTION— подписки.
purchase_status — статусы покупок:
-
Для продуктов:
ERuStorePayPurchaseStatusFilter.Item.PAID— успешное холдирование средств, покупка ожидает подтверждения со стороны разработчика.ERuStorePayPurchaseStatusFilter.Item.CONFIRMED— покупка подтверждена, средства списаны.
-
Для подписок:
ERuStorePayPurchaseStatusFilter.Item.ACTIVE— подписка активна.ERuStorePayPurchaseStatusFilter.Item.PAUSED— подписка в Hold периоде (например, из-за недостатка средств на карте), продолжаются попытки списания в соответствии с настройками тарифа подписки.
По умолчанию фильтры выключены, если значения не заданы, метод вернёт все покупки пользователя в статусах PAID, CONFIRMED, ACTIVE и PAUSED, независимо от типа товара.
Получение сведений о покупке
Для получения информац ии о покупке, используйте методget_purchase.
func _ready:
# Инициализация _pay_client
_pay_client.on_get_purchase_success(_on_get_purchase_success)
_pay_client.on_get_purchase_failure(_on_get_purchase_failure)
func _on_get_purchase_success(purchase: RuStorePayPurchase):
pass
func _on_get_purchase_failure(purchase_id: RuStorePayPurchaseId, error: RuStoreError):
pass
var purchase_id: RuStorePayPurchaseId = ...
_pay_client.get_purchase(purchase_id)
Типы покупок
В SDK предусмотрен базовый класс RuStorePayPurchase, который объединяет общие поля всех типов покупок.
На его основе созданы две реализации:
- RuStorePayProductPurchase: для потребляемых и непотребляемых покупок.
- RuStorePaySubscriptionPurchase: для подписок.
Данное разделение позволяет каждому типу покупки иметь свои уникальные свойства и поведение.
class_name RuStorePayPurchase extends RefCounted
var purchaseId: RuStorePayPurchaseId = null
var invoiceId: RuStorePayInvoiceId = null
var orderId: RuStorePayOrderId = null
var purchaseType: ERuStorePayPurchaseType.Item = 0
var description: RuStorePayDescription = null
var purchaseTime: RuStorePayTime = null
var price: RuStorePayPrice = null
var amountLabel: RuStorePayAmountLabel = null
var currency: RuStorePayCurrency = null
var developerPayload: RuStorePayDeveloperPayload = null
var sandbox: bool = false
var _status = 0
Модель разовой покупки ProductPurchase
class_name RuStorePayProductPurchase extends RuStorePayPurchase
var productId: RuStorePayProductId = null
var productType: ERuStorePayProductType.Item = 0
var quantity: RuStorePayQuantity = null
var status: ERuStorePayProductPurchaseStatus.Item = 0
Унаследованные поля:
purchaseId— идентификатор покупки.invoiceId— идентификатор счёта.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.PurchaseType— тип покупки:ONE_PHASE- одностадийная покупка;TWO_PHASE- двухстадийная покупка;UNDEFINED- стадийность не определена.
description— описание на языкеlanguage.purchaseTime— время покупки.price— цена в минимальных единицах (в копейках).amountLabel— отформатированная цена покупки, включая валютный знак.currency— код валюты ISO 4217.-
developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации -
sandbox— флаг тестового платежа. Значениеtrue— тестовый платёж,false— реальный платёж.
Уникальные поля:
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).productType— тип продукта.NON_CONSUMABLE_PRODUCT;CONSUMABLE_PRODUCT.
quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров.status— состояние покупки:INVOICE_CREATED— создан счёт на оплату, покупка ожидает оплаты;CANCELLED— покупка отменена покупателем;PROCESSING— запущена оплата;REJECTED— покупка отклонена (например, ввиду недостатка средств);CONFIRMED— покупка успешно оплачена;REFUNDED— запрос на возврат средств за покупку совершён успешно. Деньги будут возвращены пользователю в течение 10 рабочих дней.;REFUNDING— инициирован возврат, запрос отправлен в эквайер;EXECUTING— покупка находится в процессе выполнения;EXPIRED— истекло время на оплату покупки;PAID— только для двухстадийной оплаты, промежуточный статус, средства на счёте покупателя захолдированы, покупка ожидает подтверждения от разработчика;REVERSED— только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 6 часов, холдирование средств отменено.
Статусная модель покупки
Статусная модель одностадийного платежа.
Статусная модель двухстадийного платежа.
Модель подписки SubscriptionPurchase
class_name RuStorePaySubscriptionPurchase extends RuStorePayPurchase
var productId: RuStorePayProductId = null
var expirationDate: RuStorePayTime = null
var gracePeriodEnabled: bool = false
var status: ERuStorePaySubscriptionPurchaseStatus.Item = 0
Унаследованные поля:
purchaseId— идентификатор покупки.invoiceId— идентификатор счёта.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.PurchaseType— тип покупки:ONE_PHASE- одностадийная покупка;TWO_PHASE- двухстадийная покупка;UNDEFINED- стадийность не определена.
description— описание на языкеlanguage.purchaseTime— время покупки.price— цена в минимальных единицах (в копейках).amountLabel— отформатированная цена покупки, включая валютный знак.currency— код валюты ISO 4217.-
developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации -
sandbox— флаг тестового платежа. Значениеtrue— тестовый платёж,false— реальный платёж.
Уникальные поля:
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр). Идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).expirationDate— дата окончания действия подписки.gracePeriodEnabled— флаг, указывающий, активен ли Grace-период для подписки.status— состояние подписки:INVOICE_CREATED— создан счет на оплату, подписка ожидает оплаты.CANCELLED— счет на оплату подписки отменен.EXPIRED— срок действия оплаты счета истек.PROCESSING— первый платеж по подписке в обработке.REJECTED— первый платеж по подписке отклонен. Подписка не оформлена.ACTIVE— подписка активна.PAUSED— подписка приостановлена из-за проблем с оплатой.TERMINATED— закончились попытки списания по подписке (все были неуспешными). Подписка закрыта автоматически из-за проблем с оплатой.CLOSED— подписка была отменена пользователем или разработчиком. Истек срок оплаченного периода, подписка закрыта.
Статусная модель подписки
Покупка продукта
- При использовании одностадийного платежа покупка не требует подтверждения, денежные средства сразу списываются со счёта покупателя, а с разработчика удерживается комиссия. В таком случае, если требуется вернуть денежные средства клиенту (например, по какой-то причине нет возможности поставить продукт), возможен только возврат средств через RuStore Консоль, денежные средства возвращаются покупателю через несколько дней. Возвращается полная стоимость покупки, при этом удержанная комиссия разработчику не возмещает ся.
- В случае использования двухстадийного платежа сначала производится холдирование средств на счете покупателя. Комиссия в этом случае не удерживается. После холдирования покупка требует подтверждения или отмены. Комиссия с разработчика удерживается при подтверждении покупки. Отмена покупки означает снятие холда - денежные средства мгновенно снова доступны покупателю.
Двухстадийная оплата доступна только для определенного набора способов оплаты (на текущий момент — только для карт). Технологии СБП не поддерживают двухстадийную оплату. Если выбран способ оплаты, который не поддерживает холдирование, то покупка будет запущена по сценарию с одной стадией.
Оплата с выбором типа покупки
Для вызова покупки продукта с выбором стадийности оплаты используйте метод purchase.
Перед использованием метода необходимо единожды выполнить подписку на события:
on_purchase_success;on_purchase_failure.
func _ready():
# Инициализация _pay_client
_pay_client.on_purchase_success(_on_purchase_success)
_pay_client.on_purchase_failure(_on_purchase_failure)
func _on_purchase_success(result: RuStorePayProductPurchaseResult):
pass
func _on_purchase_failure(product_id: RuStorePayProductId, error: RuStoreError):
pass
var parameters = RuStorePayProductPurchaseParams.new(
RuStoreProductId.new("product_id"), # productId
null, # appUserEmail
null, # appUserId
null, # developerPayload
null, # orderId
RuStoreQuantity.new(1)); # quantity
var preferredPurchaseType = ERuStorePayPreferredPurchaseType.Item.ONE_STEP
var sdk_theme = ERuStorePaySdkTheme.Item.DARK
_pay_client.purchase(parameters, preferredPurchaseType, sdk_theme)
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются.-
appUserId— внутренний ID пользователя в вашем приложении (опциональный параметр). Строка с максимальной длиной в 128 символов.提示Например, данный параметр может использоваться для выявления случаев мошенничества в вашем приложении, что позволит повысить его безопасность.
appUserEmail- это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemailпри отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.preferredPurchaseType— желаемый тип покупки: одностадийная (ONE_STEP) или двухстадийная (TWO_STEP).
sdk_theme— цветовая тема платежной шторки. Доступны два вариантаLIGHTиDARK(светлая и темная тема соотвественно), по умолчаниюLIGHT.
Данный метод по умолчанию запускается по одностадийному сценарию оплаты (preferredPurchaseType = ERuStorePayPreferredPurchaseType.Item.ONE_STEP), т.е. без холдирования средств.
Для двухстадийной оплаты нужно указать preferredPurchaseType = ERuStorePayPreferredPurchaseType.Item.TWO_STEP. Двухстадийная оплата (т.е. оплата с холдированием средств) для данного метода не гарантирована и напрямую зависит от того, какой способ оплаты (карта, СПБ и др.) выбрал пользователь.
При запуске данного метода (с предпочитаемым preferredPurchaseType = twoStep), до тех пор пока пользователь не выберет способ оплаты, стадийность покупки будет UNDEFINED. Учитывайте данное поведение при обработке результатов отмены (ProductPurchaseCancelled) или ошибки (ProductPurchaseException) покупки.
Двухстадийная оплата (с холдированием средств)
При вызове данного метода пользователю будет доступен ограниченный набор способов оплаты — только те, которые поддерживают двухстадийную оплату.
purchase_two_step.
Перед использованием метода необходимо единожды выполнить подписку на события:
on_purchase_two_step_success;on_purchase_two_step_failure.
func _ready():
# Инициализация _pay_client
_pay_client.on_purchase_two_step_success(_on_purchase_two_step_success)
_pay_client.on_purchase_two_step_failure(_on_purchase_two_step_failure)
func _on_purchase_two_step_success(result: RuStorePayProductPurchaseResult):
pass
func _on_purchase_two_step_failure(product_id: RuStorePayProductId, error: RuStoreError):
pass
var parameters = RuStorePayProductPurchaseParams.new (
RuStoreProductId.new("product_id"), # productId
null, # appUserEmail
null, # appUserId
null, # developerPayload
null, # orderId
RuStoreQuantity.new(1)); # quantity
);
var sdk_theme = ERuStorePaySdkTheme.Item.DARK
_pay_client.purchase_two_step(parameters, sdk_theme)
Структура параметров покупки
class_name RuStorePayProductPurchaseParams extends RefCounted
var productId: RuStorePayProductId = null
var appUserEmail: RuStorePayAppUserEmail = null
var appUserId: RuStorePayAppUserId = null
var developerPayload: RuStorePayDeveloperPayload = null
var orderId: RuStorePayOrderId = null
var quantity: RuStorePayQuantity = null
func _init(
productId: RuStorePayProductId,
appUserEmail: RuStorePayAppUserEmail = null,
appUserId: RuStorePayAppUserId = null,
developerPayload: RuStorePayDeveloperPayload = null,
orderId: RuStorePayOrderId = null,
quantity: RuStorePayQuantity = null
):
self.productId = productId
self.appUserEmail = appUserEmail
self.appUserId = appUserId
self.developerPayload = developerPayload
self.orderId = orderId
self.quantity = quantity
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload— строка с дополнител ьной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются.-
appUserId— внутренний ID пользователя в вашем приложении (опциональный параметр). Строка с максимальной длиной в 128 символов.提示Например, данный параметр может использоваться для выявления случаев мошенничества в вашем приложении, что позволит повысить его безопасность.
appUserEmail— это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, е го можно передать для автоматического заполнения поляemailпри отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.
sdkTheme— цветовая тема платежной шторки. Доступны два вариантаLIGHTиDARK(светлая и темная тема соотвественно), по умолчаниюLIGHT.
class_name RuStorePayProductPurchaseResult extends RefCounted
var invoiceId: RuStorePayInvoiceId = null
var orderId: RuStorePayOrderId = null
var productId: RuStorePayProductId = null
var productType: ERuStorePayProductType.Item = 0
var purchaseId: RuStorePayPurchaseId = null
var purchaseType: ERuStorePayPurchaseType.Item = 0
var quantity: RuStorePayQuantity = null
var sandbox: bool = false
invoiceId— идентификатор счета. Используется для серверной валидации платежа, поиска платежей в консоли разработчика, а также отображается покупателю в истори и платежей в мобильном приложении RuStore.orderId— уникальный идентификатор оплаты, указанный разработчиком или сформированный автоматически (uuid).productId— идентификатор приобретенного продукта, указанный при создании в консоли разработчика RuStore.productType— тип продукта.purchaseId— идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупке.purchaseType— тип покупки (ONE_STEP/TWO_STEP/UNDEFINED— одностадийная/двухстадийная/стадийность не определена).quantity— количество товара.sandbox— флаг, указывающий признак тестового платежа в песочнице. ЕслиTRUE- покупка совершена в режиме тестирования.
Обработка ошибки оплаты
Если в процессе оплаты возникает ошибка или пользователь отменяет покупку, выполнение метода оплаты (как с выбором типа покупки, так и двухстадийного метода) завершается с ошибкой:
ProductPurchaseException— ошибка покупки продукта.ProductPurchaseCancelled— ошибка, вызванная отменой покупки продукта (пользователь закрыл платежную шторку) до получения результата покупки. В таком случае рекомендуется дополнительно проверить статус покупки методом получения информации о покупке.
Структура ошибки и отмены покупки:
ProductPurchaseResult— результат успешной оплаты цифрового товара (для одностадийной оплаты) или успешного холдирования средств (для двухстадийной оплаты).
class ProductPurchaseException extends RuStorePaymentException:
var invoiceId: RuStorePayInvoiceId = null
var orderId: RuStorePayOrderId = null
var productId: RuStorePayProductId = null
var productType: ERuStorePayProductType.Item = 0
var purchaseId: RuStorePayPurchaseId = null
var purchaseType: ERuStorePayPurchaseType.Item = 0
var quantity: RuStorePayQuantity = null
var sandbox: bool = false
invoiceId— идентификатор счёта. Используется для серверной валидации платежа, поиска платежей в консоли разработчика, а также отображается покупателю в истории платежей в мобильном приложении RuStore.orderId— уникальный идентификатор оплаты, указанный разработчиком или сформированный автоматически (uuid).productId— идентификатор приобретённого продукта, указанный при создании в консоли разработчика RuStore.productType- тип продукта (NON_CONSUMABLE_PRODUCT- непотребляемый товар,CONSUMABLE_PRODUCT- потребляемый товар,SUBSCRIPTION- подписка).purchaseId— идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупке.purchaseType— тип покупки (ONE_STEP/TWO_STEP/UNDEFINED— одностадийная/двухстадийная/стадийность не определена).quantity— количество товара, заданное при старте покупки.sandbox— флаг, указывающий признак тестового платежа в песочнице. Еслиtrue— покупка совершена в режиме тестирования.
ProductPurchaseCancelled — отмена покупки цифрового товара. Платёжный диалог был закрыт до получения результата покупки, поэтому состояние покуп ки неизвестно. Рекомендуется запросить статус покупки отдельно методом получения информации о покупке.
class ProductPurchaseCancelled extends RuStorePaymentException:
var productType: ERuStorePayProductType.Item = 0
var purchaseId: RuStorePayPurchaseId = null
var purchaseType: ERuStorePayPurchaseType.Item = 0
purchaseId— идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупке.purchaseType— тип покупки (ONE_STEP/TWO_STEP/UNDEFINED— одностадийная/двухстадийная/стадийность не определена).productType— тип продукта (NON_CONSUMABLE_PRODUCT— непотребляемый товар,CONSUMABLE_PRODUCT— потребляемый товар,SUBSCRIPTION— подписка).
func _on_any_purchase_failure(product_id: RuStorePayProductId, error: RuStoreError):
if is_instance_of(error, RuStorePaymentException.ProductPurchaseCancelled):
var cancelled_error = error as RuStorePaymentException.ProductPurchaseCancelled
OS.alert(cancelled_error.purchaseId.value, error.name)
elif is_instance_of(error, RuStorePaymentException.ProductPurchaseException):
var exception_error = error as RuStorePaymentException.ProductPurchaseException
OS.alert(exception_error.purchaseId.value, error.name)
else:
OS.alert(error.description, error.name)
Серверная валидация покупки
Если вам необходимо произвести валидацию успешной покупки на сервере RuStore, вы можете использовать subscriptionToken в SuccessProductPurchaseResult, возвращаемой при успешной покупке продукта.
func _on_purchase_two_step_success(result: RuStorePayProductPurchaseResult):
if result is RuStorePayProductPurchaseResult.SuccessProductPurchaseResult:
yourApi.validate(result.subscriptionToken);
Также можно получить subscriptionToken в сущности Purchase. Сущность Purchase можно получить используя метод get_purchases.
func _on_get_purchases_success(purchases: Array[RuStorePayPurchase]):
for item in purchases:
yourApi.validate(item.subscriptionToken);