Skip to main content

SDK Платежи in-app для Godot (версия 10.0.0)

With RuStore you can integrate payments in your mobile app.

tip

Подготовка к работе

  1. Copy the plugin and example application projects from the official RuStore repository on GitFlic.
  2. Copy the contents of the godot_example/android/plugins folder to the your_project/android/plugins folder.
  3. In the Android build preset, in the Plugins list, check the Ru Store Godot Pay and Ru Store Godot Core plugins.
  4. For Godot 4.2.2 and older, in the your_project/android/build/build.gradle file, add the resolutionStrategy section:
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.

Specifying console_app_id 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.

AndroidManifest.xml
<?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?
  1. Navigate to the Applications tab and selected the needed app.
  2. 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 address https://console.rustore.ru/apps/123456/versions the app ID is 123456.

Important
  • The ApplicationId specified in build.gradle must match the applicationId of the APK file you published in the RuStore Console.
  • The keystore signature must match the signature that was used to sign the app published in the RuStore Console. Make sure that buildType used (example: debug) uses the same signature as the published app (example: release).

warning
Test build signature (for example: debug) of the app must match the signature of the app build that was uploaded to the console and passed moderation (for example, release)
info

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.

Example rustore_values.xml
<?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>

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.

AndroidManifest.xml
<?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.

Example 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>
Example GodotApp.java
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.

Calling the proceedIntent method
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.

Creating RuStoreGodotPayClient instance
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.
If all above conditions are met, 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.
Subscribe to events
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
Call get_purchase_availability
_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.
Subscribe to events
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
Call GetUserAuthorizationStatus
_pay_client.get_user_authorization_status()

Получение списка продуктов

To retrieve the products added to your application via the RuStore Console, you must use the method:s get_products.

Before using the method, subscribe to the events once:

  • on_get_products_success;
  • on_get_products_failure.
Subscribe to events
func _ready():
# Initialize _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
Call get_products
var PRODUCT_IDS: Array[RuStorePayProductId] = [
RuStorePayProductId.new("con_1"),
RuStorePayProductId.new("non_con_1"),
]

_pay_client.get_products(PRODUCT_IDS)

product_ids — the list of product IDs that are set when products are created in the RuStore Console. The list is limited by 1000 items.

Where are product IDs in the RuStore Console?
  1. Navigate to the Applications tab and selected the needed app.
  2. Select Monetization in the left menu.
  3. Select product type: Subscriptions or In-App purchases.
  4. Copy the IDs of the required products.

The method returns a list of products. The product model is shown below.

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
  • productId — product ID assigned to product in RuStore Console (mandatory).
  • type — product type. CONSUMABLE/NON-CONSUMABLE/SUBSCRIPTION (consumable/non-consumable/subscription).
  • amountLabel — formatted purchase price, including currency symbol.
  • price — price in minimum currency units.
  • currency — ISO 4217 currency code.
  • title — product name in language.
  • description — descriptions in language.
  • imageUrl — image URL.

Получение списка покупок

To get a list of the user’s purchases, use the get_purchases method.

Before using the method, subscribe to the events once:

  • on_get_purchases_success;
  • on_get_purchases_failure.
Subscribe to events
func _ready:
# Initialize _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
Call the method to get the user's purchases
# Initialize _pay_client

# Call without filters
_pay_client.get_purchases()

# Call with filters
var product_type = ERuStorePayProductType.Item.CONSUMABLE_PRODUCT
var purchase_status = ERuStorePayPurchaseStatusFilter.Item.CONFIRMED

_pay_client.get_purchases(product_type, purchase_status)

A filtered call lets you filter purchases by product type and purchase status:

product_type — product types:

  • ERuStorePayProductType.Item.NON_CONSUMABLE_PRODUCT — non-consumable products.
  • ERuStorePayProductType.Item.CONSUMABLE_PRODUCT — consumable products.
  • ERuStorePayProductType.Item.SUBSCRIPTION — subscriptions.

