Skip to main content
Unlisted page
This page is unlisted. Search engines will not index it, and only users having a direct link can access it.

6.1.0 (Beta)

With RuStore you can integrate payments in your mobile app.

tip
  • If you are in doubt read the instruction in the usage scenarios.

  • If you migrate to Pay SDK from billingClient SDK, please review the migration instructions. For more details, see here.

Prerequisites

  • In-app purchases for the app are enabled in RuStore Console.
  • The app must not be banned in RuStore.
  • The current version of RuStore is installed on the user's device.
  • User is authorized in RuStore.
  • The user must is not banned in RuStore.

Connect to project

Adding repository

Add our repository as shown in the example below.

build.gradle
repositories {
maven {
url = uri("https://artifactory-external.vkpartner.ru/artifactory/maven")
}
}

Connecting the dependency

Add the following code to your configuration file to add the dependency.

build.gradle
dependencies {
implementation(platform("ru.rustore.sdk:bom:6.1.0"))
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:

manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="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_key"
android:value="@string/CONSOLE_APPLICATION_ID" />

</application>
</manifest>
Where are app IDs in the RuStore Console?
  1. Navigate to the Applications tab and selected the needed app.
  2. Copy the ID from the URL address of the app page — it is a set of numbers between apps/ and /versions. FOr example, for URL address https://console.rustore.ru/apps/123456/versions the app ID is 123456.

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

Working with SDK

Available public interactiors:

  • PurchaseInteractor — interactor that allows working with payments and has several public methods:
    • getPurchase(purchaseId: PurchaseId): Task<Purchase> — retrieves payment information by its ID.
    • getPurchases(): Task<List<Purchase>> — retrieves the user's purchases. The returned list contains purchases in the CONFIRMED status for non-consumable products and PAID status for consumable products. PAID — this status means that the money is put on hold. The purchase requires the developer's confirmation.
    • getPurchaseAvailability(): Task<PurchaseAvailabilityResult> — returns payments availability result.
    • consumePurchase(purchaseId: PurchaseId, developerPayload: DeveloperPayload? = null) — purchase confirmation (consumption). Only for consumable products.
  • ProductInteractor — interactor that allows working with products and has several public methods:
    • getProducts(productsId: List<ProductId>): Task<List<Product>> — retrieves product information by ID. You can specify up to 1000 items in the products list.
    • purchase(params: ProductPurchaseParams): Task<ProductPurchaseResult> — allows to purchase product.
  • The RuStoreUtils block — set of public methods, such as:
    • isRuStoreInstalled — checks if the RuStore app is installed on the user's device.
    • openRuStoreDownloadInstruction — opens RuStore app download page.
    • openRuStore — launches RuStore app.
    • openRuStoreAuthorization — launches RuStore app for authorization. Automatically closes after user authorization in RuStore.

Payments availability check

To check purchase availability, call the getPurchaseAvailability methods from PurchaseInteractor. On calling, the following conditions are checked:

  • The current version of RuStore is installed on the user's device.
  • User is authorized in RuStore.
  • The user and the app are not banned in RuStore.
  • Monetization is enabled in the RuStore Console.

If all conditions are met, PurchaseAvailabilityResult.Available is returned. Otherwise, PurchaseAvailabilityResult.Unavailable(val cause: Throwable) is returned, where cause is an error of unmet conditions.

To figure out the cause of the error, check its type for RuStoreException. See Error handling.

For example, if you received RuStoreUserUnauthorizedException, this means that the user is not authorized in RuStore. IN this case you can call the openRuStoreAuthorization method that launches the RuStore app for authorization. See other methods in section SDK.

Calling the getPurchaseAvailability method
RuStorePayClient.getPurchaseInteractor().getPurchaseAvailability()
.addOnSuccessListener { result ->
when (result) {
is PurchaseAvailabilityResult.Available -> {
// Process purchases available
}

is PurchaseAvailabilityResult.Unavailable -> {
// Process purchases unavailable
}
}
}.addOnFailureListener { throwable ->
// Process unknown error
}

Working with products

Retrieving products list

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.

Вызов метода getProducts
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?
  1. Navigate to the Applications tab and selected the needed app.
  2. Select Monetization in the left menu.
  3. Select product type: Subscriptions or In-App purchases.
  4. Copy the IDs of the required products.

The method returns products list. Below is the product pattern.

Product structure
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 in language.
  • imageUrl — image URL.
  • price — price in minimum currency units.
  • productId — product ID assigned to product in RuStore Console (mandatory).
  • title — product name in language.
  • type — product type.

Response examples

Consumable product model example
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"),
)
Non-consumable product model example
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"),
)

