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.

7.0.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.

Implementation example

Look at the example app to learn how to integrate our SDK.

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

Download the files below:

Import files to your project with Package Manager (Window > Package Manager > + > Add package from tarball...).

The dependencies are connected automatically with External Dependency Manager.

  1. Open package manager window (Window > Package Manager > + > Add package from git URL...).
  2. Use the https://github.com/googlesamples/unity-jar-resolver.git?path=/upm link to connect the External Dependency Manager package.
  3. To cure the Google.IOSResolver.dll will not be loaded error, install the iOS build module for your version of Unity (UnityHub > Installs > Your version of Unity > Add modules > iOS Build Support).
Google.IOSResolver.dll error
Assembly 'Packages/com.google.external-dependency-manager/ExternalDependencyManager/Editor/1.2.182/Google.IOSResolver.dll' will not be loaded due to errors:
Unable to resolve reference 'UnityEditor.iOS.Extensions.Xcode'. Is the assembly missing or incompatible with the current platform?
Reference validation can be disabled in the Plugin Inspector.
tip

If you use macOS, change Archive Utility settings. Uncheck Keep expanding if possible. Otherwise, the project archive will not be downloaded correctly.

For proper SDK dependencies processing set the following settings.

  1. Opt project settings: Edit > Project Settings > Player > Android Settings.

  2. In the Publishing Settings section enable to following settings.

    • Custom Main Manifest.
    • Custom Main Gradle Template.
    • Custom Gradle Properties Template.
  3. In the Other Settings section configure:

    • package name.
    • Minimum API Level = 24.
    • Target API Level = 34.
  4. Open the External Dependency Manager settings: Assets > External Dependency Manager > Android Resolver > Settings and enable the following settings.

    • Use Jetifier.
    • Patch mainTemplate.gradle.
    • Patch gradleTemplate.properties.
  5. Update project dependencies: Assets > External Dependency Manager > Android Resolver > Force Resolve.

Initialization

Initialize the library before calling its methods. The initialization itself is done automatically, however, for your SDK to work, in your Manifest.xml file define console_app_id_key and internal_config_key.

<!-- Initializing sdk -->
<meta-data android:name="console_app_id_key" android:value="@string/rustore_PayClientSettings_consoleApplicationId" />
<meta-data android:name="internal_config_key" android:value="@string/rustore_PayClientSettings_internalConfigKey" />

Both values must be inside the <application> tag

<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unity3d.player"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>

<!-- Initializing sdk -->
<meta-data android:name="console_app_id_key" android:value="@string/rustore_PayClientSettings_consoleApplicationId" />
<meta-data android:name="internal_config_key" android:value="@string/rustore_PayClientSettings_internalConfigKey" />

</application>
</manifest>

console_app_id_key — product ID form the RuStore Console.

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

Important

Package Name of the app specified in Edit > Project Settings... > Player > Android > Other Settings > Package Name must match Package Name of the APK file you published in the RuStore Console.

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

The console_app_id_key value is set in the PayClientSettings.assets file. To create the PayClientSettings.assets file, in the Unity editor select Window > RuStore SDK > Settings > PayClient.

The internal_config_key value is set in the PayClientSettings.assets automatically.

Attention!

Do not specify console_app_id_key and internal_config_key in the manifest directly. The strings must be placed in a resource file that is generated automatically based on PayClientSettings.assets data.

Working with SDK

Payments availability check

To check purchase availability, call the GetPurchaseAvailability method. On calling, the following conditions are checked.

  • The current version of RuStore is installed on the user's device.
  • RuStore app supports payments.
  • User is authorized in RuStore.
  • The user and the app are not banned in RuStore.
  • In-app purchases for the app are enabled in RuStore Console.
If all above conditions are met, PurchaseAvailabilityResult.Available is returned.

Otherwise, PurchaseAvailabilityResult.Unavailable(val cause: Throwable) is returned, where cause is an error of a failed condition. To check what caused such result, check error type for RuStoreException (error data is described in Errors).

Calling GetPurchaseAvailability
RuStorePayClient.Instance.GetPurchaseAvailability(
onFailure: (error) => {
// Process error
},
onSuccess: (result) => {
if (result.isAvailable) {
// Process success
}
else {
// Process result.cause
}
});

Check whether RuStore is installed

To check whether the RuStore app is installe don the user's device, call the IsRuStoreInstalled method.

bool isRuStoreInstalled = RuStorePayClient.Instance.IsRuStoreInstalled();
  • true – RuStore is installed.

  • false – RuStore is not installed.

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
ProductId[] ids = ...