purchase_status — purchase statuses:

  • For products:

    • ERuStorePayPurchaseStatusFilter.Item.PAID — funds have been held successfully; the purchase is awaiting developer confirmation.
    • ERuStorePayPurchaseStatusFilter.Item.CONFIRMED — the purchase has been confirmed and the funds have been charged.
  • For subscriptions:

    • ERuStorePayPurchaseStatusFilter.Item.ACTIVE — the subscription is active.
    • ERuStorePayPurchaseStatusFilter.Item.PAUSED — the subscription is in a hold period (for example, due to insufficient funds on the card). Retry attempts continue according to the subscription plan settings.

By default, filters are disabled. If no values are provided, the method returns all user purchases in the PAID, CONFIRMED, ACTIVE, and PAUSED statuses, regardless of product type.

Получение сведений о покупке

Go get purchase information, use the get_purchase method.
Subscription on the events
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
Call the method to get the user's purchase information
var purchase_id: RuStorePayPurchaseId = ...

_pay_client.get_purchase(purchase_id)

Типы покупок

The SDK provides a base class, RuStorePayPurchase, which contains common fields for all purchase types. Two implementations are built on top of it:

  • RuStorePayProductPurchase: for consumable and non-consumable purchases.
  • RuStorePaySubscriptionPurchase: for subscriptions.

This separation allows each purchase type to have its own unique properties and behavior.

Base purchase class
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

One-time purchase model
class_name RuStorePayProductPurchase extends RuStorePayPurchase

var productId: RuStorePayProductId = null
var productType: ERuStorePayProductType.Item = 0
var quantity: RuStorePayQuantity = null
var status: ERuStorePayProductPurchaseStatus.Item = 0

Inherited fields:

  • purchaseId — product ID.

  • invoiceId — invoice ID.

  • orderId — payment ID generated by the app (optional). If you specify this parameter in your system, you will receive it via our API. If not specified, will be generated automatically (uuid). 150 characters max.

  • PurchaseType — purchase type:

    • ONE_PHASE - one-stage payment;
    • TWO_PHASE - two-stage payment;
    • UNDEFINED - number of stages is undefined.
  • description — descriptions in language.

  • purchaseTime — purchase time.

  • price — price in minimum currency units.

  • amountLabel — formatted purchase price, including currency symbol.

  • currency — ISO 4217 currency code.

  • developerPayload — a string with additional order information that you can set when confirming the purchase. This string overrides the value set during initialization
  • — test payment flag. true — test payment, false — actual payment

Unique fields:

  • productId — product ID assigned to product in RuStore Console (mandatory).

  • productType — product type.

    • NON_CONSUMABLE_PRODUCT;
    • CONSUMABLE_PRODUCT.
  • quantity — product amount (optional, value 1 will be used if not specified).

  • status — purchase state:

    • INVOICE_CREATED — purchase invoice is created and awaiting payment;
    • CANCELLED — purchase canceled by the user;
    • PROCESSING — payment initiated;
    • REJECTED — purchase rejected (for example: due to insufficient funds);
    • CONFIRMED — purchase successfully paid for;
    • REFUNDED — purchase successfully refunded;
    • REFUNDING — refunding initiated, request sent to the acquirer;
    • EXECUTING — the purchase is in progress;
    • EXPIRED — payment time expired;
    • PAID — only for two-stage payments, intermediate status, funds are put on hold on the user's account, the purchase is awaiting confirmation from the developer;
    • REVERSED — only for two-stage payment: wither the purchase was canceled by the developer or there was no payment within 6 hours, the funds on the user's account are put off hold.

Статусная модель покупки

One-stage payment status model.

Two-stage payment status model.

Модель подписки SubscriptionPurchase

class_name RuStorePaySubscriptionPurchase extends RuStorePayPurchase

var productId: RuStorePayProductId = null
var expirationDate: RuStorePayTime = null
var gracePeriodEnabled: bool = false
var status: ERuStorePaySubscriptionPurchaseStatus.Item = 0