Working with purchases

Getting products list

Go get the user's purchases list, use the getPurchases method.

RuStorePayClient.getPurchaseInteractor().getPurchases()
.addOnSuccessListener { purchases: List<Purchase> ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}

This method returns the products list in the CONFIRMED status for non-consumable products and PAID for consumable products. Below is the product pattern:

Purchase information structure
public class Purchase internal constructor(
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val orderId: OrderId?,
public val type: PurchaseType,
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 subscriptionToken: SubscriptionToken?,
public val developerPayload: DeveloperPayload?,
)
  • purchaseId — product ID.
  • productId — product ID assigned to product in RuStore Console (mandatory).
  • invoiceId — invoice ID.
  • orderId — payment ID generated by the app (optional). If you specify this parameter in your system, you will receive it via our API. If not specified, will be generated automatically (uuid). 150 characters max.
  • type — product type: CONSUMABLE/NON-CONSUMABE.
  • description — purchase description;
  • purchaseTime — purchase time.
  • price — price in minimum currency units.
  • amountLable — formatted purchase price, including currency symbol.
  • currency — ISO 4217 currency code.
  • quantity — product amount (optional, value 1 will be used if not specified).
  • purchaseState — purchase state.
  • developerPayload — string with additional order information, that you can specify on purchase initialization.

Getting purchase information

Go get purchase information, use the getPurchase method.
RuStorePayClient.getPurchaseInteractor().getPurchase(PurchaseId("purchaseId"))
.addOnSuccessListener { purchase: Purchase ->
// Process success
}
.addOnFailureListener { throwable: Throwable ->
// Process error
}

This method returns information about a specific purchase in any status. Below is the product pattern:

Purchase information structure
public class Purchase internal constructor(
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val orderId: OrderId?,
public val type: PurchaseType,
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 subscriptionToken: SubscriptionToken?,
public val developerPayload: DeveloperPayload?,
)
  • purchaseId — product ID.

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

  • invoiceId — invoice ID.

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

  • type — product type: CONSUMABLE/NON-CONSUMABE.

  • description — purchase description;

  • purchaseTime — purchase time.

  • price — price in minimum currency units.

  • amountLable — formatted purchase price, including currency symbol.

  • currency — ISO 4217 currency code.

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

  • purchaseState — purchase state.

    Intermediate statuses:

    • INVOICE_CREATED — purchase invoice is created and awaiting payment.
    • PROCESSING — payment initiated.
    • PAID — only for consumable products — intermediate status, the funds on the user's account are put on hold. The purchase is awaiting confirmation from the developer.

    Final statuses:

    • CONSUMED — payment for consumable product successful.
    • CONFIRMED — payment for non-consumable product successful.
    • CANCELLED— purchase canceledm no payment was made.
    • EXPIRED — payment time expired.
    • REJECTED — purchase rejected (for example: due to insufficient funds).
    • REVERSED — purchase was canceled as it was not confirmed within 72 hours (for consumable products).
    • REFUNDED — purchase successfully refunded.

    For more information on status changes, see purchase status model.

  • developerPayload — string with additional order information, that you can specify on purchase initialization.

  • subscriptionToken — purchase token for server validation .

Purchase status model (purchaseState)

CONSUMABLES - purchase state model

Purchase canceled

CANCELLED

Purchase is not paid for

EXPIRED


INVOICE_CREATED
Payment invoice created. Purchase is not paid for


PROCESSING
Payment process started


REJECTED
Purchase cannot be paid for using the selected method (for example: insufficient funds)


CONSUMED
For consumable products. Purchase confirmed and paid for. Money is withdrawn from the buyers account and transferred to the developer. Subsequent purchase available
Invoice payment
time expired
Purchase canceled
by the user
User
initiated payment
Payment operation
rejected
Purchase is paid for


REFUNDED
Refund request successfully completed. Subsequent purchase available
Purchase
refunded


PAID
For consumable products. Money on the buyer's account is put on hold. Purchase awaiting confirmation. Further purchase attempts are blocked by the store


REVERSED
Purchase was not confirmed within 72 hours
Purchase canceled

NON-CONSUMABLES - purchase state model

Purchase canceled

CANCELLED

Purchase is not paid for

EXPIRED


INVOICE_CREATED
Payment invoice created. Purchase is not paid for


PROCESSING
Payment process started


REJECTED
Purchase cannot be paid for using the selected method (for example: insufficient funds)


CONFIRMED
For non consumable products. Purchase is paid for. Subsequent purchases are not available
Invoice payment
timed out
Purchase canceled
by the user
User
initiated payment
Payment rejected
Purchase is paid for


