react-native-rustore-billing
React Native RuStoreSDK для подключения платежей
Общее
Пример реализации
Для того, чтобы узнать как правильно интегрировать платежи, рекомендуется ознакомиться с приложением-примером в папке example
.
Условия работы платежей
Для работы проведения платежей необходимо соблюдение следующих условий:
- На устройстве пользователя должен быть установлен RuStore.
- RuStore должен поддерживать функциональность платежей.
- Пользователь должен быть авторизован в RuStore.
- Пользователь и приложение не должны быть заблокированы в RuStore.
- Для приложения должна быть включена возможность покупок в консоли разработчика RuStore.
Подключение в проект
// HTTPS
npm install git+https://git@gitflic.ru/project/rustore/react-native-rustore-billing-sdk.git
// SSH
npm install git+ssh://git@gitflic.ru/project/rustore/react-native-rustore-billing-sdk.git
Обработка deeplink
Для корректной работы оплаты через сторонние приложения (СБП или SberPay), вам необходимо правильно реализовать обработку deeplink. Для этого необходимо указать в AndroidManifest.xml intent-filter с scheme вашего проекта:
<activity android:name=".sample.MainActivity">
<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>
где “yourappscheme” - схема вашего deeplink, может быть изменена на другую. Эта схема должна совпадать со схемой, передаваемым в методе RustoreBillingClient.init()
.
Инициализация
Перед вызовом методов библиотеки необходимо выполнить ее инициализацию. Для инициализации вызовете метод RustoreBillingClient.init()
:
try {
RustoreBillingClient.init({
consoleApplicationId: 'appId',
deeplinkScheme: 'scheme',
});
console.log(`initialize success: ${result}`);
} catch (err) {
console.log(`initialize err: ${err}`);
}
consoleApplicationId
- код приложения из консоли разработчика RuStore (пример: https://console.rustore.ru/apps/123456).deeplinkScheme
- cхема deeplink, необходимая для возврата в ваше приложение после оплаты через стороннее приложение (например, SberPay или СБП). SDK генерирует свой хост к данной схеме. Важно, чтобы схема deeplink, передаваемая в deeplinkScheme, совпадала со схемой, указанной в AndroidManifest.xml в разделе “Обработка deeplink”.
Проверка доступности работы с платежами
Для проверки доступности платежей необходимы следующие условия:
- На устройстве пользователя должен быть установлен RuStore.
- RuStore должен поддерживать функциональность платежей.
- Пользователь должен быть авторизован в RuStore.
- Пользователь и приложение не должны быть заблокированы в RuStore.
- Для приложения должна быть включена возможность покупок в консоли разработчика RuStore.
- Если все условия выполняются, метод
RustoreBillingClient.checkPurchasesAvailability()
возвращает значениеtrue
.
try {
const isAvailable = await RustoreBillingClient.checkPurchasesAvailability();
console.log(`available success ${isAvailable}`);
} catch (err) {
console.log(`available error ${err}`);
}
Проверка установлен ли RuStore на устройстве
try {
const isRuStoreInstalled = await RustoreBillingClient.isRuStoreInstalled()
} catch (err) => {
console.log(`isRuStoreInstalled error ${err}`);
}
Работа с продуктами
Получение списка продуктов
Для получения продуктов необходимо использовать метод RustoreBillingClient.getProducts(productIds)
:
try {
const products = await RustoreBillingClient.getProducts(productIds);
for (const product of products) {
console.log(product?.productId);
}
} catch (err) {
console.log(`products err: ${err}`);
}
productIds
- список идентификаторов продуктов.
Метод возвращает список продуктов Product[]
. Ниже представлена модель продукта:
interface Product {
productId: string;
productType?: ProductType;
productStatus: ProductStatus;
priceLabel?: string;
price?: number;
currency?: string;
language?: string;
title?: string;
description?: string;
imageUrl?: string;
promoImageUrl?: string;
subscription?: ProductSubscription;
}
productId
- идентификатор продукта.productType
- тип продукта.productStatus
- статус продукта.priceLabel
- отформатированная цена товара, включая валютный знак на языке [language].price
- цена в минимальных единицах.currency
- код валюты ISO 4217.language
- язык, указанный с помощью BCP 47 кодирования.title
- название продукта на языке [language].description
- описание продукта на языке [language].imageUrl
- ссылка на картинку.promoImageUrl
- ссылка на промо картинку.subscription
- описание подписки, возвращается только для продуктов с типом subscription.
Структура подписки Subscription
:
interface ProductSubscription {
subscriptionPeriod?: SubscriptionPeriod;
freeTrialPeriod?: SubscriptionPeriod;
gracePeriod?: SubscriptionPeriod;
introductoryPrice?: string;
introductoryPriceAmount?: string;
introductoryPricePeriod?: SubscriptionPeriod;
}
subscriptionPeriod
- период подписки.freeTrialPeriod
- пробный период подписки.gracePeriod
- льготный период подписки.introductoryPrice
- отформатированная вступительная цена подписки, включая знак валюты, на языке product:language.introductoryPriceAmount
- вступительная цена в минимальных единицах валюты (в копейках).introductoryPricePeriod
- расчетный период вступительной цены.
Интерфейс периода подписки SubscriptionPeriod
:
interface SubscriptionPeriod {
years: number;
months: number;
days: number;
}
years
- количество лет.months
- количество месяцев.days
- количество дней.
Работа с покупками
Получение списка покупок
Для получения списка покупок необходимо использовать метод RustoreBillingClient.getPurchases()
:
try {
const purchases = await RustoreBillingClient.getPurchases();
for (const purchase of purchases) {
console.log(purchase?.purchaseId);
}
} catch (err) {
console.log(`purchase err: ${err}`);
}
Метод возвращает список покупок Purchase[]
. Ниже представлена модель покупки:
interface Purchase {
purchaseId?: string;
productId: string;
productType?: ProductType;
invoiceId?: string;
language?: string;
purchaseTime?: string;
orderId?: string;
amountLabel?: string;
amount?: number;
currency?: string;
quantity?: number;
purchaseState?: PurchaseState;
developerPayload?: string;
subscriptionToken?: string;
}
purchaseId
- идентификатор покупки.productId
- идентификатор продукта.productType
- тип продукта.invoiceId
- идентификатор счета.language
- язык, указанный с помощью BCP 47 кодирования.purchaseTime
- время покупки (в формате RFC 3339).orderId
- уникальный идентификатор оплаты, сформированный приложением (uuid).amountLabel
- отформатированная цена покупки, включая валютный знак на языке [language].amount
- цена в минимальных единицах валюты.currency
- код валюты ISO 4217.quantity
- количество продукта.purchaseState
- состояние покупки.CREATED
- покупка создана.INVOICE_CREATED
- по покупке создан счёт, ожидает оплаты.CONFIRMED
- финальный статус, покупка подтверждена (для подписок и непотребляемых товаров). Средства отправлены разработчику. Повторная покупка товара блокируется магазином.PAID
- только покупки потребляемого товара — промежуточный статус, средства на счёте покупателя зарезервированы. Покупка ожидает подтверждения от разработчика.CANCELLED
- ппокупка отменена — оплата не была произведена или был совершен возврат средств покупателю (для подписок после возврата средств покупка не переходит в CANCELLED).CONSUMED
- потребление покупки подтверждено.PAUSED
- пподписка перешла в HOLD период.TERMINATED
- подписка закрылась.
developerPayload
- указанная разработчиком строка, содержащая дополнительную информацию о заказе.subscriptionToken
- токен для валидации покупки на сервере.
Получение конкретной покупки
Для получения конкретной покупки необходимо использовать метод RustoreBillingClient.getPurchaseInfo(purchaseId)
:
try {
const purchase = await RustoreBillingClient.getPurchaseInfo('purchaseId');
console.log(purchase?.purchaseId);
} catch (err) {
console.log(`purchase err: ${err}`);
}
purchaseId
- идентификатор покупки.
Метод возвращает Purchase
, интерфейс которой описан выше.
Покупка продукта
Для вызова покупки продукта используйте метод RustoreBillingClient.purchaseProduct({...})
:
try {
const response = await RustoreBillingClient.purchaseProduct({
productId: 'productId',
orderId: 'orderId',
quantity: 0,
developerPayload: 'developerPayload'
});
console.log(`purchase success: ${response}`);
} catch (err) {
console.log(`purchase err: ${err}`);
}
productId
- идентификатор продукта.orderId
- идентификатор заказа, создаётся на стороне AnyApp (опционально. Если не указан, то генерируется автоматически).quantity
- количество продуктов (опционально).developerPayload
- дополнительная информация от разработчика AnyApp (опционально).
Результатом покупки может быть один из следующих интерфейсов: SuccessPayment
, CancelledPayment
или FailurePayment
:
enum PaymentResult {
SUCCESS = 'SUCCESS',
CANCELLED = 'CANCELLED',
FAILURE = 'FAILURE',
}
interface SuccessPaymentResult {
orderId?: string;
purchaseId: string;
productId: string;
invoiceId: string;
sandbox: boolean;
subscriptionToken?: string;
}
interface SuccessPayment {
type: PaymentResult.SUCCESS;
response: SuccessPaymentResult;
}
interface CancelledPaymentResult {
purchaseId: string;
sandbox: boolean;
}
interface CancelledPayment {
type: PaymentResult.CANCELLED;
response: CancelledPaymentResult;
}
interface FailurePaymentResult {
purchaseId?: string;
invoiceId?: string;
orderId?: string;
quantity?: number;
productId?: string;
errorCode?: number;
sandbox: boolean;
}
interface FailurePayment {
type: PaymentResult.FAILURE;
response: FailurePaymentResult;
}
SuccessPayment
- результат успешного завершения покупки цифрового товара.FailurePayment
- результат ошибки покупки цифрового товара.CancelledPayment
- результат отмены покупки цифрового товара.
Потребление (подтверждение) покупки
RuStore содержит продукты следующих типов:
CONSUMABLE
- потребляемый (можно купить много раз, например кристаллы в приложении).NON_CONSUMABLE
- непотребляемый (можно купить один раз, например отключение рекламы в приложении).SUBSCRIPTION
- подписка (можно купить на период времени, например подписка в стриминговом сервисе).
Потребления требуют только продукты типа CONSUMABLE
, если они находятся в состоянии PurchaseState.PAID
.
Для потребления покупки вы можете использовать метод RustoreBillingClient.confirmPurchase({...})
:
try {
const isConfirmed = await RustoreBillingClient.confirmPurchase({
purchaseId: 'purchaseId',
developerPayload: 'developerPayload'
})
console.log(`confirm success: ${isConfirmed}`);
} catch (err) {
console.log(`confirm err: ${err}`);
}
purchaseId
- идентификатор покупки.developerPayload
- дополнительная информация от разработчика AnyApp (опционально).
Если все условия выполняются, метод RustoreBillingClient.confirmPurchase()
возвращает значение true
.
Отмена покупки
Для отмены покупки вы можете использовать метод RustoreBillingClient.deletePurchase(purchaseId)
:
try {
const isDeleted = await RustoreBillingClient.deletePurchase(purchaseId)
console.log(`delete success: ${isDeleted}`);
} catch (err) {
console.log(`delete err: ${err}`);
}
purchaseId
- идентификатор покупки.
Если все условия выполняются, метод RustoreBillingClient.deletePurchase()
возвращает значение true
.
Сценарий потребления и отмены покупки
Обработка незавершённых платежей должна производиться разработчиком AnyApp.
Метод отмены покупки (deletePurchase
) необходимо использовать, если:
- Метод получения списка покупок (
getPurchases
) вернул покупку со статусом:PurchaseState.CREATED
.PurchaseState.INVOICE_CREATED
.
- Метод покупки (
purchaseProduct
) вернулPaymentResult.Cancelled
. - Метод покупки (
purchaseProduct
) вернулPaymentResult.Failure
.
Метод потребления продукта (confirmPurchase
) необходимо использовать, если метод получения списка покупок (getPurchases
) вернул покупку типа CONSUMABLE
и со статусом PurchaseState.PAID
.
Тестовые данные
Ссылка на тестовые банковские карты.
Описание
React Native RuStoreSDK для подключения платежей