Inherited fields:

  • purchaseId — product ID.

  • invoiceId — invoice ID.

  • orderId — payment ID generated by the app (optional). If you specify this parameter in your system, you will receive it via our API. If not specified, will be generated automatically (uuid). 150 characters max.

  • PurchaseType — purchase type:

    • ONE_PHASE - one-stage payment;
    • TWO_PHASE - two-stage payment;
    • UNDEFINED — number of payment stages is undefined.
  • description — descriptions in language.

  • purchaseTime — purchase time.

  • price — price in minimum currency units.

  • amountLabel — formatted purchase price, including currency symbol.

  • currency — ISO 4217 currency code.

  • developerPayload — a string with additional order information that you can set when confirming the purchase. This string overrides the value set during initialization
  • — test payment flag. true — test payment, false — actual payment

Unique fields:

  • productId — product ID assigned to product in RuStore Console (mandatory). The product ID assigned to the product in the RuStore Developer Console (required).

  • expirationDate — subscription expiration date.

  • gracePeriodEnabled — indicates whether the subscription grace period is enabled.

  • status — subscription status:

    • INVOICE_CREATED — an invoice has been created; the subscription is awaiting payment.
    • CANCELLED — the subscription invoice has been cancelled.
    • EXPIRED — the invoice payment period has expired.
    • PROCESSING — the first subscription payment is being processed.
    • REJECTED — the first subscription payment was rejected. The subscription was not activated.
    • ACTIVE — the subscription is active.
    • PAUSED — the subscription is paused due to payment issues.
    • TERMINATED — all retry attempts for subscription charges have been exhausted (all failed). The subscription was closed automatically due to payment issues.
    • CLOSED — the subscription was cancelled by the user or the developer. The paid period has ended; the subscription is closed.

Статусная модель подписки

Покупка продукта

One-step vs. two-step payments
  • With a one-step payment, the purchase does not require confirmation: funds are debited from the buyer’s account immediately, and a commission is charged to the developer. In this case, if you need to refund the customer (for example, if you cannot deliver the product for some reason), you can only issue a refund via the RuStore Developer Console. The funds are returned to the buyer within a few days. The full purchase amount is refunded, while the charged commission is not reimbursed to the developer.
  • With a two-step payment, funds are first held on the buyer’s account. No commission is charged at this stage. After the hold, the purchase must be confirmed or cancelled. The commission is charged to the developer when the purchase is confirmed. Cancelling a purchase releases the hold, and the funds become available to the buyer immediately.
Important

Two-step payments are available only for a limited set of payment methods (currently, cards only). SBP payment methods do not support two-step payments. If the selected payment method does not support holding funds, the purchase will be processed as a one-step payment.

Payment with purchase type selection

To purchase a product with purchase type selection, use the purchase method.

Before using the method, subscribe to the events once:

  • on_purchase_success;
  • on_purchase_failure.
Subscribe to events
func _ready():
# Initialize _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
Call the product purchase method
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

_pay_client.purchase(parameters, preferredPurchaseType)
  • productId — product ID assigned to product in RuStore Console (mandatory).
  • quantity — product amount (optional, value 1 will be used if not specified).
  • orderId — payment ID generated by the app (optional). If you specify this parameter in your system, you will receive it via our API. If not specified, will be generated automatically (uuid). 150 characters max.
  • developerPayload — a string with additional order information that you can set when confirming the purchase. This string overrides the value set during initialization. Maximum length is 250 characters.
  • appUserId — the internal user ID in your application (optional parameter). A string with a maximum length of 128 characters.
    tip

    For example, this parameter can be used to detect cases of fraud in your application, which will help improve its security.

  • appUserEmail — this is an optional parameter that allows you to specify the user's email address in your application. If the buyer's email address was provided during registration in the app, it can be passed for automatic filling of the email field when sending a receipt — both for payments outside RuStore and in cases where the user is not authorized in RuStore. This saves the user from having to manually enter their email, shortens the purchase flow, and helps increase conversion.
  • preferredPurchaseType — the desired purchase type: single-stage (ONE_STEP) or two-stage (TWO_STEP).
Important

This method is launched by default using the single-stage payment scenario (preferredPurchaseType = ERuStorePayPreferredPurchaseType.Item.ONE_STEP), i.e., without funds being held.