REFUNDED
Refund request is successfully completed. Subsequent purchase available
Purchase
refunded

Purchasing product

To purchase product, use the purchase method.

RuStorePayClient.getProductInteractor().purchase(
ProductPurchaseParams(
productId = ProductId("productId"),
orderId = null,
quantity = null,
developerPayload = null,
)
).addOnSuccessListener { paymentResult: PaymentResult ->
when (paymentResult) {
// Process PaymentResult
}
}.addOnFailureListener { throwable: Throwable ->
// Process 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,
)
  • productId — product ID assigned to product in RuStore Console (mandatory).
  • quantity — product amount (optional, value 1 will be used if not specified).
  • orderId — payment ID generated by the app (optional). If you specify this parameter in your system, you will receive it via our API. If not specified, will be generated automatically (uuid). 150 characters max.
  • developerPayload — string with additional order information, that you can specify on purchase initialization. 250 characters max.
Purchase result structure
public sealed interface ProductPurchaseResult {

public class SuccessProductPurchaseResult(
public val orderId: OrderId?,
public val purchaseId: PurchaseId,
public val productId: ProductId,
public val invoiceId: InvoiceId,
public val subscriptionToken: SubscriptionToken?,
) : ProductPurchaseResult

public class CancelProductPurchaseResult(
public val purchaseId: PurchaseId?,
) : ProductPurchaseResult

public class FailureProductPurchaseResult(
public val orderId: OrderId?,
public val purchaseId: PurchaseId?,
public val productId: ProductId?,
public val invoiceId: InvoiceId?,
public val quantity: Quantity?,
public val subscriptionToken: SubscriptionToken?,
public val cause: Throwable,
) : ProductPurchaseResult
}
  • SuccessProductPurchaseResult — successful purchase result.
  • FailureProductPurchaseResult — failed purchase result.
  • CancelProductPurchaseResult — payment dialog was closed prior to receiving purchase result. Purchase state unknown. We recommend request purchase status using the method for getting purchase information.

Server purchase validation

If you need to validate a purchase on the RuStore server, you can use subscriptionToken from the ProductPurchaseResult.SuccessProductPurchaseResult model, that is returned on successful purchase. You can also validate payments using InvoiceId.

Retrieving subscriptionToken from purchase result
RuStorePayClient.getProductInteractor().purchase(ProductId("productId"))
.addOnSuccessListener { result ->
if (result is ProductPurchaseResult.SuccessProductPurchaseResult) {
val subscriptionToken = result.subscriptionToken
yourApi.validate(subscriptionToken)
}
}

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

Retrieving subscriptionToken from purchase result
RuStorePayClient.getPurchaseInteractor().getPurchases()
.addOnSuccessListener { purchases ->
purchases.forEach { purchase ->
yourApi.validate(purchase.subscriptionToken)
}
}

Consume (confirm) purchase

The RuStore application consists of the following types of products:

  • CONSUMABLE — consumables (multiple-time purchases, such as crystals in the app).
  • NON_CONSUMABLE — non-consumables (one-time purchases, such as disabling in-app ads).

Only CONSUMABLE products need confirmation when they are in the PurchaseState.PAID status.

To consume purchase, use the consumePurchase method:

Calling confirmation method
RuStorePayClient.getPurchaseInteractor().consumePurchase(
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. 250 characters max. If passed, changes value set on purchase start by the purchase method.

Handling pending payments

Handling of unfinished payments is done by the developer.

To confirm a purchase of CONSUMABLE product in the PAID state, call the [purchase confirmation method].(#consumepurchase) (see Retrieve purchase details).

Error handling

  • RuStorePaymentNetworkException — SDK network communication error;
  • RuStorePaymentCommonException — general SDK error;
  • RuStorePayClientAlreadyExist — duplicate initialization error SDK;
  • RuStorePayClientNotCreated — attempt to access public SDK interface before initialisation;
  • RuStorePayInvalidActivePurchase — payment initiated for unknown product type;
  • RuStorePayInvalidConsoleAppId — mandatory parameter сonsole_application_id for SDK initialisation not set;
  • RuStorePaySignatureException — invalid signature (occurs because of fraud actions);
  • EmptyPaymentTokenException — error receiving payment token;
  • RuStoreNotInstalledException — RuStore is not installed on the user's device;
  • RuStoreOutdatedException — RuStore version installed on the user's device does not support this SDK;
  • RuStoreUserUnauthorizedException — user is not authorized in RuStore;
  • RuStoreApplicationBannedException — app is banned in RuStore RuStore;
  • RuStoreUserBannedException — user is blocked in RuStore;
  • RuStoreException — basic RuStore error from which other errors are inherited.