7.0.0 (Beta)
With RuStore you can integrate payments in your mobile app.
-
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.
Getting started
To connect payments to your project, execute the following command.
flutter pub add flutter_rustore_billing
Initialization
Initialize the library before calling its methods. The initialization itself is done automatically, however, for your SDK to work, in your AndroidManifest.xml
file define consoleApplicationId
.
<meta-data
android:name="console_app_id_key"
android:value="@string/CONSOLE_APPLICATION_ID" />
Replace the string with your app_id
in strings.xml
.
<string name="CONSOLE_APPLICATION_ID">"your_app_id"</string>
CONSOLE_APPLICATION_ID
— product ID form the RuStore Console.
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
specified in build.gradle
must match applicationId
of the APK file you published in the RuStore Console.
debug
) of the app must match the signature of the app build that was uploaded to the console and passed moderation (for example, release
)Working with SDK
SDK offers 2 public interactors:
PurchaseInteractor
— interactor that allows working with payments and has several public methods:getPurchase(purchaseId: PurchaseId): Task<Purchase>
- allows receiving purchase information by its ID;getPurchases(): Task<List<Purchase>>
- allows retrieving the user's purchases. The returned list contains purchases in theCONFIRMED
returned status for non-consumable products and in thePAID
status (this status means that the money is put on hold on the buyers account and the purchase is awaiting the developer's confirmation);getPurchaseAvailability(): Task<PurchaseAvailabilityResult>
- retrieves payments availability status;consumePurchase(purchaseId: PurchaseId, developerPayload: DeveloperPayload? = null)
— allows product consumption (only for consumable products).
ProductInteractor
— interactor that allows working with products and has several public methods:-
getProducts(productsId: List<ProductId>): Task<List<Product>>
— allows receiving product infromation by ID.
(Important! The method has a limitation of 1000 products) -
purchase(params: ProductPurchaseParams): Task<ProductPurchaseResult>
— allows product purchase
-
Also RuStoreUtils
— a set of public methods is available:
isRuStoreInstalled
— check whether RuStore is installed on the user's device;openRuStore
— starts the RuStore mobile app;openRuStoreAuthorization
— starts the RuStore app for user authorization, after successful authorization the RuStore app will be closed automatically;openRuStoreDownloadInstruction
— opens RuStore download page.
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, PurchaseAvailabilityResponse.Available
is returned.Otherwise, PurchaseAvailabilityResponse.Unavailable(val cause: Throwable)
is returned, where cause
is an error of a failed condition.
RuStorePayClient.instance.purchaseInteractor.getPurchaseAvailability().then((value) {
if (value case Available _) {
// Process purchases available
} else if (value case Unavailable unavailable) {
// Process purchases unavailable
}
});
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.
RuStorePayClient.instance.productInteractor.getProducts(productIds).then((response) {
for (final product in response.products) {
print(product?.productId);
}
}, onError: (err) {
print("products err: $err");
}
);
productIds: 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.
class Product {
String productId;
ProductType type;
String amountLabel;
int? price;
String currency;
String imageUrl;
String title;
String? 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.
ProductType
structure.
enum ProductType {
consumable,
nonConsumable,
}
consumable
— consumable (can be bought more than once, for example: crystals in app);nonConsumable
— non-consumable (can be purchased only once, for example: disabling ads);
Purchasing product
One-stage payment (without hold)
RuStorePayClient.instance.productInteractor.purchaseOneStep(id).then((value) {
// Process success
});
Two-stage payment (with hold)
RuStorePayClient.instance.productInteractor.purchaseTwoStep(id).then((value) {
// Process success
});
Getting products list
Go get the user's purchases list, use the getPurchases
method.
RuStorePayClient.instance.purchaseInteractor.getPurchases().then((purchase) {
// Process success
});
class Purchase {
String purchaseId;
String productId;
String invoiceId;
String? orderId;
PurchaseType purchaseType;
ProductType productType;
String description;
String? purchaseTime;
int price;
String amountLabel;
String currency;
int quantity;
PurchaseStatus status;
String? subscriptionToken;
String? 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.purchaseType
— purchase type.productType
— product type:CONSUMABLE
/NON-CONSUMABE
/SUBSCRIPTION
.description
— descriptions inlanguage
.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, value1
will be used if not specified).purchaseState
— 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.
DeveloperPayload
— string with additional order information, that you can specify on purchase initialization.
PurchaseType
structure.
enum PurchaseType {
oneStep,
twoStep,
}
Getting purchase information
Go get purchase information, use thegetPurchase
method.
RuStorePayClient.instance.purchaseInteractor.getPurchase(purchaseId).then((purchase) {
// Process success
});
This method returns information about a specific purchase in any status. Below is the purchase pattern:
class Purchase {
String purchaseId;
String productId;
String invoiceId;
String? orderId;
PurchaseType purchaseType;
ProductType productType;
String description;
String? purchaseTime;
int price;
String amountLabel;
String currency;
int quantity;
PurchaseStatus status;
String? subscriptionToken;
String? developerPayload;
}
Purchase status model
One-stage payment status model.
Two-stage payment status model.
Consume (confirm) purchase
Confirmation is required only for two-stage payments (when the money is put on hold on the user's account). After a successful hold, such purchases will be in the PurchaseStatus.PAID
status.
Purchase confirmation is required for a success transaction. To do this, use the confirmTwoStepPurchase
method.
RuStorePayClient.instance.purchaseInteractor.confirmTwoStepPurchase(purchaseId).then((value) {
// Process success
});
id
— product ID.-
developerPayload
— string with additional order information, that you can specify on purchase initialization
Server validation
If you need to validate a purchase on the RuStore server, you can use subscriptionToken
in ProductPurchaseResult.SuccessProductPurchaseResult
, that is returned on successful purchase.
You can also get a subscriptionToken
from the Purchase
entity. The Purchase
entity can be retrieved using the getPurchases()
method.
RuStorePayClient.instance.getPurchases().then((response) {
for (final purchase in response.purchases) {
print(purchase?.subscriptionToken);
}
}, onError: (err) {
print("purchases err: $err" );
}
);
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. On a successful payment, such purchases will change their statuses to PurchaseStatus.paid
. Purchase cancellations means that the money is put off hold on the user's account.
RuStorePayClient.instance.purchaseInteractor.cancelTwoStepPurchase(id).then((value) {
// Process success
});
id
— product ID.
RuStoreFlutterUtils methods (public methods)
Check if the RuStore app is installed on the user's device.
RuStorePayClient.instance.ruStoreUtils.isRuStoreInstalled().then((isInstalled) {
});
Te method returns logical isInstalled
.
Open RuStore download web page.
RuStorePayClient.instance.ruStoreUtils.openRuStoreDownloadInstruction()
Start RuStore app
RuStorePayClient.instance.ruStoreUtils.openRuStore()
Start RuStore app for authorization. The RuStore app will be automatically closed after successful authorization.
RuStorePayClient.instance.ruStoreUtils.openRuStoreAuthorization()
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.