For two-stage payment, you need to specify preferredPurchaseType = ERuStorePayPreferredPurchaseType.Item.TWO_STEP. Two-stage payment (i.e., payment with funds being held) is not guaranteed for this method and directly depends on the payment method (card, SPB, etc.) selected by the user.

When launching this method (with the preferred preferredPurchaseType = twoStep), until the user selects a payment method, the purchase stage will be UNDEFINED. Please take this behavior into account when handling purchase cancellation results (ProductPurchaseCancelled) or purchase errors (ProductPurchaseException).

Two-step payment (with funds hold)

To purchase product, use the purchase_two_step method.

Before using the method, subscribe to the events once:

  • on_purchase_two_step_success;
  • on_purchase_two_step_failure.
Subscribe to events
func _ready():
# Initialize _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
Call the product purchase method
var parameters = RuStorePayProductPurchaseParams.new (
RuStoreProductId.new("product_id"), # productId
null, # appUserEmail
null, # appUserId
null, # developerPayload
null, # orderId
RuStoreQuantity.new(1)); # quantity
);

_pay_client.purchase_two_step(parameters)

Purchase parameters structure

Purchase parameters structure
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 — product ID assigned to product in RuStore Console (mandatory).
  • quantity — product amount (optional, value 1 will be used if not specified).
  • orderId — payment ID generated by the app (optional). If you specify this parameter in your system, you will receive it via our API. If not specified, will be generated automatically (uuid). 150 characters max.
  • developerPayload — a string with additional order information that you can set when confirming the purchase. This string overrides the value set during initialization. Maximum length is 250 characters.
  • appUserId — the internal user ID in your application (optional parameter). A string with a maximum length of 128 characters.
    tip

    For example, this parameter can be used to detect cases of fraud in your application, which will help improve its security.

  • appUserEmail — this is an optional parameter that allows you to specify the user's email address in your application. If the buyer's email address was provided during registration in the app, it can be passed for automatic filling of the email field when sending a receipt — both for payments outside RuStore and in cases where the user is not authorized in RuStore. This saves the user from having to manually enter their email, shortens the purchase flow, and helps increase conversion.
Purchase result structure
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 — invoice ID. Used for server-side payment validation, searching for payments in the Developer Console, and displayed to the user in the payment history in the RuStore mobile app.
  • orderId — a unique payment ID specified by the developer or generated automatically (uuid).
  • productId — the ID of the purchased product specified when creating it in the RuStore Developer Console.
  • productType — product type.
  • purchaseId — purchase ID. Used to retrieve purchase information in the SDK using the Get purchase info method.
  • purchaseType — purchase type (ONE_STEP/TWO_STEP/UNDEFINED — one-step/two-step/undefined).
  • quantity — product quantity.
  • sandbox — indicates a sandbox (test) payment. If TRUE, the purchase was made in test mode.

Обработка ошибки оплаты

If an error occurs during payment or the user cancels the purchase, the payment method execution (both with purchase type selection and the two-step method) ends with an error:

  • ProductPurchaseException — a product purchase error.
  • ProductPurchaseCancelled — an error caused by cancelling a product purchase (the user closed the payment bottom sheet) before the purchase result was received.
    In this case, we recommend additionally checking the purchase status using the Get purchase info method.

Purchase error/cancellation structure:

  • ProductPurchaseResult — the result of a successful purchase of a digital item (for one-step payments) or a successful funds hold (for two-step payments).
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 — invoice ID. Used for server-side payment validation, searching for payments in the Developer Console, and displayed to the user in the payment history in the RuStore mobile app.
  • orderId — a unique payment ID specified by the developer or generated automatically (UUID).
  • productId — the ID of the purchased product specified when creating it in the RuStore Developer Console.
  • productType — product type (NON_CONSUMABLE_PRODUCT — non-consumable, CONSUMABLE_PRODUCT — consumable, SUBSCRIPTION — subscription).
  • purchaseId — purchase ID. Used to retrieve purchase information in the SDK using the Get purchase info method.
  • purchaseType — purchase type (ONE_STEP/TWO_STEP/UNDEFINED — one-step/two-step/undefined).
  • quantity — product quantity specified when starting a purchase.
  • sandbox — indicates a sandbox (test) payment. If true, the purchase was made in test mode.

