2.2.1
该门户网站正在开发中。文档的完整版本请看这里.
通过以下链接下载Unity插件以集成支付功能。
为了进行支付,必须遵守所有条件:
- 用户的设 备上安装了RuStore应用程序。
- 用户在RuStore中已授权。
- 用户和应用程序不应在RuStore中被封锁。
- 应用程序必须在 RuStore 控制台系统中启用购买功能。
服务在俄罗斯联邦以外有一些运作限制。
在项目中集成
要集成,请下载RuStoreBilling SDK并将其导入项目(Assets → Import Package → Custom Package)。依赖项将通过SDK中包含的External Dependency Manager自动连接。
为了正确处理SDK的依赖项,需要设置以下参数:
- Edit-> Project Settings -> Player Settings -> Publishing Settings,启用Custom Main Gradle Template和CustomGradlePropertiesTemplate
- Assets-> External Dependencies Manager -> Android Resolver -> Settings,启用Use Jetifier, Patch mainTemplate.gradle,PatchgradleTemplate.properties
成设置后,请确保执行Assets -> External Dependencies Manager -> Android Resolver -> Force Resolve。
MinimumAPIlevel应设置为不低于24。应用程序的缩减(ProGuard/R8)目前不受支持,因此需要在项目设置中将其关闭(File → Build Settings → Player Settings → Publishing Settings → Minify)。
处理deeplink
当用户通过SberPay支付时,会跳转到俄罗斯储蓄银行应用程序。支付完成后,应使用deeplink返回原应用程序 。要处理deeplink,需在AndroidManifest.xml中设置带有您项目scheme的intent-filter:
\< activity \`\`android:name = \"ru.rustore.unitysdk.RuStoreUnityActivity\" android:theme = \"@style/UnityThemeSelector\" android:exported = \"true\" \> \`\`\< 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方案,可以 更改为其他方案。
接下来,扩展UnityPlayerActivity类,并在onNewIntent中添加对传入intent的处理。
package ru.rustore.unitysdk;import android.os.Bundle;import android.content.Intent;import ru.rustore.unitysdk.billingclient.RuStoreUnityBillingClient;import com.unity3d.player.UnityPlayerActivity;public class RuStoreUnityActivity extends UnityPlayerActivity { \`\`@Override protected void onCreate(Bundle savedInstanceState) { \`\`super .onCreate(savedInstanceState); \`\`if (savedInstanceState == null ) { \`\`RuStoreUnityBillingClient.onNewIntent(getIntent()); \`\`} \`\`} \`\`@Override protected void onNewIntent(Intent intent) { \`\`super .onNewIntent(intent); \`\`RuStoreUnityBillingClient.onNewIntent(intent); \`\`}}
包含UnityPlayerActivity扩展代码的Java文件放置在项目的Assets文件夹中。如果已有UnityPlayerActivity扩展,需合并onCreate和onNewIntent功能代码至该扩展。
初始化
在调用库的方法之前,需要先进行其初始化。库将使用在Unity编辑器中设置的参数进行初始化。在编辑器菜单中选择 Window → RuStoreSDK → Settings → Billing Client。
RuStoreBillingClient.Instance.Init();\<br\>
果需要使用其他设置进行初始化,可以直接从代码中传递这些设置:
var config = new RuStoreBillingClientConfig() { \`\`consoleApplicationId = \"11111\" , \`\`deeplinkPrefix = \"yourappscheme\" , \`\`allowNativeErrorHandling = true, enableLogs = true};RuStoreBillingClient.Instance.Init(config);
consoleApplicationId
- 来自RuStore 控制台的应用程序代码。(例如: https://console.rustore.ru/apps/111111)deeplinkPrefix
- url用于实现deeplink的url。可以使用任何唯一名称作为名称(例如: yourappscheme)allowAllowNativeErrorHandling
- 允许原生SDK处理错误(参见错误处理部分);enableLogs
- 启用日志。
要的是,传递给deeplinkPrefix的deeplink方案必须与AndroidManifest.xml中指定的方案相匹配。
如果需要检查库是否已初始化,请使用RuStoreBillingClient.Instance.isInitialized属性。如果库已初始化,其值为true;如果Init还未被调用,则为false。
var isInitialized = RuStoreBillingClient.Instance.IsIninialized;
检查支付功能的可用性
要检查支付功能的可用性,请调用 checkPurchasesAvailability 方法。在调用时,将检查以下条件:
- 用户的设备上必须安装 RuStore。
- RuStore 必须支持支付功能。
- 用户必须在 RuStore 中获得授权。
- 用户和应用程序不应在RuStore中被封锁。
- 应用程序必须在 RuStore 控制台系统中启用购买功能。
果所有条件都满足,则在onSuccess返回 FeatureAvailabilityResult.isAvailable == true。否则,返回 FeatureAvailabilityResult.isAvailable == false,其中 FeatureAvailabilityResult.cause - 是未满足条件的错误。 所有可能的 RuStoreException 错误在 «错误处理»部分有描述。其他错误(例如,"没有互联网连接")将在 onFailure
中返回。
RuStoreBillingClient.Instance.CheckPurchasesAvailability( \`\`onFailure: (error) =\> { \`\`// Process error \`\`}, \`\`onSuccess: (response) =\> { \`\`if (response.isAvailable) { \`\`// Process purchases available \`\`} else { \`\`// Process purchases unavailable \`\`} \`\`});
获取产品列表
要获取产品,使用GetProducts方法:
RuStoreBillingClient.Instance.GetProducts(productIds, \`\`onFailure: (error) =\> { \`\`// Process error \`\`}, \`\`onSuccess: (response) =\> { \`\`// Process response \`\`});
string\[\] productIds
- 产品标识符列表。
方法返回:
Listresponse
- 产品列表。
品结构:
public class Product { \`\`public enum ProductStatus { \`\`ACTIVE, \`\`INACTIVE \`\`} \`\`public enum ProductType { \`\`NON_CONSUMABLE, \`\`CONSUMABLE, \`\`SUBSCRIPTION \`\`} \`\`public string productId; \`\`public ProductType productType; \`\`public ProductStatus productStatus; \`\`public string priceLabel; \`\`public int price; \`\`public string currency; \`\`public string language; \`\`public string title; \`\`public string description; \`\`public string imageUrl; \`\`public string promoImageUrl; \`\`public ProductSubscription subscription;}
productId
- 产品标识符;productType
- 产品类型;productStatus
- 产品状态;priceLable
- 格式化的产品价格,包括[language]语言的货币符号;price
- 以货币最小单位(戈比)表示的价格;currency
- ISO 4217货币代码;language
- 使用 BCP 47 编码指定的语言;title
- 产品名称,以[language]语言表示;description
- 产品描述,以[language]语言表示;imageUrl
- 图片链接;promoImageUrl
- 促销图片链接;subscription
- 订阅描述,仅对于类型为 subscription 的产品返回。
阅结构:
public class ProductSubscription { \`\`public SubscriptionPeriod subscriptionPeriod; \`\`public SubscriptionPeriod freeTrialPeriod; \`\`public SubscriptionPeriod gracePeriod; \`\`public string introductoryPrice; \`\`public string introductoryPriceAmount; \`\`public SubscriptionPeriod introductoryPricePeriod;}
subscriptionPeriod
- 订阅周期;freeTrialPeriod
- 订阅试用期;gracePeriod
- 订阅宽限期;introductoryPrice
- 格式化的介绍性订阅价格,包括product:language语言的货币符号;introductoryPriceAmount
- 以货币最小单位(戈比)表示的介绍性价格;introductoryPricePeriod
- 介绍性价格计算周期。
阅周期结构:
public class SubscriptionPeriod { \`\`public int years; \`\`public int months; \`\`public int days;}
years
- 年数;months
- 月数;days
- 天数。
获取购买列表
要获取购买列表,请使用getPurchases方法:
RuStoreBillingClient.Instance.GetPurchases( \`\`onFailure: (error) =\> { \`\`// Process error \`\`}, \`\`onSuccess: (response) =\> { \`\`// Process response \`\`});
方法返回:
Listresponse
- 购买列表。
买结构:
public class Purchase { \`\`public enum PurchaseState \`\`{ \`\`CREATED, \`\`INVOICE_CREATED, \`\`CONFIRMED, \`\`PAID, \`\`CANCELLED, \`\`CONSUMED, \`\`CLOSED \`\`} \`\`public string purchaseId; \`\`public string productId; \`\`public string description; \`\`public string invoiceId; \`\`public string language; \`\`public DateTime purchaseTime; \`\`public string orderId; \`\`public string amountLabel; \`\`public int amount; \`\`public string currency; \`\`public int quantity; \`\`public PurchaseState purchaseState; \`\`public string developerPayload; \`\`public string subscriptionToken;}
purchaseId
- 购买标识符;productId
- 产品标识符;description
- 购买描述;invoiceId
- 账单标识符;language
- 使用 BCP 47 编码指定的语言;purchaseTime
- 购买时间;orderId
- 应用程序生成的唯一支付标识符(uuid);amountLable
- 格式化的购买价格,包括[language]语言的货币符号;amount
- 以最小货币单位表示的价格;currency
- ISO 4217货币代码;quantity
- 产品数量;purchaseState
- 购买状态:- 购买状态的可能值:
CREATED
- 已创建;INVOICE_CREATED
- 已创建,等待支付;CONFIRMED
- 已确认;PAID
- 已支付;CANCELLED
- 购买已取消;CONSUMED
- 已确认购买消耗;CLOSED
- 订阅已取消;TERMINATED
- 订阅已完成。
- 购买状态的可能值:
developerPayload
- 开发者指定的字符串,包含关于订单的附加信息;subscriptionToken
- 用于在服务器端验证购买的令牌。
状态模型 (purchaseState):
订阅购买状态模型 (SUBSCRIPTIONS):
非消耗性产品购买状态模型 (NON-CONSUMABLES):
消耗性产品购买状态模型 (CONSUMABLES):
购买产品
要调用购买产品,请使用 purchaseProduct 方法:
RuStoreBillingClient.Instance.PurchaseProduct( \`\`productId: \"productId\" , \`\`quantity: 1, \`\`developerPayload: \"\" , \`\`onFailure: (error) =\> { \`\`// Process error \`\`}, \`\`onSuccess: (response) =\> { \`\`switch (response) { \`\`case PaymentSuccess paymentSuccess: \`\`// Process PaymentSuccess \`\`break ; \`\`case PaymentCancelled paymentCancelled: \`\`// Process PaymentCancelled \`\`break ; \`\`case PaymentFailure paymentFailure: \`\`// Process PaymentFailure \`\`break ; \`\`case InvalidPaymentState invalidPaymentState: \`\`// Process InvalidPaymentState \`\`break ; \`\`} \`\`});
stringproductId
- 产品标识符;intquantity
- 产品数量;stringdeveloperPayload
- AnyApp开发者的附加信息。
买结果的结构:
public class PaymentResult {}public class PaymentSuccess : PaymentResult { \`\`public string orderId; \`\`public string purchaseId; \`\`public string productId; \`\`public string invoiceId; \`\`public string subscriptionToken;}public class PaymentCancelled : PaymentResult { \`\`public string purchaseId;}public class PaymentFailure : PaymentResult { \`\`public string purchaseId; \`\`public string invoiceId; \`\`public string orderId; \`\`public int quantity; \`\`public string productId; \`\`public int errorCode;}public class InvalidPaymentState : PaymentResult {}
PaymentSuccess
- 成功完成数字产品购买的结果;PaymentCancelled
- 数字产品购买被取消的结果;PaymentFailure
- 购买数字产品时错误的结果;InvalidPaymentState
- 支付SDK操作错误。可能因deeplink回调不正确而发生。
购买消耗(确认)
RuStore 包含以下类型的产品:
CONSUMABLE
- 消耗的(可以多次购买,例如应用中的水晶);NON_CONSUMABLE
- 非消耗的(只能购买一次,例如禁用应用程序中的广告);SUBSCRIPTION
- 订阅(可以购买一段时间,例如流媒体服务的订阅)。
有处于 PurchaseState.PAID
状态的 CONSUMABLE
类型产品需要消耗。
您可以使用 confirmPurchase 方法来消耗购买:
RuStoreBillingClient.Instance.ConfirmPurchase( \`\`purchaseId: \"purchaseId\" , \`\`onFailure: (error) =\> { \`\`// Process error \`\`}, \`\`onSuccess: () =\> { \`\`// Process success \`\`});
purchaseId
- 购买标识符。
取消购买
要取 消购买,需要使用 deletePurchase 方法:
RuStoreBillingClient.Instance.DeletePurchase( \`\`purchaseId: \"purchaseId\" , \`\`onFailure: (error) =\> { \`\`// Process error \`\`}, \`\`onSuccess: () =\> { \`\`// Process success \`\`});
purchaseId
- 购买标识符。
果您有与删除购买相关的逻辑,请使用此方法。购买将在20分钟后自动取消,或者在同一客户端进行重复购买时取消。
购买消耗和取消的流程
未完成的支付处理应由 AnyApp 的开发者执行。
使用取消购买方法的条件:
- 获取购买列表方法返回的购买状态为:
- PurchaseState.CREATED;
- PurchaseState.INVOICE_CREATED.
- 如果PurchaseProduct返回InvalidPurchase。
- 如果PurchaseProduct返回包含以下PaymentFinishCode的PurchaseResult:
CLOSED_BY_USER
- 由用户取消;UNHANDLED_FORM_ERROR
- 未知错误;PAYMENT_TIMEOUT
- 支付超时错误;DECLINED_BY_SERVER
- 由服务器拒绝;RESULT_UNKNOWN
- 未知支付状态。
用产品消耗方法的条件:
- 获取购买列表方法返回的购买状态为:
PurchaseState.PAID
.
- 如果 PurchaseProduct 返回的 PaymentResult.PurchaseResult 包含以下 PaymentFinishCode:
SUCCESSFUL_PAYMENT
- 成功支付。
错误处理
在 SDK 方法的 onFailure
处理程序中传递发生的错误。
错误结构:
public class RuStoreError { \`\`public string name; \`\`public string description;}
name
- 错误名称;description
- 错误描述。
能的错误:
RuStoreNotInstalledException
- 用户设备上未安装 RuStore;RuStoreOutdatedException
- 用户设备上安装的 RuStore 不支持支付;RuStoreUserUnauthorizedException
- 用户未在 RuStore 中授权;RuStoreApplicationBannedException
- 应用程序在 RuStore 中被禁止;RuStoreUserBannedException
- 用户在 RuStore 中被禁止;RuStoreException
- RuStore的基本错误,其他错误均继承自此。
用 PurchaseProduct 方法时,错误会自动处理。
如果在 SDK 初始化时传递了参数 allowNativeErrorHandling == true
,在出现错误时,除了调用相应的 onFailure
处理程序外,该错误还会传递到原生 SDK 的 resolveForBilling
方法中,以便向用户显示错误对话框:
public fun RuStoreException.resolveForBilling(context: Context)
初始化后,可以通过设置 AllowNativeErrorHandling
属性来更改此行为:
RuStoreBillingClient.Instance.AllowNativeErrorHandling = false ;