9.0.1
Project Integration
Adding the Repository
Adding repository
Add our repository as shown in the example below.
repositories {
maven {
url = uri("https://artifactory-external.vkpartner.ru/artifactory/maven")
}
}
Adding the Dependency
Connecting the dependency
Add the following code to your configuration file to add the dependency.
dependencies {
implementation(platform("ru.rustore.sdk:bom:2025.05.02"))
implementation("ru.rustore.sdk:pay")
}
Initialization
Initialize the library before calling its methods.
The initialization itself is done automatically, however, for your SDK to work, define console_app_id_key
in your manifest.xml
.
You can so it the following way:
<?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="your.app.package.name">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.App"
tools:targetApi="n">
...
<meta-data
android:name="console_app_id_value"
android:value="@string/CONSOLE_APPLICATION_ID" />
</application>
</manifest>
-
Пример:CONSOLE_APPLICATION_ID
— product ID form the RuStore Console.https://console.rustore.ru/apps/111111
.
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/versions
the app ID is123456
.
ApplicationId
, указанный вbuild.gradle
, должен совпадать сapplicationId
APK-файла, который вы публиковали в RuStore Консоль.-
The
keystore
signature must match the signature that was used to sign the app published in the RuStore Console. Make sure thatbuildType
used (example:debug
) uses the same signature as the published app (example:release
).
В целях безопасности, SDK устанавливает android:usesCleartextTraffic="false"
по умолчанию, чтобы предотвратить передачу данных по незащищённому HTTP и защитить от атак типа "Man-in-the-Middle". Если ваше приложение требует использования HTTP, вы можете изменить этот атрибут на true
, но делайте это на свой страх и риск, так как это увеличивает шанс перехвата и подмены данных. Мы рекомендуем разрешать незащищённый трафик только в исключительных случаях и для доверенных доменов, предпочитая HTTPS для всех сетевых взаимодействий.
Deeplink Handling
Deeplink handling in the RuStore SDK enables efficient interaction with third-party applications when processing payments through banking apps (SBP, SberPay, T-Pay, etc.). This allows you to redirect the user to the payment screen and, after the transaction is completed, return them to your application.
To set up deeplink support in your application and Pay SDK, specify the deeplinkScheme
using sdk_pay_scheme_value
in your AndroidManifest.xml
file and override the onNewIntent
method of your Activity
.
When using deeplinks, specifying the scheme is mandatory. If a payment is attempted without specifying the scheme, an error will occur.
Specifying deeplinkScheme:
<?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="your.app.package.name">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.App"
tools:targetApi="n">
<!-- ... -->
<activity
android:name=".YourPayActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="yourappscheme" />
</intent-filter>
</activity>
<meta-data
android:name="sdk_pay_scheme_value"
android:value="yourappscheme" />
</application>
</manifest>
Replace yourappscheme
with the name of your scheme. For example, ru.package.name.rustore.scheme
.
Next, add the following code to the Activity
you want to return to after the payment is completed (your application page):
class YourPayActivity: AppCompatActivity() {
private val intentInteractor: IntentInteractor by lazy {
RuStorePayClient.instance.getIntentInteractor()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
intentInteractor.proceedIntent(intent)
}
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
intentInteractor.proceedIntent(intent)
}
}
To restore the state of your application when returning via deeplink, add the android:launchMode="singleTop"
attribute to your AndroidManifest.xml
.
Specifying launchMode:
<?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="your.app.package.name">
<!-- ... -->
<application>
<!-- ... -->
<activity
android:name=".YourPayActivity"
android:launchMode="singleTop"
android:exported="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize">
<!-- ... -->
</activity>
<!-- ... -->
</application>
</manifest>
Working with the SDK
Available public interactors:
PurchaseInteractor
– an interactor that allows you to work with payments and provides several public methods:getPurchase(purchaseId: PurchaseId): Task<Purchase>
– allows you to get information about a purchase by its ID.getPurchases(productType: ProductType? = null, purchaseStatus: PurchaseStatus? = null): Task<List<Purchase>>
— allows you to retrieve user purchases. This method supports optional filtering by product type (consumable or non-consumable) as well as by purchase status (supported statuses arePAID
andCONFIRMED
). By default, filters are disabled and all user purchases (regardless of product type) with statusesPAID
andCONFIRMED
will be returned.getPurchaseAvailability(): Task<PurchaseAvailabilityResult>
– returns the result of checking payment availability.purchase(params: ProductPurchaseParams, preferredPurchaseType: PreferredPurchaseType = PreferredPurchaseType.ONE_STEP): Task<ProductPurchaseResult>
– allows you to make a product purchase with the desired payment type specified: single-stage (ONE_STEP
) or two-stage (TWO_STEP
). For this method, all payment options are available on the payment sheet. If the parameter is not specified, single-stage payment is used by default.
Important!If the payment type
TWO_STEP
is specified, an attempt will be made to initiate a two-stage payment, but the final result will directly depend on the payment method (card, SBP, etc.) selected by the user. Two-stage payment is available only for a specific set of payment methods (currently — only for cards). SBP technologies do not support two-stage payment. If a payment method that does not support holding is selected, the purchase will be processed using the single-stage scenario.purchaseTwoStep(params: ProductPurchaseParams): Task<ProductPurchaseResult>
– initiates a guaranteed two-stage purchase scenario. When using this method, the payment sheet presents the user only with payment methods that support two-stage payment. During the payment process, the buyer's funds are first held and are debited only after the purchase is confirmed using theconfirmTwoStepPurchase
method.confirmTwoStepPurchase(purchaseId: PurchaseId, developerPayload: DeveloperPayload? = null)
– confirms a purchase made using two-stage payment.cancelTwoStepPurchase(purchaseId: PurchaseId)
– cancels a purchase made using two-stage payment.
ProductInteractor
– an interactor that allows you to work with products:getProducts(productsId: List<ProductId>): Task<List<Product>>
– allows you to get information about active products published in the RuStore console.
ImportantThis method returns no more than 1000 products and works without authorization or the RuStore app being installed on the user's device.
UserInteractor
– an interactor that allows you to get the user's authorization statusUserAuthorizationStatus
. This model can have two states:AUTHORIZED
– the user is authorized in RuStore.UNAUTHORIZED
– the user is not authorized in RuStore.
IntentInteractor
– an interactor that allows you to handle intents:proceedIntent(intent: Intent?)
– a method for handling deeplinks used for payments in banking applications. Calling this method is necessary for the correct display of the payment sheet when returning to the app from the banking application.
RuStoreUtils
block – a set of public methods, such as:isRuStoreInstalled
– checks if the RuStore app is installed on the user's device.openRuStoreDownloadInstruction
– opens a web page for downloading the RuStore app.openRuStore
– launches the RuStore app.openRuStoreAuthorization
– launches the RuStore app for authorization. After successful user authorization, the RuStore app will automatically close.
Checking Payment Availability
To check payment availability, call the getPurchaseAvailability
method on PurchaseInteractor. When called, the following conditions are checked:
- The company has monetization enabled via the RuStore Developer Console.
- The application must not be banned in RuStore.
- The user must not be banned in RuStore.
If all conditions are met, PurchaseAvailabilityResult.Available
is returned. Otherwise, PurchaseAvailabilityResult.Unavailable(val cause: Throwable)
is returned, where cause
is the error indicating the unmet condition. To check the reason for this result, you should check the error type for RuStoreException
(these errors are described in the Error Handling section).
- Kotlin
- Java
RuStorePayClient.instance.getPurchaseInteractor().getPurchaseAvailability()
.addOnSuccessListener { result ->
when (result) {
is PurchaseAvailabilityResult.Available -> {
// Process purchases available
}
is PurchaseAvailabilityResult.Unavailable -> {
// Process purchases unavailable
}
}
}
.addOnFailureListener { throwable ->
// Process failure error
}
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.getPurchaseAvailability()
.addOnSuccessListener(result -> {
if (result instanceof PurchaseAvailabilityResult.Available) {
// Process purchases available
} else if (result instanceof PurchaseAvailabilityResult.Unavailable) {
RuStoreException exception = ((PurchaseAvailabilityResult.Unavailable) result).getCause();
// Process purchases unavailable
}
})
.addOnFailureListener(throwable -> {
// Process errors
});
Checking User Authorization Status
To check the user's authorization status, call the getUserAuthorizationStatus
method on UserInteractor
.
The result of this method is the UserAuthorizationStatus
class. There are 2 possible values:
AUTHORIZED
- the user is authorized in RuStoreUNAUTHORIZED
- the user is not authorized in RuStore. This value will also be returned if the user does not have RuStore installed on the device.
- Kotlin
- Java
RuStorePayClient.instance.getUserInteractor().getUserAuthorizationStatus()
.addOnSuccessListener { result ->
when (result) {
UserAuthorizationStatus.AUTHORIZED -> {
// Logic when the user is authorized in RuStore
}
UserAuthorizationStatus.UNAUTHORIZED -> {
// Logic when the user is NOT authorized in RuStore
}
}
}.addOnFailureListener { throwable ->
// Error handling
}
UserInteractor userInteractor = RuStorePayClient.Companion.getInstance().getUserInteractor();
userInteractor.getUserAuthorizationStatus()
.addOnSuccessListener(status -> {
switch (status) {
case AUTHORIZED:
// Logic when the user is authorized in RuStore
break;
case UNAUTHORIZED:
// Logic when the user is NOT authorized in RuStore
break;
}
})
.addOnFailureListener(throwable -> {
// Error handling
});
Retrieving Product List
- Kotlin
- Java
You checked that payments are available and the users are able to make purchases. Now you can request products list. Use the getProducts
method to request the information about products added to your app in RuStore Console.
RuStorePayClient.instance.getProductInteractor().getProducts(productsId = listOf(ProductId("id1"), ProductId("id2")))
.addOnSuccessListener { products: List<Product> ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}
productsId: List<ProductId>
— 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?
- Navigate to the Applications tab and selected the needed app.
- Select Monetization in the left menu.
- Select product type: Subscriptions or In-App purchases.
- Copy the IDs of the required products.
The method returns products list. Below is the product pattern.
public class Product internal constructor(
public val productId: ProductId,
public val type: ProductType,
public val amountLabel: AmountLabel,
public val price: Price?,
public val currency: Currency,
public val imageUrl: Url,
public val title: Title,
public val description: Description?,
)
amountLabel
— formatted purchase price, including currency symbol.currency
— ISO 4217 currency code.description
— descriptions inlanguage
.imageUrl
— image URL.price
— price in minimum currency units.productId
— product ID assigned to product in RuStore Console (mandatory).title
— product name inlanguage
.type
— product type.
Response examples
Product(
productId = ProductId("conProduct1"),
type = ProductType.CONSUMABLE_PRODUCT,
amountLabel = AmountLabel("100.00 rub."),
price = Price(10000),
currency = Currency("RUB"),
imageUrl = Url("https://your_image_consumable_product.png"),
title = Title("Title of a Consumable product"),
description = Description("Description of a Consumable product"),
)
Product(
productId = ProductId("nonConProduct1"),
type = ProductType.NON_CONSUMABLE_PRODUCT,
amountLabel = AmountLabel("200.00 rub."),
price = Price(20000),
currency = Currency("RUB"),
imageUrl = Url("https://your_image_non_consumable_product.png"),
title = Title("Title of a Non-consumable product"),
description = Description("Description of a Non-consumable product"),
)
You checked that payments are available and the users are able to make purchases. Now you can request products list. Use the getProducts
method to request the information about products added to your app in RuStore Console.
List<ProductId> productIds = Arrays.asList(new ProductId("id1"), new ProductId("id2"));
ProductInteractor productInteractor = RuStorePayClient.Companion.getInstance().getProductInteractor();
productInteractor.getProducts(productsId)
.addOnSuccessListener(products -> {
// Process success
})
.addOnFailureListener(throwable -> {
// Process error
});
productsId: List<ProductId>
— 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?
- Navigate to the Applications tab and selected the needed app.
- Select Monetization in the left menu.
- Select product type: Subscriptions or In-App purchases.
- Copy the IDs of the required products.
The method returns products list. Below is the product pattern:
public class Product {
private final ProductId productId;
private final ProductType type;
private final AmountLabel amountLabel;
private final Price price;
private final Currency currency;
private final Url imageUrl;
private final Title title;
private final Description description;
public Product(ProductId productId, ProductType type, AmountLabel amountLabel, @Nullable Price price, Currency currency, Url imageUrl, Title title, @Nullable Description description) {
this.productId = productId;
this.type = type;
this.amountLabel = amountLabel;
this.price = price;
this.currency = currency;
this.imageUrl = imageUrl;
this.title = title;
this.description = description;
}
public ProductId getProductId() {
return productId;
}
public ProductType getType() {
return type;
}
public AmountLabel getAmountLabel() {
return amountLabel;
}
public @Nullable Price getPrice() {
return price;
}
public Currency getCurrency() {
return currency;
}
public Url getImageUrl() {
return imageUrl;
}
public Title getTitle() {
return title;
}
public @Nullable Description getDescription() {
return description;
}
}
amountLabel
— formatted purchase price, including currency symbol.currency
— ISO 4217 currency code.description
— descriptions inlanguage
.imageUrl
— image URL.price
— price in minimum currency units.productId
— product ID assigned to product in RuStore Console (mandatory).title
— product name inlanguage
.type
— product type.
Response examples
Product(
productId = ProductId("conProduct1"),
type = ProductType.CONSUMABLE_PRODUCT,
amountLabel = AmountLabel("100.00 rub."),
price = Price(10000),
currency = Currency("RUB"),
imageUrl = Url("https://your_image_consumable_product.png"),
title = Title("Title of a Consumable product"),
description = Description("Description of a Consumable product"),
)
Product(
productId = ProductId("nonConProduct1"),
type = ProductType.NON_CONSUMABLE_PRODUCT,
amountLabel = AmountLabel("200.00 rub."),
price = Price(20000),
currency = Currency("RUB"),
imageUrl = Url("https://your_image_non_consumable_product.png"),
title = Title("Title of a Non-consumable product"),
description = Description("Description of a Non-consumable product"),
)
Retrieving Purchase List
- Kotlin
- Java
Go get the user's purchases list, use the getPurchases
method.
RuStorePayClient.instance.getPurchaseInteractor().getPurchases()
.addOnSuccessListener { purchases: List<Purchase> ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}
This method supports optional filtering by product type (consumable or non-consumable products), as well as by purchase status (only PAID
and CONFIRMED
statuses are supported).
By default, the filter is disabled and all user purchases (regardless of product type) with statuses PAID
and CONFIRMED
will be returned. The PAID
status means that the funds have been successfully held and the purchase is awaiting confirmation from the developer.
RuStorePayClient.instance.getPurchaseInteractor().getPurchases(
productType = ProductType.CONSUMABLE_PRODUCT,
purchaseStatus = PurchaseStatus.PAID,
)
.addOnSuccessListener { purchases: List<Purchase> ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}
The purchase model is shown below.
public class Purchase internal constructor(
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val orderId: OrderId?,
public val purchaseType: PurchaseType,
public val productType: ProductType,
public val description: Description,
public val purchaseTime: Date?,
public val price: Price,
public val amountLabel: AmountLabel,
public val currency: Currency,
public val quantity: Quantity,
public val status: PurchaseStatus,
public val developerPayload: DeveloperPayload?,
public val sandbox: Boolean,
)
purchaseId
— product ID. Used to obtain purchase information in the SDK via the purchase information retrieval method.productId
— product ID assigned to product in RuStore Console (mandatory).invoiceId
— invoice ID. Used for server-side payment validation, searching payments in the developer console, and is also displayed to the user in the payment history in the RuStore mobile app.orderId
- unique payment identifier specified by the developer or generated automatically (uuid
).PurchaseType
— purchase type:ONE_STEP
- one-stage payment;TWO_STEP
- two-stage payment;UNDEFINED
— number of payment stages is undefined.
productType
— product type. (CONSUMABLE
/NON-CONSUMABLE
- consumable/non-consumable.)description
- purchase description.purchaseTime
— purchase time.price
— price in minimum currency units.amountLabel
— formatted purchase price, including currency symbol.currency
— ISO 4217 currency code.quantity
— product quantity.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);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;CONFIRMED
— purchase successfully paid for;REFUNDING
— refunding initiated, request sent to the acquirer;REFUNDED
— purchase successfully refunded;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.
-
developerPayload
— string with additional order information, that you can specify on purchase initialization -
— test payment flag.
true
— test payment,false
— actual payment
Go get the user's purchases list, use the getPurchases
method.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.getPurchases(null)
.addOnSuccessListener(purchases -> {
// Process PaymentResult
})
.addOnFailureListener(error -> {
// Process error
});
This method supports optional filtering by product type (consumable or non-consumable products), as well as by purchase status (only PAID
and CONFIRMED
statuses are supported).
By default, the filter is disabled and all user purchases (regardless of product type) with statuses PAID
and CONFIRMED
will be returned. The PAID
status means that the funds have been successfully held and the purchase is awaiting confirmation from the developer.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.getPurchases(ProductType.CONSUMABLE_PRODUCT, PurchaseStatus.PAID)
.addOnSuccessListener(purchases -> {
// Process PaymentResult
})
.addOnFailureListener(error -> {
// Process error
});
The purchase model is shown below.
public class Purchase {
private final PurchaseId purchaseId;
private final ProductId productId;
private final InvoiceId invoiceId;
private final OrderId orderId;
private final PurchaseType purchaseType;
private final ProductType productType;
private final Description description;
private final Date purchaseTime;
private final Price price;
private final AmountLabel amountLabel;
private final Currency currency;
private final Quantity quantity;
private final PurchaseStatus status;
private final DeveloperPayload developerPayload;
private boolean sandbox;
public Purchase(PurchaseId purchaseId, ProductId productId, InvoiceId invoiceId, OrderId orderId, PurchaseType purchaseType, ProductType productType, Description description, Date purchaseTime, Price price, AmountLabel amountLabel, Currency currency, Quantity quantity, PurchaseStatus status, @Nullable DeveloperPayload developerPayload, boolean sandbox) {
this.purchaseId = purchaseId;
this.productId = productId;
this.invoiceId = invoiceId;
this.orderId = orderId;
this.purchaseType = purchaseType;
this.productType = productType;
this.description = description;
this.purchaseTime = purchaseTime;
this.price = price;
this.amountLabel = amountLabel;
this.currency = currency;
this.quantity = quantity;
this.status = status;
this.developerPayload = developerPayload;
this.sandbox = sandbox;
}
public PurchaseId getPurchaseId() {
return purchaseId;
}
public ProductId getProductId() {
return productId;
}
public InvoiceId getInvoiceId() {
return invoiceId;
}
public @Nullable OrderId getOrderId() {
return orderId;
}
public PurchaseType getPurchaseType() {
return purchaseType;
}
public ProductType getProductType() {
return productType;
}
public Description getDescription() {
return description;
}
public Date getPurchaseTime() {
return purchaseTime;
}
public Price getPrice() {
return price;
}
public AmountLabel getAmountLabel() {
return amountLabel;
}
public Currency getCurrency() {
return currency;
}
public Quantity getQuantity() {
return quantity;
}
public PurchaseStatus getStatus() {
return status;
}
public @Nullable DeveloperPayload getDeveloperPayload() {
return developerPayload;
}
public boolean isSandbox() {
return sandbox;
}
}
purchaseId
— product ID. Used to obtain purchase information in the SDK via the purchase information retrieval method.productId
— product ID assigned to product in RuStore Console (mandatory).invoiceId
— invoice ID. Used for server-side payment validation, searching payments in the developer console, and is also displayed to the user in the payment history in the RuStore mobile app.orderId
- unique payment identifier specified by the developer or generated automatically (uuid
).PurchaseType
— purchase type:ONE_STEP
- one-stage payment;TWO_STEP
- two-stage payment;UNDEFINED
— number of payment stages is undefined.
productType
— product type. (CONSUMABLE
/NON-CONSUMABLE
- consumable/non-consumable.)description
- purchase description.purchaseTime
— purchase time.price
— price in minimum currency units.amountLabel
— formatted purchase price, including currency symbol.currency
— ISO 4217 currency code.quantity
— product quantity.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);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;CONFIRMED
— purchase successfully paid for;REFUNDING
— refunding initiated, request sent to the acquirer;REFUNDED
— purchase successfully refunded;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.
-
developerPayload
— string with additional order information, that you can specify on purchase initialization -
— test payment flag.
true
— test payment,false
— actual payment
Retrieving Purchase Details
- Kotlin
- Java
getPurchase
method.
RuStorePayClient.instance.getPurchaseInteractor().getPurchase(PurchaseId("purchaseId"))
.addOnSuccessListener { purchase: Purchase ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}
The method returns information about a specific purchase in any status. The purchase model is shown below.
public class Purchase internal constructor(
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val orderId: OrderId?,
public val purchaseType: PurchaseType,
public val productType: ProductType,
public val description: Description,
public val purchaseTime: Date?,
public val price: Price,
public val amountLabel: AmountLabel,
public val currency: Currency,
public val quantity: Quantity,
public val status: PurchaseStatus,
public val developerPayload: DeveloperPayload?,
public val sandbox: Boolean,
)
purchaseId
— product ID. Used to obtain purchase information in the SDK via the purchase information retrieval method.productId
— product ID assigned to product in RuStore Console (mandatory).invoiceId
— invoice ID. Used for server-side payment validation, searching payments in the developer console, and is also displayed to the user in the payment history in the RuStore mobile app.orderId
- unique payment identifier specified by the developer or generated automatically (uuid
).PurchaseType
— purchase type:ONE_STEP
- one-stage payment;TWO_STEP
- two-stage payment;UNDEFINED
— number of payment stages is undefined.
productType
— product type. (CONSUMABLE
/NON-CONSUMABLE
- consumable/non-consumable.)description
- purchase description.purchaseTime
— purchase time.price
— price in minimum currency units.amountLabel
— formatted purchase price, including currency symbol.currency
— ISO 4217 currency code.quantity
— product quantity.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);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;CONFIRMED
— purchase successfully paid for;REFUNDING
— refunding initiated, request sent to the acquirer;REFUNDED
— purchase successfully refunded;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.
-
developerPayload
— string with additional order information, that you can specify on purchase initialization -
— test payment flag.
true
— test payment,false
— actual payment
Example response:
Purchase(
purchaseId = PurchaseId("purchaseId"),
productId = ProductId("productId"),
invoiceId = InvoiceId("invoiceId"),
orderId = OrderId("orderId"),
purchaseType = PurchaseType.ONE_STEP,
productType = ProductType.CONSUMABLE_PRODUCT,
description = Description("description"),
purchaseTime = Date(123123123124),
price = Price(14100),
amountLabel = AmountLabel("141,00 ₽"),
currency = Currency("RUB"),
quantity = Quantity(1),
status = PurchaseStatus.CONFIRMED,
developerPayload = DeveloperPayload("developerPayload"),
sandbox = false,
)
getPurchase
method.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.getPurchase(new PurchaseId("purchaseId"))
.addOnSuccessListener(purchase -> {
// Process success
})
.addOnFailureListener(throwable -> {
// Process error
});
The method returns information about a specific purchase in any status. The purchase model is shown below.
public class Purchase {
private final PurchaseId purchaseId;
private final ProductId productId;
private final InvoiceId invoiceId;
private final OrderId orderId;
private final PurchaseType purchaseType;
private final ProductType productType;
private final Description description;
private final Date purchaseTime;
private final Price price;
private final AmountLabel amountLabel;
private final Currency currency;
private final Quantity quantity;
private final PurchaseStatus status;
private final DeveloperPayload developerPayload;
private boolean sandbox;
public Purchase(PurchaseId purchaseId, ProductId productId, InvoiceId invoiceId, OrderId orderId, PurchaseType purchaseType, ProductType productType, Description description, Date purchaseTime, Price price, AmountLabel amountLabel, Currency currency, Quantity quantity, PurchaseStatus status, @Nullable DeveloperPayload developerPayload, boolean sandbox) {
this.purchaseId = purchaseId;
this.productId = productId;
this.invoiceId = invoiceId;
this.orderId = orderId;
this.purchaseType = purchaseType;
this.productType = productType;
this.description = description;
this.purchaseTime = purchaseTime;
this.price = price;
this.amountLabel = amountLabel;
this.currency = currency;
this.quantity = quantity;
this.status = status;
this.developerPayload = developerPayload;
this.sandbox = sandbox;
}
public PurchaseId getPurchaseId() {
return purchaseId;
}
public ProductId getProductId() {
return productId;
}
public InvoiceId getInvoiceId() {
return invoiceId;
}
public @Nullable OrderId getOrderId() {
return orderId;
}
public PurchaseType getPurchaseType() {
return purchaseType;
}
public ProductType getProductType() {
return productType;
}
public Description getDescription() {
return description;
}
public Date getPurchaseTime() {
return purchaseTime;
}
public Price getPrice() {
return price;
}
public AmountLabel getAmountLabel() {
return amountLabel;
}
public Currency getCurrency() {
return currency;
}
public Quantity getQuantity() {
return quantity;
}
public PurchaseStatus getStatus() {
return status;
}
public @Nullable DeveloperPayload getDeveloperPayload() {
return developerPayload;
}
public boolean isSandbox() {
return sandbox;
}
}
purchaseId
— product ID. Used to obtain purchase information in the SDK via the purchase information retrieval method.productId
— product ID assigned to product in RuStore Console (mandatory).invoiceId
— invoice ID. Used for server-side payment validation, searching payments in the developer console, and is also displayed to the user in the payment history in the RuStore mobile app.orderId
- unique payment identifier specified by the developer or generated automatically (uuid
).PurchaseType
— purchase type:ONE_STEP
- one-stage payment;TWO_STEP
- two-stage payment;UNDEFINED
— number of payment stages is undefined.
productType
— product type. (CONSUMABLE
/NON-CONSUMABLE
- consumable/non-consumable.)description
- purchase description.purchaseTime
— purchase time.price
— price in minimum currency units.amountLabel
— formatted purchase price, including currency symbol.currency
— ISO 4217 currency code.quantity
— product quantity.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);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;CONFIRMED
— purchase successfully paid for;REFUNDING
— refunding initiated, request sent to the acquirer;REFUNDED
— purchase successfully refunded;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.
-
developerPayload
— string with additional order information, that you can specify on purchase initialization -
— test payment flag.
true
— test payment,false
— actual payment
Example response:
Purchase(
purchaseId = PurchaseId("purchaseId"),
productId = ProductId("productId"),
invoiceId = InvoiceId("invoiceId"),
orderId = OrderId("orderId"),
purchaseType = PurchaseType.ONE_STEP,
productType = ProductType.CONSUMABLE_PRODUCT,
description = Description("description"),
purchaseTime = Date(123123123124),
price = Price(14100),
amountLabel = AmountLabel("141,00 ₽"),
currency = Currency("RUB"),
quantity = Quantity(1),
status = PurchaseStatus.CONFIRMED,
developerPayload = DeveloperPayload("developerPayload"),
sandbox = false,
)
Purchase Status Model
One-stage payment status model.
Two-stage payment status model.
Product Purchase
- When using a single-stage payment, the purchase does not require confirmation; the funds are immediately debited from the buyer’s account, and a commission is charged to the developer. In this case, if a refund to the customer is required (for example, if the product cannot be delivered for some reason), a refund can only be processed via the RuStore Console, and the funds will be returned to the buyer within a few days. The full purchase amount is refunded, but the commission previously withheld from the developer is not reimbursed.
- In the case of a two-stage payment, the funds are first held (authorized) on the buyer’s account. No commission is charged at this stage. After the hold, the purchase requires either confirmation or cancellation. The commission is charged to the developer upon purchase confirmation. Cancelling the purchase releases the hold, and the funds instantly become available to the buyer again.
Not all payment methods support two-stage payment.
- Kotlin
- Java
Payment with Purchase Type Selection
To initiate a product purchase with the option to select the payment stage, use the purchase
method.
val params = ProductPurchaseParams(
productId = ProductId("productId"),
orderId = null,
quantity = null,
developerPayload = null,
appUserId = null,
appUserEmail = null,
)
RuStorePayClient.instance.getPurchaseInteractor()
.purchase(params = params, preferredPurchaseType = PreferredPurchaseType.ONE_STEP)
.addOnSuccessListener { result ->
// Successful purchase result
}
.addOnFailureListener { throwable: Throwable ->
when(throwable){
is RuStorePaymentException.ProductPurchaseException -> // handle product purchase error
is RuStorePaymentException.ProductPurchaseCancelled -> // handle product purchase cancellation
else -> // handle other error
}
}
productId
— product ID assigned to product in RuStore Console (mandatory).quantity
— product amount (optional, value1
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
— string with additional order information, that you can specify on purchase 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.tipFor 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 theemail
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
).
This method is launched by default using the single-stage payment scenario (preferredPurchaseType = PreferredPurchaseType.ONE_STEP
), i.e., without funds being held.
For two-stage payment, you need to specify preferredPurchaseType = PreferredPurchaseType.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-stage payment (with funds holding)
To initiate a product purchase using the two-stage scenario, use the purchaseTwoStep
method.
When calling this method, the user will only have access to payment methods that support two-stage payment.
val params = ProductPurchaseParams(
productId = ProductId("productId"),
orderId = null,
quantity = null,
developerPayload = null,
appUserId = null,
appUserEmail = null,
)
RuStorePayClient.instance.getPurchaseInteractor()
.purchaseTwoStep(params)
.addOnSuccessListener { result ->
// Successful purchase result
}
.addOnFailureListener { throwable: Throwable ->
when(throwable){
is RuStorePaymentException.ProductPurchaseException -> // handle product purchase error
is RuStorePaymentException.ProductPurchaseCancelled -> // handle product purchase cancellation
else -> // handle other error
}
}
Purchase Parameters Structure
public class ProductPurchaseParams(
public val productId: ProductId,
public val quantity: Quantity? = null,
public val orderId: OrderId? = null,
public val developerPayload: DeveloperPayload? = null,
public val appUserId: AppUserId? = null,
public val appUserEmail: AppUserEmail? = null,
)
productId
— product ID assigned to product in RuStore Console (mandatory).quantity
— product amount (optional, value1
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
— string with additional order information, that you can specify on purchase 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.tipFor 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 theemail
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.
Payment with Purchase Type Selection
To initiate a product purchase with the option to select the payment stage, use the purchase
method.
ProductPurchaseParams params = new ProductPurchaseParams(new ProductId("productId"), null, null, null, null, null);
RuStorePayClient ruStorePayClient = RuStorePayClient.Companion.getInstance();
PurchaseInteractor purchaseInteractor = ruStorePayClient.getPurchaseInteractor();
purchaseInteractor.purchase(params, PreferredPurchaseType.ONE_STEP)
.addOnSuccessListener(result -> {
// Successful purchase result
})
.addOnFailureListener(throwable -> {
if (throwable instanceof ProductPurchaseException) {
// Handle product purchase error
} else if (throwable instanceof ProductPurchaseCancelled) {
// Handle product purchase cancellation
} else {
// Handle other error
}
});
productId
— product ID assigned to product in RuStore Console (mandatory).quantity
— product amount (optional, value1
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
— string with additional order information, that you can specify on purchase 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.tipFor 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 theemail
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
).
This method is launched by default using the single-stage payment scenario (preferredPurchaseType = PreferredPurchaseType.ONE_STEP
), i.e., without funds being held.
For two-stage payment, you need to specify preferredPurchaseType = PreferredPurchaseType.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-stage payment (with funds holding)
To initiate a product purchase using the two-stage scenario, use the purchaseTwoStep
method.
When calling this method, the user will only have access to payment methods that support two-stage payment.
ProductPurchaseParams params = new ProductPurchaseParams(new ProductId("productId"), null, null, null, null, null);
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.purchaseTwoStep(params)
.addOnSuccessListener(result -> {
// Successful purchase result
})
.addOnFailureListener(throwable -> {
if (throwable instanceof ProductPurchaseException) {
// Handle product purchase error
} else if (throwable instanceof ProductPurchaseCancelled) {
// Handle product purchase cancellation
} else {
// Handle other error
}
});
Purchase Parameters Structure
public class ProductPurchaseParams {
private final ProductId productId;
private final Quantity quantity;
private final OrderId orderId;
private final DeveloperPayload developerPayload;
private final AppUserId appUserId;
private final AppUserEmail appUserEmail;
public ProductPurchaseParams(ProductId productId, @Nullable Quantity quantity, @Nullable OrderId orderId, @Nullable DeveloperPayload developerPayload, @Nullable AppUserId appUserId, @Nullable AppUserEmail appUserEmail) {
this.productId = productId;
this.quantity = quantity;
this.orderId = orderId;
this.developerPayload = developerPayload;
this.appUserId = appUserId;
this.appUserEmail = appUserEmail;
}
public ProductId getProductId() {
return productId;
}
public @Nullable Quantity getQuantity() {
return quantity;
}
public @Nullable OrderId getOrderId() {
return orderId;
}
public @Nullable DeveloperPayload getDeveloperPayload() {
return developerPayload;
}
public @Nullable AppUserId getAppUserId() {
return appUserId;
}
public @Nullable AppUserEmail getAppUserEmail() {
return appUserEmail;
}
}
productId
— product ID assigned to product in RuStore Console (mandatory).quantity
— product amount (optional, value1
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
— string with additional order information, that you can specify on purchase 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.tipFor 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 theemail
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
ProductPurchaseResult
- the result of a successful digital product payment (for single-stage payment)
or successful funds holding (for two-stage payment).
- Kotlin
- Java
public class ProductPurchaseResult internal constructor(
public val orderId: OrderId?,
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val purchaseType: PurchaseType,
public val quantity: Quantity,
public val sandbox: Boolean,
)
public class ProductPurchaseResult {
private final OrderId orderId;
private final PurchaseId purchaseId;
private final ProductId productId;
private final InvoiceId invoiceId;
private final PurchaseType purchaseType;
private final Quantity quantity;
private final boolean sandbox;
public ProductPurchaseResult(OrderId orderId,
PurchaseId purchaseId,
ProductId productId,
InvoiceId invoiceId,
PurchaseType purchaseType,
Quantity quantity,
boolean sandbox) {
this.orderId = orderId;
this.purchaseId = purchaseId;
this.productId = productId;
this.invoiceId = invoiceId;
this.purchaseType = purchaseType;
this.quantity = quantity;
this.sandbox = sandbox;
}
public OrderId getOrderId() {
return orderId;
}
public PurchaseId getPurchaseId() {
return purchaseId;
}
public ProductId getProductId() {
return productId;
}
public InvoiceId getInvoiceId() {
return invoiceId;
}
public PurchaseType getPurchaseType() {
return purchaseType;
}
public Quantity getQuantity() {
return quantity;
}
public boolean isSandbox() {
return sandbox;
}
}
-
ProductPurchaseResult
— the result of a successful digital product payment (for single-stage payment) or successful funds holding (for two-stage payment).purchaseId
- purchase identifier. Used to obtain purchase information in the SDK via the purchase information retrieval method.productId
- identifier of the purchased product, specified when created in the RuStore developer console.invoiceId
- invoice identifier. Used for server-side payment validation, searching payments in the developer console, and is also displayed to the user in the payment history in the RuStore mobile app.orderId
- unique payment identifier specified by the developer or generated automatically (uuid).purchaseType
- purchase type (ONE_STEP
/TWO_STEP
- single-stage/two-stage).quantity
- product quantity (optional). If not specified, the value 1 will be used. Applicable only for consumable product purchases.sandbox
- flag indicating a test payment in the sandbox. IfTRUE
, the purchase was made in test mode.
Payment Error Handling
If an error occurs during payment or the user cancels the purchase, the execution of the payment method (both with purchase type selection and the two-stage method) will complete with an error:
ProductPurchaseException
- product purchase error.ProductPurchaseCancelled
- error caused by purchase cancellation (the user closed the payment sheet) before receiving the purchase result.
In this case, it is recommended to additionally check the purchase status using the purchase information retrieval method.
Error and cancellation structure:
- Kotlin
- Java
public class ProductPurchaseException internal constructor(
public val orderId: OrderId?,
public val purchaseId: PurchaseId?,
public val productId: ProductId?,
public val invoiceId: InvoiceId?,
public val quantity: Quantity?,
public val purchaseType: PurchaseType?,
public val sandbox: Boolean?,
public override val cause: Throwable,
) : RustorePaymentException(message = "Error purchase product", cause = cause)
public class ProductPurchaseCancelled internal constructor(
public val purchaseId: PurchaseId?,
public val purchaseType: PurchaseType?,
)
public class ProductPurchaseException extends RuStorePaymentException {
private final OrderId orderId;
private final PurchaseId purchaseId;
private final ProductId productId;
private final InvoiceId invoiceId;
private final Quantity quantity;
private final PurchaseType purchaseType;
private final Boolean sandbox;
public ProductPurchaseException(OrderId orderId,
PurchaseId purchaseId,
ProductId productId,
InvoiceId invoiceId,
Quantity quantity,
PurchaseType purchaseType,
Boolean sandbox,
Throwable cause) {
super("Error purchase product", cause);
this.orderId = orderId;
this.purchaseId = purchaseId;
this.productId = productId;
this.invoiceId = invoiceId;
this.quantity = quantity;
this.purchaseType = purchaseType;
this.sandbox = sandbox;
}
public OrderId getOrderId() {
return orderId;
}
public PurchaseId getPurchaseId() {
return purchaseId;
}
public ProductId getProductId() {
return productId;
}
public InvoiceId getInvoiceId() {
return invoiceId;
}
public Quantity getQuantity() {
return quantity;
}
public PurchaseType getPurchaseType() {
return purchaseType;
}
public Boolean getSandbox() {
return sandbox;
}
}
public class ProductPurchaseCancelled {
private final PurchaseId purchaseId;
private final PurchaseType purchaseType;
public ProductPurchaseCancelled(PurchaseId purchaseId, PurchaseType purchaseType) {
this.purchaseId = purchaseId;
this.purchaseType = purchaseType;
}
public PurchaseId getPurchaseId() {
return purchaseId;
}
public PurchaseType getPurchaseType() {
return purchaseType;
}
}
purchaseId
— purchase identifier. Used to obtain purchase information in the SDK via the purchase information retrieval method.productId
— identifier of the purchased product, specified when created in the RuStore developer console.invoiceId
— invoice identifier. Used for server-side payment validation, searching payments in the developer console, and is also displayed to the user in the payment history in the RuStore mobile app.orderId
— unique payment identifier specified by the developer or generated automatically (uuid).purchaseType
— purchase type (ONE_STEP
/TWO_STEP
— single-stage/two-stage).quantity
— product quantity (optional). If not specified, the value 1 will be used. Applicable only for consumable product purchases.
ProductPurchaseCancelled
— digital product purchase cancellation. The payment dialog was closed before receiving the purchase result, so the purchase state is unknown. It is recommended to request the purchase status separately using the purchase information retrieval method.
- Kotlin
- Java
public class ProductPurchaseCancelled internal constructor(
public val purchaseId: PurchaseId?,
public val purchaseType: PurchaseType?,
) : RuStorePaymentException(message = "Purchase product is cancelled")
public class ProductPurchaseCancelled extends RuStorePaymentException {
private final PurchaseId purchaseId;
private final PurchaseType purchaseType;
public ProductPurchaseCancelled(PurchaseId purchaseId, PurchaseType purchaseType) {
super("Purchase product is cancelled");
this.purchaseId = purchaseId;
this.purchaseType = purchaseType;
}
public PurchaseId getPurchaseId() {
return purchaseId;
}
public PurchaseType getPurchaseType() {
return purchaseType;
}
}
purchaseId
— purchase identifier. Used to obtain purchase information in the SDK via the purchase information retrieval method.purchaseType
— purchase type (ONE_STEP/TWO_STEP — single-stage/two-stage).
Server-Side Purchase Validation
- Kotlin
- Java
If you need to validate a successful purchase on the RuStore server, you can use the invoiceId
from the ProductPurchaseResult
model returned after a successful product purchase.
val params = ProductPurchaseParams(ProductId("productId"))
RuStorePayClient.instance.getPurchaseInteractor()
.purchase(params = params, preferredPurchaseType = PreferredPurchaseType.TWO_STEP)
.addOnSuccessListener { result ->
val invoiceId = result.invoiceId.value
yourApi.validate(invoiceId)
}
You can also get the invoiceId
from the Purchase
model. The Purchase
model can be obtained using the getPurchases()
method or the getPurchase
method.
RuStorePayClient.instance.getPurchaseInteractor().getPurchases()
.addOnSuccessListener { purchases ->
purchases.forEach { purchase ->
yourApi.validate(purchase.invoiceId.value)
}
}
If you need to validate a successful purchase on the RuStore server, you can use the invoiceId
from the ProductPurchaseResult
model returned upon a successful product purchase.
ProductInteractor productInteractor = RuStorePayClient.Companion.getInstance().getProductInteractor();
ProductPurchaseParams params = new ProductPurchaseParams(new ProductId("productId"), null, null, null);
productInteractor.purchase(params, PreferredPurchaseType.TWO_STEP)
.addOnSuccessListener(result -> {
String invoiceId = successResult.getInvoiceId().getValue();
yourApi.validate(invoiceId);
});
You can also get the invoiceId
from the Purchase
model. The Purchase
model can be obtained using the getPurchases()
method or the getPurchase
method.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.getPurchases()
.addOnSuccessListener(purchases -> {
for (Purchase purchase : purchases) {
yourApi.validate(purchase.getInvoiceId().getValue());
}
})
.addOnFailureListener(error -> {
// Process error
});
Purchase Confirmation
- Kotlin
- Java
Only purchases initiated using the two-stage payment scenario (i.e., with funds being held) require confirmation. Such purchases, after successful holding, will have the status PurchaseStatus.PAID
.
To debit funds from the buyer's card, the purchase must be confirmed. For this, you should use the confirmTwoStepPurchase
method.
RuStorePayClient.instance.getPurchaseInteractor().confirmTwoStepPurchase(
purchaseId = PurchaseId("purchaseId"),
developerPayload = null,
)
.addOnSuccessListener {
// Process success
}.addOnFailureListener { throwable: Throwable ->
// Process error
}
purchaseId
— product ID.developerPayload
— string with additional order information, that you can specify on purchase initialization. Maximum 250 characters. If provided, it replaces the value set at the start of the purchase via thepurchase
/purchaseTwoStep
method.
Only purchases initiated using the two-stage payment scenario (i.e., with funds being held) require confirmation. Such purchases, after successful holding, will have the status PurchaseStatus.PAID
.
To debit funds from the buyer's card, the purchase must be confirmed. For this, you should use the confirmTwoStepPurchase
method.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.confirmTwoStepPurchase(
new PurchaseId("purchaseId"),
null
).addOnSuccessListener(success -> {
// Process success
}).addOnFailureListener(throwable -> {
// Process error
});
purchaseId
— product ID.developerPayload
— string with additional order information, that you can specify on purchase initialization. Maximum 250 characters. If provided, it replaces the value set at the start of the purchase via thepurchase
/purchaseTwoStep
method.
Purchase Cancellation
With our SDK you can cancel only the purchases that undergo a two-stage payment process, i.e. when the user's money is put on hold. After a successful hold, such purchases are in the PurchaseStatus.PAID
status. If a purchase is canceled it has the PurchaseStatus.REVERSED
status.
Cancel purchases if you cannot deliver your product after payment is made (when the user's money is put on hold).
To cancel a purchase (put the user's money off hold), use the cancelTwoStepPurchase
method.
- Kotlin
- Java
RuStorePayClient.instance.getPurchaseInteractor().cancelTwoStepPurchase(
purchaseId = PurchaseId("purchaseId"),
)
.addOnSuccessListener {
// Process success
}.addOnFailureListener { throwable: Throwable ->
// Process error
}
purchaseId
— product ID.
PurchaseInteractor purchaseInteractor = RuStorePayClient.Companion.getInstance().getPurchaseInteractor();
purchaseInteractor.cancelTwoStepPurchase(
new PurchaseId("purchaseId")
).addOnSuccessListener(success -> {
// Process success
}).addOnFailureListener(throwable -> {
// Process error
});
purchaseId
— product ID.
Error List
RuStorePaymentNetworkException - SDK network interaction error.
The error model returns an error code (the code
field), which can be used to determine the cause of the error.
The table with error codes is available in the error codes section.
The message
field contains a description of the error cause.
- Kotlin
- Java
public class RuStorePaymentNetworkException internal constructor(
public val code: String?,
public val id: String,
public override val message: String,
public override val cause: Throwable? = null,
) : RuStorePaymentException(message, cause)
public class RuStorePaymentNetworkException extends RuStorePaymentException {
private final String code;
private final String id;
public RuStorePaymentNetworkException(
String code,
String id,
String message,
Throwable cause
) {
super(message, cause);
this.code = code;
this.id = id;
}
public String getCode() {
return code;
}
public String getId() {
return id;
}
}
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
— the required parameterconsole_application_id
for SDK initialization is not specified;RuStorePaySignatureException
— invalid response signature. Occurs when attempting fraudulent actions;EmptyPaymentTokenException
— error obtaining payment token;InvalidCardBindingIdException
— error when 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.
Error Codes
Error Code | Description |
---|---|
4000001 | The request is malformed: a required parameter is missing or incorrectly filled, or the data format is invalid. |
4000002 , 4000016 , 4040005 | Application not found. |
4000003 | Application is banned. |
4000004 | Application signature does not match the registered one. |
4000005 | Company not found. |
4000006 | Company is banned. |
4000007 | Company monetization is disabled or inactive. |
4000014 | Product not found. |
4000015 | Product not published. |
4000017 | Invalid quantity parameter. |
4000018 | Purchase limit exceeded. |
4000020 | Product already purchased. |
4000021 | Unfinished product purchase. |
4000022 | Purchase not found. |
4000025 | No suitable payment method found. |
4000026 | Invalid purchase type for confirmation (should be two-stage payment). |
4000027 | Invalid purchase status for confirmation. |
4000028 | Invalid purchase type for cancellation (should be two-stage payment). |
4000029 | Invalid purchase status for cancellation. |
4000030 | The issued token does not match the purchased product. |
4010001 | Access to the requested resource is forbidden (unauthorized). |
4010002 | Token lifetime has expired. |
4010003 | Payment token is invalid. |
4030001 | Payment token not provided. |
4030002 | User is blocked due to security requirements. |
4040002 , 4040003 , 4040004 | Payment system error. |
5000*** | Internal error. |
List of Dependencies
androidx.core:core-ktx:1.12.0
— The Apache Software License, Version 2.0;androidx.activity:activity-ktx:1.7.0
— The Apache Software License, Version 2.0;androidx.fragment:fragment-ktx:1.4.0
— The Apache Software License, Version 2.0;androidx.lifecycle:lifecycle-runtime-ktx:2.7.0
— The Apache Software License, Version 2.0;androidx.lifecycle:lifecycle-common-java8:2.7.0
— The Apache Software License, Version 2.0;androidx.recyclerview:recyclerview:1.2.1
— The Apache Software License, Version 2.0;com.google.android.material:material:1.5.0
— The Apache Software License, Version 2.0;io.coil-kt:coil:2.6.0
— The Apache Software License, Version 2.0.com.dpforge:primaree:1.2.0
- MIT License.