ProductPurchaseCancelled — cancellation of a digital product purchase. The payment dialog was closed before the purchase result was received, so the purchase state is unknown. We recommend requesting the purchase status separately using the Get purchase info method.

class ProductPurchaseCancelled extends RuStorePaymentException:

var productType: ERuStorePayProductType.Item = 0
var purchaseId: RuStorePayPurchaseId = null
var purchaseType: ERuStorePayPurchaseType.Item = 0
  • purchaseId — purchase ID. Used to retrieve purchase information in the SDK using the Get purchase info method.
  • purchaseType — purchase type (ONE_STEP/TWO_STEP/UNDEFINED — one-step/two-step/undefined).
  • productType — product type (NON_CONSUMABLE_PRODUCT — non-consumable, CONSUMABLE_PRODUCT — consumable, SUBSCRIPTION — subscription).
Error handling example
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)

Серверная валидация покупки

If you need to validate a purchase on the RuStore server, you can use subscriptionToken in SuccessProductPurchaseResult, that is returned on successful purchase.

Retrieving subscriptionToken from purchase result
func _on_purchase_two_step_success(result: RuStorePayProductPurchaseResult):
if result is RuStorePayProductPurchaseResult.SuccessProductPurchaseResult:
yourApi.validate(result.subscriptionToken);

You can also get a subscriptionToken from the Purchase entity. The Purchase entity can be retrieved using the get_purchases method.

Getting subscriptionToken from products list
func _on_get_purchases_success(purchases: Array[RuStorePayPurchase]):
for item in purchases:
yourApi.validate(item.subscriptionToken);

Подтверждение покупки

Us the consume_purchase method to confirm a purchase. Purchase confirmation request must be accompanied by the delivery of the product. After calling the confirmation method the purchase changes its state to CONSUMED.

Before using the method, subscribe to the events once:

  • on_confirm_two_step_purchase_success;
  • on_confirm_two_step_purchase_failure.
Subscribe to events
func _ready:
# Initialize _pay_client

_pay_client.on_confirm_two_step_purchase_success(_on_confirm_two_step_purchase_success)
_pay_client.on_confirm_two_step_purchase_failure(_on_confirm_two_step_purchase_failure)

func _on_confirm_two_step_purchase_success(purchase_id: RuStorePayPurchaseId):
pass

func _on_confirm_two_step_purchase_failure(purchase_id: RuStorePayPurchaseId, error: RuStoreError):
pass
Call the confirmation method
var id: RuStorePayPurchaseId = ...
var payload: RuStorePayDeveloperPayload = ...

_pay_client.confirm_two_step_purchase(id, payload)
  • id — product ID.
  • payload — a string with additional order information that you can set when confirming the purchase. This string overrides the value set during initialization

Отмена покупки

To cancel a purchase, use the cancel_two_step_purchase method.

Before using the method, subscribe to the events once:

  • on_cancel_two_step_purchase_success;
  • on_cancel_two_step_purchase_failure.
Subscribe to events
func _ready:
# Initialize _pay_client

_pay_client.on_cancel_two_step_purchase_success(_on_cancel_two_step_purchase_success)
_pay_client.on_cancel_two_step_purchase_failure(_on_cancel_two_step_purchase_failure)

func _on_cancel_two_step_purchase_success(purchase_id: RuStorePayPurchaseId):
pass

func _on_cancel_two_step_purchase_failure(purchase_id: RuStorePayPurchaseId, error: RuStoreError):
pass
Call cancel_two_step_purchase
# Your UI implementation for purchase cancellation
func _on_cancel_two_step_purchase_pressed(purchaseId: RuStorePayPurchaseId):
_pay_client.cancel_two_step_purchase(purchaseId)
purchaseId — product ID

  • The on_cancel_two_step_purchase_success callback returns the purchase ID.
  • The on_cancel_two_step_purchase_failure callback returns the purchase ID (as a String) and a RuStoreError object with error details. The error structure is described in the Error handling section.