RuStorePayClient.Instance.GetProducts(
productIds: ids,
onFailure: (error) => {
// Process error
},
onSuccess: (result) => {
// Process success
});

ProductId[] productIds — 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 : BaseFields {

public AmountLabel amountLabel { get; }
public Currency currency { get; }
public Description? description { get; }
public Url imageUrl { get; }
public Price? price { get; }
public ProductId productId { get; }
public Title title { get; }
public ProductType type { get; }

...
}
  • 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.

Getting products list

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

RuStorePayClient.Instance.GetPurchases(
onFailure: (error) => {
// Process error
},
onSuccess: (result) => {
// Process success
});

This method returns the products list in the CONFIRMED and PAID statuses. Below is the purchase pattern:

Purchase information structure
public class Purchase : BaseFields {

public AmountLabel amountLabel { get; }
public Currency currency { get; }
public Description description { get; }
public DeveloperPayload? developerPayload { get; }
public InvoiceId invoiceId { get; }
public OrderId? orderId { get; }
public Price price { get; }
public ProductId productId { get; }
public ProductType productType { get; }
public PurchaseId purchaseId { get; }
public DateTime? purchaseTime { get; }
public PurchaseType purchaseType { get; }
public Quantity quantity { get; }
public PurchaseStatus status { get; }
public SubscriptionToken? subscriptionToken { get; }

...
}
  • amountLabel — formatted purchase price, including currency symbol.
  • currency — ISO 4217 currency code.
  • description — descriptions in language.
  • developerPayload — string with additional order information, that you can specify on purchase initialization
  • 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.
  • price — price in minimum currency units.
  • productId — product ID assigned to product in RuStore Console (mandatory).
  • productType — product type.
  • purchaseId — product ID.
  • purchaseTime — purchase time.
  • PurchaseType — purchase type:
    • ONE_PHASE - one-stage payment;
    • TWO_PHASE - two-stage payment.
  • quantity — product amount (optional, value 1 will be used if not specified).
  • status — purchase state:
    • INVOICE_CREATED — purchase invoice is created and awaiting payment;
    • CANCELLED — purchase canceled by the user;
    • PROCESSING — payment initiated;
    • REJECTED — purchase rejected (for example: due to insufficient funds);
    • 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;
    • REFUNDED — purchase successfully refunded;
    • REVERSED — only for two-stage payment: wither the purchase was canceled by the developer or there was no payment within 72 hours, the funds on the user's account are put off hold.

Getting purchase information

Go get purchase information, use the getPurchase method.
RuStorePayClient.Instance.GetPurchase(
purchaseId: purchase.purchaseId,
onFailure: (error) => {
// Process error
},
onSuccess: (response) => {
// Process success
});

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

Purchase information structure
public class Purchase : BaseFields {

public AmountLabel amountLabel { get; }
public Currency currency { get; }
public Description description { get; }
public DeveloperPayload? developerPayload { get; }
public InvoiceId invoiceId { get; }
public OrderId? orderId { get; }
public Price price { get; }
public ProductId productId { get; }
public ProductType productType { get; }
public PurchaseId purchaseId { get; }
public DateTime? purchaseTime { get; }
public PurchaseType purchaseType { get; }
public Quantity quantity { get; }
public PurchaseStatus status { get; }
public SubscriptionToken? subscriptionToken { get; }

...
}
  • amountLabel — formatted purchase price, including currency symbol.
  • currency — ISO 4217 currency code.
  • description — descriptions in language.
  • developerPayload — string with additional order information, that you can specify on purchase initialization
  • 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.
  • price — price in minimum currency units.
  • productId — product ID assigned to product in RuStore Console (mandatory).
  • productType — product type.
  • purchaseId — product ID.
  • purchaseTime — purchase time.
  • PurchaseType — purchase type:
    • ONE_PHASE - one-stage payment;
    • TWO_PHASE - two-stage payment.
  • quantity — product amount (optional, value 1 will be used if not specified).
  • status — purchase state:
    • INVOICE_CREATED — purchase invoice is created and awaiting payment;
    • CANCELLED — purchase canceled by the user;
    • PROCESSING — payment initiated;
    • REJECTED — purchase rejected (for example: due to insufficient funds);
    • 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;
    • REFUNDED — purchase successfully refunded;
    • REVERSED — only for two-stage payment: wither the purchase was canceled by the developer or there was no payment within 72 hours, the funds on the user's account are put off hold.

Purchase status model

One-stage payment status model.

Two-stage payment status model.

Purchasing product

One-stage payment (without hold)

