9.1.0
RuStore позволяет интегрировать платежи в мобильное приложение.
-
Если не знаете с чего начать, прочтите инструкцию в сценариях использования.
-
Если вы переходите на Pay SDK с billingClient SDK, ознакомьтесь с инструкцией по переходу. Подробности о Pay SDK можно узнать тут.
Подключение в проект
- Скопируйте проекты плагина и приложения-примера из официального репозитория RuStore на GitFlic.
- Скопируйте папки
pay_example / extension_rustore_payиpay_example / extension_rustore_coreв корень вашего проекта.
Инициализация
Перед вызовом методов библиотеки необходимо выполнить её инициализацию. Сама инициализация происходит автоматически, но для работы SDK в вашем файле Manifest.xml необходимо прописать console_app_id_value и internal_config_key. Оба значения должны располагаться внутри тега <application>
<!-- 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" />
console_app_id_value — идентификатор приложения из RuStore консоли.
Где в RuStore Консоль отображаются идентификаторы приложений?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Скопируйте идентификатор из URL-адреса страницы приложения — это набор цифр между
apps/и/versions. Например, для URL-адресаhttps://console.rustore.ru/apps/123456/versionsID приложения —123456.

Не задавайте значения console_app_id_value и internal_config_key напрямую в манифесте. Строки должны располагаться в файле ресурсов.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rustore_PayClientSettings_consoleApplicationId" translatable="false">2063572661</string>
<string name="rustore_PayClientSettings_internalConfigKey" translatable="false">defold</string>
<string name="rustore_PayClientSettings_deeplinkScheme" translatable="false">yourappscheme</string>
</resources>
Также, чтобы обеспечить правильное поведение платежной шторки при сворачивании приложения, игровому активити необходимо задать режим запуска android:launchMode="singleTop".
<?xml version="1.0" encoding="utf-8"?>
<activity android:name="com.dynamo.android.DefoldActivity"
android:label="{{project.title}}"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="{{orientation-support}}"
android:exported="true"
android:launchMode="singleTop">
<meta-data android:name="android.app.lib_name"
android:value="{{exe-name}}" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Package Name приложения, указанный в game.project → Android → Package, должен совпадать с Package Name APK-файла, который вы публиковали в системе RuStore Консоль.
Обработка deeplink
Deeplink в RuStore SDK платежей нужна для корректной работы со сторонними приложениями оплаты. Она помогает пользователям быстрее совершать покупки в стороннем приложении и возвращаться в ваше приложение.
Плагин RuStorePay содержит реализацию RuStoreIntentFilterActivity, которая обрабатывает входящие intent и возвращается в игровую активити com.dynamo.android.DefoldActivity.
Для включения в сборку добавьте RuStoreIntentFilterActivity в AndroidManifest.xml указав intent-filter и meta-data.
<!-- Deeplink activity -->
<activity android:name="ru.rustore.defold.pay.RuStoreIntentFilterActivity"
android:exported="true"
android:launchMode="singleTask">
<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>
<!-- Deeplink scheme -->
<meta-data
android:name="sdk_pay_scheme_value"
android:value="@string/rustore_PayClientSettings_deeplinkScheme" />
Пример оформления манифеста
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="{{android.package}}"
android:versionCode="{{android.version_code}}"
android:versionName="{{project.version}}"
android:installLocation="auto">
<uses-feature android:required="true" android:glEsVersion="0x00020000" />
<uses-sdk android:minSdkVersion="{{android.minimum_sdk_version}}" android:targetSdkVersion="{{android.target_sdk_version}}" />
<application
{{#has-icons?}}
android:icon="@drawable/icon"
{{/has-icons?}}
android:extractNativeLibs="{{android.extract_native_libs}}"
android:label="{{project.title}}"
tools:replace="android:label"
android:hasCode="true"
android:name="android.support.multidex.MultiDexApplication"
android:enableOnBackInvokedCallback="true"
android:debuggable="{{android.debuggable}}">
<meta-data android:name="android.max_aspect" android:value="2.1" />
<meta-data android:name="android.notch_support" android:value="true"/>
<!-- android:launchMode="singleTop" -->
<activity android:name="com.dynamo.android.DefoldActivity"
android:label="{{project.title}}"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mcc|mnc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|touchscreen|uiMode"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="{{orientation-support}}"
android:exported="true"
android:launchMode="singleTop">
<meta-data android:name="android.app.lib_name"
android:value="{{exe-name}}" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Deeplink activity -->
<activity android:name="ru.rustore.defold.pay.RuStoreIntentFilterActivity"
android:exported="true"
android:launchMode="singleTask">
<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>
<!-- Deeplink scheme -->
<meta-data
android:name="sdk_pay_scheme_value"
android:value="@string/rustore_PayClientSettings_deeplinkScheme" />
<!-- 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>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
</manifest>
<!-- END_INCLUDE(manifest) -->
Реализация RuStoreIntentFilterActivity
package ru.rustore.defold.pay;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import ru.rustore.defold.pay.RuStorePay;
public class RuStoreIntentFilterActivity extends Activity {
private final String defoldActivityClassName = "com.dynamo.android.DefoldActivity";
private Class<?> getActivityClass(String activityClassName) {
Class<?> activityClass = null;
try {
activityClass = Class.forName(activityClassName);
} catch(ClassNotFoundException ex) {
}
return activityClass;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
RuStorePay.INSTANCE.proceedIntent(getIntent());
}
startGameActivity(getIntent(), defoldActivityClassName);
finish();
}
@Override
public void onNewIntent(Intent newIntent)
{
super.onNewIntent(newIntent);
RuStorePay.INSTANCE.proceedIntent(newIntent);
startGameActivity(newIntent, defoldActivityClassName);
finish();
}
private void startGameActivity(Intent intent, String gameActivityClassName) {
Class<?> gameActivityClass = getActivityClass(gameActivityClassName);
if (gameActivityClass != null) {
Intent newIntent = new Intent(this, gameActivityClass);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
if (intent != null) newIntent.putExtras(intent.getExtras());
startActivity(newIntent);
}
}
}
Работа с SDK
Доступные публичные методы:
get_purchase— позволяет получить информацию о покупке по её ID.get_purchases— позволяет получить покупки пользователя. Данный метод поддерживает опциональную фильтрацию по типу товаров (потребляемые или непотребляемые товары), а также по статусу покупки (поддерживаются статусыPAIDиCONFIRMED). По умолчанию фильтры отключены, и вернутся все покупки пользователя (независимо от типа товара) в статусахPAIDиCONFIRMED.get_purchase_availability— возвращает результат доступности работы с платежами.purchase— позволяет совершить покупку продукта с указанием желаемого типа оплаты - одностадийной (ONE_STEP) или двухстадийной (TWO_STEP). Для данного метода оплаты на платёжной шторке доступны все способы оплаты. Если параметр не задан, по умолчанию запускается с оплатой в одну стадию.
Если указан тип оплаты TWO_STEP, будет произведена попытка запустить двухстадийную оплату, но итоговый результат напрямую будет зависеть от того, какой способ оплаты (карта, СБП и др.) будет выбран пользователем. Двухстадийная оплата доступна только для определенного набора способов оплаты (на текущий момент — только для карт). Технологии СБП не поддерживают двухстадийную оплату. Если выбран способ оплаты, который не поддерживает холдирование, то покупка будет запущена по сценарию с одной стадией.
purchase_two_step— запускает сценарий гарантированной двухстадийной покупки товара. При использовании данного метода пользователю на платёжной шторке доступен ограниченный набор способов оплаты — только те, которые поддерживают двухстадийную оплату. В процессе платежа сначала осуществляется холдирование денежных средств покупателя, которые списываются только после подтверждения покупки методомConfirmTwoStepPurchase.confirm_two_step_purchase— подтверждение покупки, совершенной по двухстадийной оплате.cancel_two_step_purchase— отмена покупки, совершённой по двухстадийной оплате.get_products— позволяет получить информацию по активным продуктам, опубликованным в RuStore консоль.
Данный метод возвращает не более 1000 продуктов и работает без авторизации и наличия установленного RuStore на устройстве пользователя.
- модуль
rustorecore— набор открытых методов, таких как:is_rustore_installed— проверки наличия приложения RuStore на устройстве пользователя.open_rustore_download_instruction— открывает веб-страницу для скачивания приложения RuStore.open_rustore— запускает приложение RuStore.open_rustore_authorization— запускает приложение RuStore для авторизации. После успешной авторизации пользователя приложение RuStore автоматически закроется.
Проверка доступности работы с платежами
Для проверки доступности платежей, вызовите метод get_purchase_availability. При его вызове проверяются следующие условия.
- У компании подключена монетизация через консоль разработчика RuStore.
- Приложение не должно быть заблокировано в RuStore.
- Пользователь не должен быть заблокирован в RuStore.
Перед использованием метода необходимо единожды выполнить подписку на события:
rustore_pay_on_get_purchase_availability_successrustore_pay_on_get_purchase_availability_failure
function init(self)
rustorecore.connect("rustore_pay_on_get_purchase_availability_success", _on_get_purchase_availability_success)
rustorecore.connect("rustore_pay_on_get_purchase_availability_failure", _on_get_purchase_availability_failure)
end
function _on_get_purchase_availability_success(self, channel, value)
local data = json.decode(value)
if data.isAvailable == true then
-- Process purchase available
else
-- Process purchase unavailable
end
end
function _on_get_purchase_availability_failure(self, channel, value)
local data = json.decode(value)
end
rustorepay.get_purchase_availability()
data.isAvailable == true.
В противном случае возвращается data.isAvailable == false и data.cause, где cause — это ошибка о невыполненном условии (возможные ошибки описаны в разделе Список ошибок).
Проверка статуса авторизации пользователя
Для проверки статуса авторизации пользователя, вызовите метод get_user_authorization_status. Результатом выполнения метода является значение перечисления get_user_authorization_status. Возможно только 2 значения:
AUTHORIZED— пользователь авторизован в RuStore.UNAUTHORIZED— пользователь неавторизован в RuStore. Данное значение также вернется если у пользователя нет установленного МП RuStore на девайсе.
function init(self)
rustorecore.connect("rustore_pay_on_get_user_authorization_status_success", _on_get_user_authorization_status_success)
rustorecore.connect("rustore_pay_on_get_user_authorization_status_failure", _on_get_user_authorization_status_failure)
end
function _on_get_user_authorization_status_success(self, channel, value)
if value == "AUTHORIZED" then
-- Process AUTHORIZED
elseif value == "UNAUTHORIZED" then
-- Process UNAUTHORIZED
end
end
function _on_get_user_authorization_status_failure(self, channel, value)
local data = json.decode(value)
end
rustorepay.get_user_authorization_status()
Получение списка продуктов
Для получения продуктов, добавленных в ваше приложение через RuStore консоль, необходимо использовать метод get_products.
function init(self)
rustorecore.connect("rustore_pay_on_get_products_success", _on_get_products_success)
rustorecore.connect("rustore_pay_on_get_products_failure", _on_get_products_failure)
end
function _on_get_products_success(self, channel, value)
local data = json.decode(value)
for key, val in pairs(data) do
local product_id = val.productId
-- Optional field
local description
if data.description then
description = data.description
else
description = nil
end
end
end
function _on_get_products_failure(self, channel, value)
local data = json.decode(value)
end
local PRODUCT_IDS = {
"non_con2",
"non_con1",
"con2",
"con1",
"sub2",
"sub1"}
rustorepay.get_products(PRODUCT_IDS)
local PRODUCT_IDS = {} — список идентификаторов продуктов (задаются при создании продукта в консоли разработчика). Список продуктов имеет ограничение в размере 1000 элементов.
Где в RuStore Консоль отображаются идентификаторы продуктов?
- Перейдите на вкладку Приложения и выберите нужное приложение.
- Выберите Монетизация в меню слева.
- Выберите тип товара: Подписки или Разовые покупки.
- Скопируйте идентификаторы нужных товаров.

Обратный вызов (callback) rustore_pay_on_get_products_success возвращает строку JSON с информацией о продуктах (см. ниже).
amountLabel -- string
currency -- string
description -- string (optional)
imageUrl -- string
price -- number (optional)
productId -- string
title -- string
type -- string
-- APPLICATION
-- NON_CONSUMABLE_PRODUCT
-- CONSUMABLE_PRODUCT
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).type— тип продукта.CONSUMABLE/NON-CONSUMABLE(потребляемый/непотребляемый).amountLabel— отформатированная цена покупки, включая валютный знак.price— цена в минимальных единицах (в копейках).currency— код валюты ISO 4217.title— название продукта на языкеlanguage.description— описание на языкеlanguage.imageUrl— ссылка на картинку.
Получение списка покупок
Для получения списка покупок пользователя используйте методget_purchases.
function init(self)
rustorecore.connect("rustore_pay_on_get_purchases_success", _on_get_purchases_success)
rustorecore.connect("rustore_pay_on_get_purchases_failure", _on_get_purchases_failure)
end
function _on_get_purchases_success(self, channel, value)
local data = json.decode(value)
for key, val in pairs(data) do
local purchase_id = val.purchaseId
-- Optional field
local purchase_time
if data.purchaseTime then
purchase_time = data.purchaseTime -- UTC MMM dd, yyyy h:mm:ss a
else
purchase_time = nil
end
end
end
function _on_get_purchases_failure(self, channel, value)
local data = json.decode(value)
end
rustorepay.get_purchases()
Данный метод поддерживает необязательную фильтрацию по типу товаров (потребляемые или непотреблямые товары), а также по статусу покупки (поддерживаются только статусы PAID и CONFIRMED). По умолчанию фильтр выключен и вернет все покупки пользователя (вне зависимости от типа товара) в статусах PAID и CONFIRMED. Статус PAID означает успешное холдирование средств, покупка ожидает подтверждения покупки со стороны разработчика.
local filter = {
-- productType = "CONSUMABLE_PRODUCT", -- optional
purchaseStatus = "PAID" -- optional
}
rustorepay.get_purchases(filter)
Обратный вызов (callback) rustore_pay_on_get_purchases_success возвращает строку JSON с информацией о покупках (см. ниже).
amountLabel -- string
currency -- string
description -- string
developerPayload -- string (optional)
invoiceId -- string
orderId -- string (optional)
price -- number
productId -- string
productType -- string
-- APPLICATION
-- NON_CONSUMABLE_PRODUCT
-- CONSUMABLE_PRODUCT
purchaseId -- string
purchaseTime -- string (optional) MMM dd, yyyy h:mm:ss a
purchaseType
-- ONE_STEP
-- TWO_STEP
-- UNDEFINED
quantity -- number
sandbox -- boolean
status -- string
-- INVOICE_CREATED
-- CANCELLED
-- PROCESSING
-- REJECTED
-- CONFIRMED
-- REFUNDING
-- REFUNDED
-- EXECUTING
-- EXPIRED
-- PAID
-- REVERSED
purchaseId— идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупке.productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).invoiceId— идентификатор счёта. Используется для серверной валидации платежа, поиска платежей в консоли разработчика, а также отображается покупателю в истории платежей в мобильном приложении RuStore.orderId- уникальный идентификатор оплаты, указанный разработчиком или сформированный автоматически (uuid).PurchaseType— тип покупки:ONE_STEP- одностадийная покупка;TWO_STEP- двухстадийная покупка;UNDEFINED- стадийность не определена.
productType— тип продукта. (CONSUMABLE/NON-CONSUMABLE- потребляемый/непотребляемый.)description- описание покупки.purchaseTime— время покупки.price— цена в минимальных единицах (в копейках).amountLabel— отформатированная цена покупки, включая валютный знак.currency— код валюты ISO 4217.quantity— количество продукта.status— состояние покупки:INVOICE_CREATED— создан счёт на оплату, покупка ожидает оплаты;CANCELLED— покупка отменена покупателем;PROCESSING— запущена оплата;REJECTED— покупка отклонена (например, ввиду недостатка средств);EXPIRED— истекло время на оплату покупки;PAID— только для двухстадийной оплаты, промежуточный статус, средства на счёте покупателя захолдированы, покупка ожидает подтверждения от разработчика;CONFIRMED— покупка успешно оплачена;REFUNDING— инициирован возврат, запрос отправлен в эквайер;REFUNDED— запрос на возврат средств за покупку совершён успешно. Деньги будут возвращены пользователю в течение 10 рабочих дней.;REVERSED— только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 6 часов, холдирование средств отменено.
-
developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации -
sandbox— флаг тестового платежа. Значениеtrue— тестовый платёж,false— реальный платёж.
Получение сведений о покупке
Для получения информации о покупке, используйте методgetPurchase.
function init(self)
rustorecore.connect("rustore_pay_on_get_purchase_success", _on_get_purchase_success)
rustorecore.connect("rustore_pay_on_get_purchase_failure", _on_get_purchase_failure)
end
function _on_get_purchase_success(self, channel, value)
local data = json.decode(value)
local purchase_id = data.purchaseId
-- Optional field
local purchase_time
if data.purchaseTime then
purchase_time = data.purchaseTime -- UTC MMM dd, yyyy h:mm:ss a
else
purchase_time = nil
end
end
function _on_get_purchase_failure(self, channel, error, id)
local data = json.decode(error)
local purchase_id = id
end
rustorepay.get_purchase()
Обратный вызов (callback) rustore_pay_on_get_purchase_success возвращает строку JSON с информацией о конкретной покупке в любом статусе (см. ниже).
amountLabel -- string
currency -- string
description -- string
developerPayload -- string (optional)
invoiceId -- string
orderId -- string (optional)
price -- number
productId -- string
productType -- string
-- APPLICATION
-- NON_CONSUMABLE_PRODUCT
-- CONSUMABLE_PRODUCT
purchaseId -- string
purchaseTime -- string (optional) MMM dd, yyyy h:mm:ss a
purchaseType
-- ONE_STEP
-- TWO_STEP
-- UNDEFINED
quantity -- number
sandbox -- boolean
status -- string
-- INVOICE_CREATED
-- CANCELLED
-- PROCESSING
-- REJECTED
-- CONFIRMED
-- REFUNDING
-- REFUNDED
-- EXECUTING
-- EXPIRED
-- PAID
-- REVERSED
purchaseId— идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупке.productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).invoiceId— идентификатор счёта. Используется для серверной валидации платежа, поиска платежей в консоли разработчика, а также отображается покупателю в истории платежей в мобильном приложении RuStore.orderId- уникальный идентификатор оплаты, указанный разработчиком или сформированный автоматически (uuid).PurchaseType— тип покупки:ONE_STEP- одностадийная покупка;TWO_STEP- двухстадийная покупка;UNDEFINED- стадийность не определена.
productType— тип продукта. (CONSUMABLE/NON-CONSUMABLE- потребляемый/непотребляемый.)description- описание покупки.purchaseTime— время покупки.price— цена в минимальных единицах (в копейках).amountLabel— отформатированная цена покупки, включая валютный знак.currency— код валюты ISO 4217.quantity— количество продукта.status— состояние покупки:INVOICE_CREATED— создан счёт на оплату, покупка ожидает оплаты;CANCELLED— покупка отменена покупателем;PROCESSING— запущена оплата;REJECTED— покупка отклонена (например, ввиду недостатка средств);EXPIRED— истекло время на оплату покупки;PAID— только для двухстадийной оплаты, промежуточный статус, средства на счёте покупателя захолдированы, покупка ожидает подтверждения от разработчика;CONFIRMED— покупка успешно оплачена;REFUNDING— инициирован возврат, запрос отправлен в эквайер;REFUNDED— запрос на возврат средств за покупку совершён успешно. Деньги будут возвращены пользователю в течение 10 рабочих дней.;REVERSED— только для двухстадийной оплаты, покупка была отменена разработчиком или не было произведено подтверждение покупки в течение 6 часов, холдирование средств отменено.
-
developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации -
sandbox— флаг тестового платежа. Значениеtrue— тестовый платёж,false— реальный платёж.
Статусная модель покупки
Статусная модель одностадийного платежа.
Статусная модель двухстадийного платежа.
Покупка продукта
- При использовании одностадийного платежа покупка не требует подтверждения, денежные средства сразу списываются со счёта покупателя, а с разработчика удерживается комиссия. В таком случае, если требуется вернуть денежные средства клиенту (например, по какой-то причине нет возможности поставить продукт), возможен только возврат средств через RuStore Консоль, денежные средства возвращаются покупателю через несколько дней. Возвращается полная стоимость покупки, при этом удержанная комиссия разработчику не возмещается.
- В случае использования двухстадийного платежа сначала производится холдирование ср едств на счете покупателя. Комиссия в этом случае не удерживается. После холдирования покупка требует подтверждения или отмены. Комиссия с разработчика удерживается при подтверждении покупки. Отмена покупки означает снятие холда - денежные средства мгновенно снова доступны покупателю.
Двухстадийная оплата доступна только для определенного набора способов оплаты (на текущий момент — только для карт и SberPay). Технологии СБП не поддерживают двухстадийную оплату. Если выбран способ оплаты, который не поддерживает холдирование, то покупка будет запущена по сценарию с одной стадией.
Оплата с выбором типа покупки
Для вызова покупки продукта с выбором стадийности оплаты используйте метод purchase:
function init(self)
rustorecore.connect("rustore_pay_on_purchase_success", _on_purchase_success)
rustorecore.connect("rustore_pay_on_purchase_failure", _on_purchase_failure)
end
function _on_purchase_success(self, channel, value)
-- ProductPurchaseResult
local data = json.decode(value)
local product_id = data.productId
local purchase_id = data.purchaseId
-- Optional field
local order_id
if data.orderId then
order_id = data.orderId
else
order_id = nil
end
end
function _on_purchase_failure(self, channel, error, id)
local data = json.decode(error)
local product_id = id
end
local params = {
-- appUserEmail = "user@example.com", -- (optional)
-- appUserId = "user123", -- (optional)
-- developerPayload = "payload_data", -- (optional)
-- orderId = "order_456", -- (optional)
-- quantity = 1, -- (optional)
productId = "product_id"
}
local json_params = json.encode(params)
local preferred_purchase_type = "ONE_STEP" -- "TWO_STEP"
rustorepay.purchase(json_params, preferred_purchase_type)
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых тов аров.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются.-
appUserId— внутренний ID пользователя в вашем приложении (опциональный параметр). Строка с максимальной длиной в 128 символов.подсказкаНапример, данны й параметр может использоваться для выявления случаев мошенничества в вашем приложении, что позволит повысить его безопасность.
appUserEmail- это необязательный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemailпри отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.preferredPurchaseType— желаемый тип покупки: одностадийная (ONE_STEP) или двухстадийная (TWO_STEP).
Данный метод по умолчанию запускается по одностадийному сценарию оплаты (preferredPurchaseType = PreferredPurchaseType.ONE_STEP), т.е. без холдирования средств.
Для двухстадийной оплаты нужно указать preferredPurchaseType = PreferredPurchaseType.TWO_STEP. Двухстадийная оплата (т.е. оплата с холдированием средств) для данного метода не гарантирована и напрямую зависит от того, какой способ оплаты (карта, СПБ и др.) выбрал пользователь.
При запуске данного метода (с предпочитаемым preferredPurchaseType = twoStep), до тех пор пока пользователь не выберет способ оплаты, стадийность покупки будет UNDEFINED. Учитывайте данное поведение при обработке результатов отмены (ProductPurchaseCancelled) или ошибки (ProductPurchaseException) покупки.
Двухстадийная оплата (с холдированием средств)
Для вызова покупки продукта по двухстадийному сценарию используйте метод PurchaseTwoStep:
При вызове данного метода пользователю будет доступен ограниченный набор способов оплаты — только те, которые поддерживают двухстадийную оплату.
function init(self)
rustorecore.connect("rustore_pay_on_purchase_two_step_success", _on_purchase_two_step_success)
rustorecore.connect("rustore_pay_on_purchase_two_step_failure", _on_purchase_two_step_failure)
end
function _on_purchase_two_step_success(self, channel, value)
-- ProductPurchaseResult
local data = json.decode(value)
local product_id = data.productId
local purchase_id = data.purchaseId
-- Optional field
local order_id
if data.orderId then
order_id = data.orderId
else
order_id = nil
end
end
function _on_purchase_two_step_failure(self, channel, error, id)
local data = json.decode(error)
local product_id = id
end
local params = {
-- appUserEmail = "user@example.com", -- (optional)
-- appUserId = "user123", -- (optional)
-- developerPayload = "payload_data", -- (optional)
-- orderId = "order_456", -- (optional)
-- quantity = 1, -- (optional)
productId = "product_id"
}
local json_params = json.encode(params)
rustorepay.purchase_two_step(json_params)
Структура параметров покупки
appUserEmail -- string (optional)
appUserId -- string (optional)
developerPayload -- string (optional)
orderId -- string (optional)
quantity -- number (optional)
productId -- string
productId— идентификатор продукта, который был присвоен продукту в RuStore Консоли (обязательный параметр).quantity— количество продукта. Необязательный параметр со стандартным значением1. Применим только к покупке потребляемых товаров.orderId— уникальный идентификатор оплаты, сформированный приложением (опциональный параметр). Если вы укажете этот параметр в вашей системе, вы получите его в ответе при работе с API. Если не укажете, он будет сгенерирован автоматически (uuid). Максимальная длина 150 символов.developerPayload— строка с дополнительной информацией о заказе, которую вы можете установить при подтверждении покупки. Эта строка переопределяет значение, заданное при инициализации. Максимальная длина 250 символов. Символы не экранируются.-
appUserId— внутренний ID пользователя в вашем приложении (опциональный параметр). Строка с максимальной длиной в 128 символов.подсказкаНапример, данный параметр может использоваться для выявления случаев мошенничества в вашем приложении, что позволит повысить его безопасность.
appUserEmail— это необязатель ный параметр, позволяющий задать адрес электронной почты пользователя в вашем приложении. Если адрес электронной почты покупателя был указан при регистрации в приложении, его можно передать для автоматического заполнения поляemailпри отправке чека — как для платежей вне RuStore, так и для случаев, когда пользователь не авторизован в RuStore. Это избавляет пользователя от необходимости вручную вводить email, сокращает путь до покупки и способствует повышению конверсии.
Структура результата покупки
ProductPurchaseResult— результат успешной оплаты цифрового товара (для одностадийной оплаты) или успешного холдирования средств (для двухстадийной оплаты).
invoiceId -- string
orderId -- string (optional)
productId -- string
purchaseId -- string
purchaseType -- string
-- ONE_STEP
-- TWO_STEP
-- UNDEFINED
quantity -- number
sandbox -- boolean
purchaseId— идентификатор покупки. Используется для получения информации о покупке в SDK методом получения информации о покупкеproductId— идентификатор приобретенного продукта, указанный при создании в консоли разработчика RuStore.invoiceId— идентификатор счета. Используется для серверной валидации платежа, поиска платежей в консоли разработчика, а также отображается покупателю в истории платежей в мобильном приложении RuStoreorderId— уникальный идентификатор оплаты, указанный разработчиком или сформированный автоматически (uuid).purchaseType— тип покупки (ONE_STEP/TWO_STEP/UNDEFINED— одностадийная/двухстадийная/стадийность не определена).quantity— количество купленного продукта.sandbox— флаг, указывающий признак тестового платежа в песочнице. ЕслиTRUE- покупка совершена в режиме тестирования.