RuStoreUtils

RuStoreUtils is a block in the native SDK that contains a set of public methods for interacting with the RuStore application on the user's device.

To access the block's methods in the Godot environment, the RuStoreGodotCoreUtils class singleton is used.

The is_rustore_installed method checks if the RuStore application is installed on the user's device.

Calling the is_rustore_installed method
var _core_client: RuStoreGodotCoreUtils = RuStoreGodotCoreUtils.get_instance()

var is_rustore_installed: Variant = _core_client.is_rustore_installed()

if is_rustore_installed == true:
print("RuStore is installed on the user's device")
elif is_rustore_installed == false:
print("RuStore is not installed on the user's device")
else:
print("State is unknown (null)")

The open_rustore_download_instruction method opens a web page to download the RuStore mobile application.

Calling the open_rustore_download_instruction method
var _core_client: RuStoreGodotCoreUtils = RuStoreGodotCoreUtils.get_instance()

_core_client.open_rustore_download_instruction();

The open_rustore method launches the RuStore mobile application. When calling this method, if the RuStore application is not installed, a Toast notification with the message "Failed to open the application" will be displayed.

Calling the open_rustore method
var _core_client: RuStoreGodotCoreUtils = RuStoreGodotCoreUtils.get_instance()

_core_client.Instance.open_rustore();

The open_rustore_authorization method launches the RuStore mobile application for authorization. After successful user authorization, the RuStore application closes automatically. When calling this method, if the RuStore application is not installed, a Toast notification with the message "Failed to open the application" will be displayed.

Calling the open_rustore_authorization method
var _core_client: RuStoreGodotCoreUtils = RuStoreGodotCoreUtils.get_instance()

_core_client.Instance.open_rustore_authorization();

Список ошибок

RuStoreError is the base error class.

RuStoreError class
class_name RuStoreError extends RefCounted

var name: String = ""
var description: String = ""
  • name – error name.
  • description – error description.

RuStorePaymentException is the base error class for the payment client.

class_name RuStorePaymentException extends RuStoreError

var cause: RuStoreError = null

...
  • cause – additional error information.

Inherited fields:

  • name – error name.
  • description – error description.

RuStorePaymentNetworkException is a network error in the SDK. The error model returns an error code (code) that can be used to determine the cause of the error. The table of error codes is available in the Error codes section.

RuStorePaymentNetworkException class
class_name RuStorePaymentException extends RuStoreError

...

class RuStorePaymentNetworkException extends RuStorePaymentException:

var code = ""
var id: String = ""
  • code — error code.
  • id — error identifier.

Inherited fields:

  • name – error name.
  • description – error description.
  • cause – additional error information.

Возможные ошибки

  • RuStorePaymentNetworkException — SDK network communication error;
  • RuStorePaymentCommonException — general SDK error;
  • RuStorePayClientAlreadyExist — SDK re-initialization error;
  • RuStorePayClientNotCreated — attempt to access public SDK interfaces before initialization;
  • RuStorePayInvalidActivePurchase — payment initiated for unknown product type;
  • RuStorePayInvalidConsoleAppId — required parameter console_application_id for SDK initialization is not specified;
  • RuStorePaySignatureException — invalid response signature. Occurs when attempting fraudulent actions;
  • EmptyPaymentTokenException — error obtaining payment token;
  • InvalidCardBindingIdException — error paying with a saved card;
  • ApplicationSchemeWasNotProvided — scheme for the return deeplink is not specified;
  • ProductPurchaseException — product purchase error. The model structure is described in the section purchase result structure;
  • ProductPurchaseCancelled — product purchase was cancelled (the user closed the payment sheet). The model structure is described in the section purchase result structure;
  • ProductPurchaseException — product purchase error;
  • RuStoreNotInstalledException — RuStore is not installed on the user's device;
  • RuStoreOutdatedException — the installed version of RuStore on the device does not support payments;
  • RuStoreUserUnauthorizedException — the user is not authorized in RuStore;
  • RuStoreApplicationBannedException — the application is banned in RuStore;
  • RuStoreUserBannedException — the user is banned in RuStore.