To purchase product, use the PurchaseOneStep method.

var parameters = new ProductPurchaseParams(
productId: new ProductId("product_id"),
developerPayload: null,
orderId: null,
quantity: new Quantity(1));

RuStorePayClient.Instance.PurchaseOneStep(
parameters: parameters,
onFailure: (error) => {
// Process error
},
onSuccess: (result) => {
// Process success
});

Two-stage payment (with hold)

To purchase product, use the PurchaseTwoStep method.

var parameters = new ProductPurchaseParams(
productId: new ProductId("product_id"),
developerPayload: null,
orderId: null,
quantity: new Quantity(1));

RuStorePayClient.Instance.PurchaseTwoStep(
parameters: parameters,
onFailure: (error) => {
// Process error
},
onSuccess: (result) => {
// Process success
});

Purchase parameters structure.

Purchase parameters structure
public class ProductPurchaseParams : BaseFields {

public ProductId productId { get; }
public DeveloperPayload? developerPayload { get; }
public OrderId? orderId { get; }
public Quantity? quantity { get; }

...
}
  • productId — product ID assigned to product in RuStore Console (mandatory).
  • developerPayload — string with additional order information, that you can specify on purchase initialization (optional).
  • 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 (optional).
  • quantity — product amount (optional, value 1 will be used if not specified) (optional).

Purchase result structure.

public interface IProductPurchaseResult {
}

public sealed class SuccessProductPurchaseResult : BaseFields, IProductPurchaseResult {

public InvoiceId invoiceId { get; }
public OrderId? orderId { get; }
public ProductId productId { get; }
public PurchaseId purchaseId { get; }
public SubscriptionToken? subscriptionToken { get; }

...
}

public sealed class CancelProductPurchaseResult : BaseFields, IProductPurchaseResult {

public PurchaseId? purchaseId { get; }

...
}

public sealed class FailureProductPurchaseResult : BaseFields, IProductPurchaseResult {

public RuStoreError cause { get; }
public InvoiceId? invoiceId { get; }
public OrderId? orderId { get; }
public ProductId? productId { get; }
public PurchaseId? purchaseId { get; }
public Quantity? quantity { get; }
public SubscriptionToken? subscriptionToken { get; }

...
}
  • SuccessProductPurchaseResult - successful purchase result.
  • FailureProductPurchaseResult - there was a problem during sending payment request or receiving payment status, purchase status unknown.
  • CancelProductPurchaseResult — payment request sent, although, the user closed the payment screen on their app, thus, the payment result is unknown.

Server validation

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

Retrieving subscriptionToken from purchase result
var parameters = new ProductPurchaseParams(
productId: new ProductId("product_id"));

RuStorePayClient.Instance.PurchaseTwoStep(
parameters: parameters,
onFailure: (error) => {
// Process error
},
onSuccess: (result) => {
if (result is SuccessProductPurchaseResult success) {
var subscriptionToken = success.subscriptionToken;
yourApi.validate(subscriptionToken);
}
});

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

RuStorePayClient.Instance.GetPurchases(
onFailure: (error) => {
// Process error
},
onSuccess: (result) => {
result.ForEach(item => {
yourApi.validate(item.subscriptionToken);
});
});

Consume (confirm) purchase

Purchases that require confirmation

A purchase can be either a one-stage or a two-stage payment.

  • If it's a one-stage payment, purchase confirmation is not required.
  • If it's a two-stage payment, to complete the purchase the developer has to confirm the purchase.

Confirmation method

To confirm a purchase, use the ConfirmTwoStepPurchase method. Purchase confirmation request must be accompanied by the delivery of the product. After calling the confirmation method the purchase changes its state to CONSUMED.

Calling confirmation method
PurchaseId id = ...
DeveloperPayload payload = ...

RuStorePayClient.Instance.ConfirmTwoStepPurchase(
purchaseId: purchaseId,
developerPayload: payload,
onFailure: (error) => {
// Process error
},
onSuccess: () => {
// Process success
});
  • purchaseId — product ID.
  • developerPayload — string with additional order information, that you can specify on purchase initialization (optional). 250 characters max. If passed, changes value set on purchase start by the purchase method.

Purchase cancellation

To cancel a purchase, use the CancelTwoStepPurchase method.

Calling CancelTwoStepPurchase
PurchaseId id = ...

RuStoreBillingClient.Instance.CancelTwoStepPurchase(
purchaseId: id" ,
onFailure: (error) => {
// Process error
},
onSuccess: () => {
// Process success
}
);
  • purchaseId — product ID.

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.