How to migrate to Pay SDK
The Pay SDK has important differences compared to the BillingClient SDK.
This section collects the key changes you should pay attention to when migrating from the BillingClient SDK. You can find full details with code examples in the documentation for a specific Pay SDK version.
Dependency list
The Pay SDK has a shorter dependency list.
Adding the SDK to your project
When adding the dependency, note the SDK artifact name is different (pay
instead of billingclient
):
- BillingClient SDK:
dependencies {
implementation(platform("ru.rustore.sdk:bom:2025.02.01"))
implementation("ru.rustore.sdk:billingclient")
}
- Pay SDK:
dependencies {
implementation(platform("ru.rustore.sdk:bom:2025.08.01"))
implementation("ru.rustore.sdk:pay")
}
Initialization
The way you pass consoleApplicationId
during initialization has changed:
- BillingClient SDK: create an instance of
RuStoreBillingClient
viaRuStoreBillingClientFactory.create()
in your app code and passconsoleApplicationId
. - Pay SDK: add the
console_app_id_value
parameter to AndroidManifest.xml. ThethemeProvider
,externalPaymentLoggerFactory
, anddebugLogs
parameters are not used.
Deeplink handling
- In the BillingClient SDK, the deeplink scheme is specified via
RustoreBillingClientFactory.create()
. - In the Pay SDK, the deeplink scheme is specified in AndroidManifest.xml using
sdk_pay_scheme_value
. A publicIntentInteractor
has been added for handling deeplinks.
Checking payment availability
The method for checking payment availability has changed:
- BillingClient SDK:
RuStoreBillingClient.Companion.checkPurchasesAvailability()
. - Pay SDK:
RuStorePayClient.instance.getPurchaseInteractor().getPurchaseAvailability()
.
The method results have also changed:
- BillingClient SDK:
FeatureAvailabilityResult.Available
andFeatureAvailabilityResult.Unavailable(val cause: RuStoreException)
. - Pay SDK:
PurchaseAvailabilityResult.Available
andPurchaseAvailabilityResult.Unavailable(val cause: Throwable)
.
Fetching the product list
- In the Pay SDK, fetching the product list does not require user authorization.
- You can now request up to 1000 items per request (in the BillingClient SDK it was up to 100).
- The structure of the returned product model has changed. The table below shows the field correspondences returned by both SDKs. For detailed field descriptions, see the documentation for billingClient SDK and Pay SDK.
- BillingClient SDK:
billingClient.products productsUseCase.getProducts()
. - Pay SDK:
RuStorePayClient.getProductInteractor().getProducts(productsId: List<ProductId>)
.
The structure of the returned product model has changed. The table below shows the field mappings returned by both SDKs. See detailed field descriptions in the documentation for BillingClient SDK and Pay SDK.
BillingClient SDK | Pay SDK |
---|---|
productId | productId |
productType | type |
productStatus | — |
priceLabel | amountLabel |
price | price |
currency | currency |
language | — |
title | title |
description | description |
imageUrl | imageUrl |
promoImageUrl | — |
subscription | — |
Fetching the list of purchases
The method for fetching the list of purchases has changed:
- BillingClient SDK:
billingClient.purchases purchasesUseCase.getPurchases()
. - Pay SDK:
RuStorePayClient.getPurchaseInteractor().getPurchases()
.
The method supports filtering:
-
by product type (
productType
): consumables, non-consumables, subscriptions; -
by purchase status (
purchaseStatus
):- for products:
PAID
,CONFIRMED
; - for subscriptions:
ACTIVE
,PAUSED
.
- for products:
Purchase types
The response structure for “get purchase info” and “get purchase list” has changed.
A common Purchase
interface and two implementations have been introduced:
ProductPurchase
for one-time purchases.SubscriptionPurchase
for subscriptions.
This separation groups shared logic and data while allowing each purchase type to have its own properties and behavior.
The table below shows the fields returned by both SDKs.
BillingClient SDK | Pay SDK (common interface) | Pay SDK ProductPurchase | Pay SDK SubscriptionPurchase |
---|---|---|---|
purchaseId | purchaseId | purchaseId | purchaseId |
productId | — | productId | productId |
invoiceId | invoiceId | invoiceId | invoiceId |
language | — | — | — |
purchaseTime | purchaseTime | purchaseTime | purchaseTime |
orderId | orderId | orderId | orderId |
— | purchaseType | purchaseType | purchaseType |
— | description | description | description |
amountLabel | amountLabel | amountLabel | amountLabel |
amount | price | price | price |
currency | currency | currency | currency |
quantity | — | quantity | — |
— | — | productType | - |
purchaseState | status | status | status |
developerPayload | developerPayload | developerPayload | developerPayload |
subscriptionToken | — | — | — |
sandbox | sandbox | sandbox | sandbox |
— | — | — | expirationDate |
— | — | — | gracePeriodEnabled |
Getting purchase details
The method for getting purchase details has changed:
- BillingClient SDK:
billingClient.purchases purchasesUseCase.getPurchaseInfo(PurchaseId("purchaseId"))
. - Pay SDK:
RuStorePayClient.getPurchaseInteractor().getPurchase(PurchaseId("purchaseId"))
.
Purchase statuses
BillingClient SDK | Pay SDK ProductPurchase | Pay SDK SubscriptionPurchase |
---|---|---|
CREATED | - | - |
INVOICE_CREATED | INVOICE_CREATED | INVOICE_CREATED |
CANCELLED | CANCELLED | CANCELLED |
- | PROCESSING | PROCESSING |
- | REJECTED | REJECTED |
CONFIRMED | CONFIRMED | - |
CONSUMED | - | - |
- | REFUNDED | - |
- | REFUNDING | - |
- | EXECUTING | - |
- | EXPIRED | EXPIRED |
PAID | PAID | - |
- | REVERSED | - |
- | - | ACTIVE |
PAUSED | - | PAUSED |
TERMINATED | - | TERMINATED |
- | - | CLOSED |
Product purchase
The product purchase method has been replaced with two new methods:
-
BillingClient SDK:
billingClient.purchases purchasesUseCase.purchaseProduct()
. -
Pay SDK:
RuStorePayClient.instance.getPurchaseInteractor().purchase(params, preferredPurchaseType: PreferredPurchaseType = PreferredPurchaseType.ONE_STEP)
— a universal method to start a purchase. It lets you choose the payment flow — one-step or two-step.-
One-step (
PreferredPurchaseType.ONE_STEP
): Funds are charged immediately. -
Two-step (
PreferredPurchaseType.TWO_STEP
): The SDK attempts a two-step flow. If the user selects a payment method that does not support authorization holds, the purchase proceeds as a one-step flow.
RuStorePayClient.instance.getPurchaseInteractor().purchaseTwoStep()
— a method for a guaranteed two-step flow. The payment sheet shows only methods that support holds. -
-
In the BillingClient SDK, the payment flow was tied to the product type (consumable/non-consumable). In the Pay SDK, you choose the flow when starting the payment.
-
The method results have changed:
- BillingClient SDK:
Success
,Failure
,Cancelled
, andInvalidPaymentState
. - Pay SDK: a successful purchase returns the
ProductPurchaseResult
class. Separate “cancel” and “error” result classes are no longer used. Errors are handled viaOnFailureListener
, where you handleRustorePaymentException.ProductPurchaseException
(general error) andRustorePaymentException.ProductPurchaseCancelled
(user cancellation).
- BillingClient SDK:
-
Optional parameters
appUserId
andappUserEmail
have been added to purchase methods in the Pay SDK.
Payment error handling
If an error occurs during payment or the user cancels the purchase, the payment method (both the selectable-flow and the two-step method) completes with an error.
Use OnFailureListener
to handle errors and define behavior for each case:
ProductPurchaseException
— product purchase error.ProductPurchaseCancelled
— error caused by user cancellation (the user closed the payment sheet) before the purchase result was received. In this case, it is recommended to additionally check the purchase status via the “get purchase info” method.
For more details and code examples, see Pay SDK page.
Error handling in Pay SDK versions prior to 8.0.0
In Pay SDK versions prior to 8.0.0, payment error handling used separate result classes:
CancelProductPurchaseResult
and FailureProductPurchaseResult
.
Server-side validation
For server-side validation of one-time purchases, use:
- BillingClient SDK:
subscriptionToken
, which you can obtain fromPaymentResult.Success
after a successful product purchase. - Pay SDK:
invoiceId
(invoice identifier) is used for server-side payment validation;purchase id
is used to retrieve subscription info. See API: Get payment data by ID (v2), Subscription validation, Subscription receipt confirmation.
Purchase confirmation
The method for purchase confirmation has changed:
- BillingClient SDK:
billingClient.purchases purchasesUseCase.confirmPurchase()
. - Pay SDK:
RuStorePayClient.getPurchaseInteractor().confirmTwoStepPurchase()
— confirms a purchase in the two-step flow.
Purchase cancellation
The method for purchase cancellation has changed:
- BillingClient SDK:
billingClient.purchases purchasesUseCase.deletePurchase()
. - Pay SDK:
RuStorePayClient.getPurchaseInteractor().cancelTwoStepPurchase()
— cancels a purchase in the two-step flow.
See also
Changelog
Pay SDK 10.0.0
- Added subscription purchases to the SDK.
- Added new purchase statuses (for subscriptions) and a purchase type for filtering the purchase list.
- Added a new SberPay payment method.
- Added a caption to the loader on purchase status check screens.
- The public
PurchaseStatus
model was replaced withProductPurchaseStatus
andSubscriptionPurchaseStatus
, representing different status models. - Removed
ProductPurchaseStatus.CONSUMED
and addedProductPurchaseStatus.REFUNDING
. - Added a new field
productType: ProductType
to the successful purchase response model, to the error model, and to the product purchase cancellation model. - Connected a new dependency: Tracer Light.
- Fixed a critical bug during purchase cancellation.
Pay SDK 9.0.1
- Added payments outside of RuStore.
- Added card payments and card saving via VK ID.
- Added coupon creation and application.
Pay SDK 8.0.0
- The one-step method
purchaseOneStep
was replaced with a universalpurchase
method that allows you to select the payment flow (one-step or two-step). - The two-step flow (
TWO_STEP
) is now available only for a limited set of payment methods. - Improved
purchaseTwoStep
, which now guarantees a two-step flow. - Added
RuStorePayInvalidActivePurchase
error when attempting to pay for a product of an unknown type. - Added support for sandbox test payments.
Pay SDK 7.0.0
- The single purchase method was replaced with two new methods for one-step and two-step payments.
- Instead of consumable/non-consumable status models, the SDK now uses status models for one-step and two-step purchase flows.
- The
CONSUMED
status was replaced withCONFIRMED
. - The confirmation method
consumePurchase
was replaced withconfirmTwoStepPurchase
for two-step payments. - A purchase cancellation method was introduced for the two-step flow.
Pay SDK 6.1.0
The first version of the migration guide from BillingClient SDK to Pay SDK 6.1.0.