跳到主要内容

2.2.1

注意

该门户网站正在开发中。文档的完整版本请看这里.

通过以下链接下载Unity插件以集成支付功能。

为了进行支付,必须遵守所有条件:

  1. 用户的设备上安装了RuStore应用程序。
  2. 用户在RuStore中已授权。
  3. 用户和应用程序不应在RuStore中被封锁。
  4. 应用程序必须在 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)。

当用户通过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 方法。在调用时,将检查以下条件:

  1. 用户的设备上必须安装 RuStore。
  2. RuStore 必须支持支付功能。
  3. 用户必须在 RuStore 中获得授权。
  4. 用户和应用程序不应在RuStore中被封锁。
  5. 应用程序必须在 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 的开发者执行。

使用取消购买方法的条件:

  1. 获取购买列表方法返回的购买状态为:
    • PurchaseState.CREATED;
    • PurchaseState.INVOICE_CREATED.
  2. 如果PurchaseProduct返回InvalidPurchase。
  3. 如果PurchaseProduct返回包含以下PaymentFinishCode的PurchaseResult:
    • CLOSED_BY_USER - 由用户取消;
    • UNHANDLED_FORM_ERROR - 未知错误;
    • PAYMENT_TIMEOUT - 支付超时错误;
    • DECLINED_BY_SERVER - 由服务器拒绝;
    • RESULT_UNKNOWN - 未知支付状态。

用产品消耗方法的条件:

  1. 获取购买列表方法返回的购买状态为:
    • PurchaseState.PAID.
  2. 如果 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 ;