SDK Платежи in-app для Godot (версия 10.0.0)
With RuStore you can integrate payments in your mobile app.
-
If you don't know where to start read the instruction.
-
If you migrate to Pay SDK from billingClient SDK, see the migration instructions. For more details, see here.
Подготовка к работе
- Copy the plugin and example application projects from the official RuStore repository on GitFlic.
- Copy the contents of the
godot_example/android/pluginsfolder to theyour_project/android/pluginsfolder. - In the Android build preset, in the Plugins list, check the Ru Store Godot Pay and Ru Store Godot Core plugins.
- For Godot 4.2.2 and older, in the
your_project/android/build/build.gradlefile, add theresolutionStrategysection:
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
Initialize the library before calling its methods. The initialization itself is done automatically, however, for your SDK to work, in your Manifest.xml file define console_app_id_value and 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" />
Both values must be placed inside the <application> tag. Also, add the attribute tools:replace="android:label" to the <application> tag.
<?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"
<!-- Additional attribute -->
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 — product ID form the RuStore Console.
Where are app IDs in the RuStore Console?
- Navigate to the Applications tab and selected the needed app.
- Copy the ID from the URL address of the app page — it is a set of numbers between
apps/and/versions. FOr example, for URL addresshttps://console.rustore.ru/apps/123456/versionsthe app ID is123456.

- The
ApplicationIdspecified inbuild.gradlemust match theapplicationIdof the APK file you published in the RuStore Console. -
The
keystoresignature must match the signature that was used to sign the app published in the RuStore Console. Make sure thatbuildTypeused (example:debug) uses the same signature as the published app (example:release).
debug) of the app must match the signature of the app build that was uploaded to the console and passed moderation (for example, release)For security purposes, the SDK sets android:usesCleartextTraffic="false" by default to prevent data transmission over unsecured HTTP and protect against "Man-in-the-Middle" attacks. If your application requires the use of HTTP, you can change this attribute to true, but do so at your own risk, as it increases the chance of data interception and tampering. We recommend allowing unsecured traffic only in exceptional cases and for trusted domains, preferring HTTPS for all network interactions.
<?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
A deeplink in the RuStore Payments SDK is required for proper interaction with third-party payment applications. It helps users complete purchases faster in an external app and return to your application.
To set up deeplink support in your application and the RuStore SDK, specify the deeplinkScheme inside your AndroidManifest file and override the onNewIntent method of your Activity. Additionally, for the SDK to work, you need to specify sdk_pay_scheme_value in your Manifest.xml file.
<?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" />
<!-- Deeplink scheme -->
<meta-data
android:name="sdk_pay_scheme_value"
android:value="@string/rustore_PayClientSettings_deeplinkScheme" />
<!-- Your activity -->
<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>
<activity-alias
android:enabled="true"
android:exported="true"
android:name=".RuStoreDeeplink"
android:targetActivity=".GodotApp" >
<!-- Deeplink 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="@string/rustore_PayClientSettings_deeplinkScheme" />
</intent-filter>
</activity-alias>
</application>
</manifest>
The values sdk_pay_scheme_value and data android:scheme should be located in a resource file, for example: your_project/android/build/res/values/rustore_values.xml.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<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>
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);
}
}
The proceedIntent method has an overload with an additional parameter maxRetryTimeMs: Long.
long maxRetryTimeMs = 5000L;
RuStoreGodotPay.proceedIntent(intent, maxRetryTimeMs);
maxRetryTimeMs— the maximum time (in milliseconds) for retrying the initialization of the payment client (default is 5000 ms).
Работа с SDK
Create a RuStoreGodotPayClient instance before using the plugin methods.
var _pay_client: RuStoreGodotPayClient = RuStoreGodotPayClient.get_instance()
Проверка доступности работы с платежами
To check purchase availability, call the get_purchase_availability method. On calling, the following conditions are checked.
- Monetization is enabled for the company in the RuStore Developer Console.
- The app must not be blocked in RuStore.
- The user must not be blocked in RuStore.
RuStorePayGetPurchaseAvailabilityResult.isAvailable == true is returned.
Otherwise, the method returns RuStorePayGetPurchaseAvailabilityResult.isAvailable == false and RuStorePayGetPurchaseAvailabilityResult.cause, where cause is an error indicating which condition was not met (possible errors are described in the Error handling section).
Before using the method, subscribe to the events once:
on_get_purchases_availability_success;on_get_purchases_availability_failure.
func _ready():
# Initialize _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()
Проверка статуса авторизации пользователя
To check the user's authorization status, call the get_user_authorization_status method. The method returns a value of the ERuStorePayUserAuthorizationStatus.Item enum:
AUTHORIZED— the user is authorized in RuStore.UNAUTHORIZED— the user is not authorized in RuStore. This value is also returned if the RuStore mobile app is not installed on the user's device.
Before using the method, subscribe to the events once:
on_get_user_authorization_status_success;on_get_user_authorization_status_failure.
func _ready():
# Initialize _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()