文档管理中心
API参考应用内支付服务订单、订阅服务Androidcom.huawei.hms.iapInterface SummaryIapClient

IapClient

  • 支持的场景:手机、平板、智慧屏。
  • 支持的OS:EMUI 3.0+、Android 4.4+。
展开

Interface Info

public interface IapClient

包含了In-App Purchases的所有接口。

Nested Class Summary

展开

Qualifier and Type

Interface Name and Description

interface

IapClient.PriceType

定义商品类型。

Public Method Summary

展开

Qualifier and Type

Method Name and Description

Task<ConsumeOwnedPurchaseResult>

consumeOwnedPurchase(ConsumeOwnedPurchaseReq consumeOwnedPurchaseReq)

在消耗型商品支付成功后,应用需要在发放商品成功之后调用此接口对消耗型商品执行消耗操作。

Task<PurchaseIntentResult>

createPurchaseIntent(PurchaseIntentReq purchaseIntentReq)

创建PMS托管商品订单接口,支持购买消耗型商品、非消耗型商品和订阅型商品。

Task<PurchaseIntentResult>

createPurchaseIntentWithPrice(PurchaseIntentWithPriceReq purchaseIntentWithPriceReq)

创建非PMS商品订单接口,支持购买消耗型商品、非消耗型商品,不支持订阅型商品。

注意

该接口已废弃,建议开发者替换成createPurchaseIntent接口。

void

enablePendingPurchase()

使能延迟付款型支付。

Task<IsEnvReadyResult>

isEnvReady()

查询用户登录的帐号服务地是否在华为IAP支付服务支持结算的国家/地区中。

Task<IsSandboxActivatedResult>

isSandboxActivated(IsSandboxActivatedReq isSandboxActivatedReq)

判断当前设备登录的华为帐号及应用的APK版本是否满足沙盒条件。

Task<OwnedPurchasesResult>

obtainOwnedPurchaseRecord(OwnedPurchasesReq ownedPurchasesReq)

用于获取消耗型商品的历史消耗商品信息或订阅型商品的所有订阅收据。

Task<OwnedPurchasesResult>

obtainOwnedPurchases(OwnedPurchasesReq ownedPurchasesReq)

查询用户已订购商品的购买数据。

对于消耗型商品,此接口仅返回用户已购但未消耗的购买数据;对于非消耗型商品,此接口返回用户所有已订购商品的购买数据;对于订阅型商品,此接口仅返回正在生效的订阅关系。

Task<ProductInfoResult>

obtainProductInfo(ProductInfoReq productInfoReq)

用于获取在AppGallery Connect上配置的商品的详情信息。

PurchaseResultInfo

parsePurchaseResultInfoFromIntent(Intent intent)

用于解析支付结果数据。

Task<StartIapActivityResult>

startIapActivity(StartIapActivityReq startIapActivityReq)

用于拉起华为应用内支付的相关页面,包括编辑订阅页和管理订阅页。

Public Methods

consumeOwnedPurchase

展开

Method

Task<ConsumeOwnedPurchaseResult> consumeOwnedPurchase(ConsumeOwnedPurchaseReq consumeOwnedPurchaseReq)

针对消耗型商品,在商品支付成功后,应用需要在发放商品成功之后调用此接口对消耗型商品执行消耗操作。

注意
  1. 您需在发货成功后再执行消耗操作。如果您在消耗之后再进行发货,可能存在以下异常场景:调用消耗接口过程中,服务器消耗成功但因网络异常等原因没有成功将结果回调给端侧,从而造成服务器已经消耗但是端侧没有发货的场景。此场景后续很难处理,您需在发货之后再执行消耗操作。
  2. 您需要把已发货的购买Token传至您的服务器,后续即使消耗失败也可以从您的服务器拉取数据进行对比,避免出现异常。建议您在发货前检查您的应用服务器,以确保每个购买Token都未使用过,即未发过货。

Parameters

展开

Name

Description

consumeOwnedPurchaseReq

包含请求信息的ConsumeOwnedPurchaseReq对象。

Returns

展开

Type

Description

Task<ConsumeOwnedPurchaseResult>

Task设置回调监听可获取接口请求结果。

  • 使用OnSuccessListener可获取到成功场景返回的数据,该场景下返回一个ConsumeOwnedPurchaseResult实例对象。
  • 使用OnFailureListener可获取失败场景的相关信息,该场景返回一个IapApiException异常对象。

Sample code:

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. // 构造一个ConsumeOwnedPurchaseReq对象
  2. ConsumeOwnedPurchaseReq req = new ConsumeOwnedPurchaseReq();
  3. String purchaseToken = "";
  4. try {
  5. // 从购买信息inAppPurchaseData中获取purchaseToken。inAppPurchaseData可从一次支付请求或者请求obtainOwnedPurchases接口获取
  6. InAppPurchaseData inAppPurchaseDataBean = new InAppPurchaseData(inAppPurchaseData);
  7. purchaseToken = inAppPurchaseDataBean.getPurchaseToken();
  8. } catch (JSONException e) {
  9. }
  10. req.setPurchaseToken(purchaseToken);
  11. // 获取调用接口的Activity对象
  12. final Activity activity = getActivity();
  13. // 调用consumeOwnedPurchase接口
  14. Task<ConsumeOwnedPurchaseResult> task = Iap.getIapClient(activity).consumeOwnedPurchase(req);
  15. task.addOnSuccessListener(new OnSuccessListener<ConsumeOwnedPurchaseResult>() {
  16. @Override
  17. public void onSuccess(ConsumeOwnedPurchaseResult result) {
  18. // 获取接口请求成功时的结果信息
  19. }
  20. }).addOnFailureListener(new OnFailureListener() {
  21. @Override
  22. public void onFailure(Exception e) {
  23. if (e instanceof IapApiException) {
  24. IapApiException apiException = (IapApiException) e;
  25. Status status = apiException.getStatus();
  26. int returnCode = apiException.getStatusCode();
  27. } else {
  28. // 其他外部错误
  29. }
  30. }
  31. });
收起
自动换行
深色代码主题
复制
  1. // 构造一个ConsumeOwnedPurchaseReq对象
  2. val req = ConsumeOwnedPurchaseReq()
  3. var purchaseToken = ""
  4. try {
  5. // 从购买信息inAppPurchaseData中获取purchaseToken。inAppPurchaseData可从一次支付请求或者请求obtainOwnedPurchases接口获取
  6. val inAppPurchaseDataBean = InAppPurchaseData(inAppPurchaseData)
  7. purchaseToken = inAppPurchaseDataBean.purchaseToken
  8. } catch (e: JSONException) {
  9. }
  10. req.setPurchaseToken(purchaseToken)
  11. // 获取调用接口的Activity对象
  12. val activity: Activity = getActivity()
  13. // 调用consumeOwnedPurchase接口
  14. val task = Iap.getIapClient(activity).consumeOwnedPurchase(req)
  15. task.addOnSuccessListener {
  16. // 获取接口请求成功时的结果信息
  17. }.addOnFailureListener { e ->
  18. if (e is IapApiException) {
  19. val apiException = e as IapApiException
  20. val status: Status = apiException.status
  21. val returnCode = apiException.statusCode
  22. } else {
  23. // 其他外部错误
  24. }
  25. }

createPurchaseIntent

展开

Method

Task<PurchaseIntentResult> createPurchaseIntent(PurchaseIntentReq purchaseIntentReq)

PMS商品创建订单接口,支持购买消耗型商品、非消耗型商品、订阅型商品。

您在AppGallery Connect配置商品后,使用此接口调用华为应用内支付收银台,显示商品、价格和支付方式。华为会根据国际汇率变动进行商品价格档调整,为了保证应用内商品价格显示一致,请您同时使用obtainProductInfo接口获取商品详情,避免从自有服务端获取价格,以免在汇率变动价格调整时,导致价格显示不一致。

本接口只返回包含IAP收银台页面的Status对象,应用需要自行启动收银台页面,启动方法见PurchaseIntentResult中对Status的说明。用户完成支付后应用可以在onActivityResult回调方法中通过parsePurchaseResultInfoFromIntent获取支付结果信息。

注意
  • 为避免资金损失,您在对支付结果验签成功后,必须校验InAppPurchaseData中的productId、price、currency等信息的一致性。
  • Status不支持序列化,请勿对IAP接口返回的Status对象执行序列化操作。

Parameters

展开

Name

Description

purchaseIntentReq

包含请求信息的PurchaseIntentReq对象。

Returns

展开

Type

Description

Task<PurchaseIntentResult>

Task设置回调监听可获取接口请求结果。

  • 使用OnSuccessListener可获取到成功场景返回的数据,该场景下返回一个PurchaseIntentResult实例对象。
  • 使用OnFailureListener可获取失败场景的相关信息,该场景返回一个IapApiException异常对象。

Sample code:

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. // 构造一个PurchaseIntentReq对象
  2. PurchaseIntentReq req = new PurchaseIntentReq();
  3. // 通过createPurchaseIntent接口购买的商品必须是您在AppGallery Connect网站配置的商品
  4. req.setProductId("CProduct1");
  5. // priceType: 0:消耗型商品; 1:非消耗型商品; 2:订阅型商品
  6. req.setPriceType(0);
  7. req.setDeveloperPayload("test");
  8. // 获取调用接口的Activity对象
  9. final Activity activity = getActivity();
  10. // 调用createPurchaseIntent接口创建PMS商品订单
  11. Task<PurchaseIntentResult> task = Iap.getIapClient(activity).createPurchaseIntent(req);
  12. task.addOnSuccessListener(new OnSuccessListener<PurchaseIntentResult>() {
  13. @Override
  14. public void onSuccess(PurchaseIntentResult result) {
  15. // 获取创建订单的结果
  16. // Status不支持序列化操作
  17. Status status = result.getStatus();
  18. if (status.hasResolution()) {
  19. try {
  20. // 6666是您自定义的常量
  21. // 启动IAP返回的收银台页面
  22. status.startResolutionForResult(activity, 6666);
  23. } catch (IntentSender.SendIntentException exp) {
  24. }
  25. }
  26. }
  27. }).addOnFailureListener(new OnFailureListener() {
  28. @Override
  29. public void onFailure(Exception e) {
  30. if (e instanceof IapApiException) {
  31. IapApiException apiException = (IapApiException) e;
  32. // Status不支持序列化操作
  33. Status status = apiException.getStatus();
  34. int returnCode = apiException.getStatusCode();
  35. } else {
  36. // 其他外部错误
  37. }
  38. }
  39. });
  40. @Override
  41. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  42. super.onActivityResult(requestCode, resultCode, data);
  43. if (requestCode == 6666) {
  44. if (data == null) {
  45. Log.e("onActivityResult", "data is null");
  46. return;
  47. }
  48. // 调用parsePurchaseResultInfoFromIntent方法解析支付结果数据
  49. PurchaseResultInfo purchaseResultInfo = Iap.getIapClient(this).parsePurchaseResultInfoFromIntent(data);
  50. switch(purchaseResultInfo.getReturnCode()) {
  51. case OrderStatusCode.ORDER_STATE_CANCEL:
  52. // 用户取消
  53. break;
  54. case OrderStatusCode.ORDER_STATE_FAILED:
  55. case OrderStatusCode.ORDER_PRODUCT_OWNED:
  56. // 检查是否存在未发货商品
  57. break;
  58. case OrderStatusCode.ORDER_STATE_SUCCESS:
  59. // 支付成功
  60. String inAppPurchaseData = purchaseResultInfo.getInAppPurchaseData();
  61. String inAppPurchaseDataSignature = purchaseResultInfo.getInAppDataSignature();
  62. // 使用您应用的IAP公钥验证签名
  63. // 若验签成功,必须校验InAppPurchaseData中的productId、price、currency等信息的一致性,验证一致后发货
  64. // 若用户购买商品为消耗型商品,您需要在发货成功后调用consumeOwnedPurchase接口进行消耗
  65. break;
  66. default:
  67. break;
  68. }
  69. }
  70. }
收起
自动换行
深色代码主题
复制
  1. // 构造一个PurchaseIntentReq对象
  2. val req = PurchaseIntentReq()
  3. // 通过createPurchaseIntent接口购买的商品必须是您在AppGallery Connect网站配置的商品
  4. req.setProductId("CProduct1")
  5. // priceType: 0:消耗型商品; 1:非消耗型商品; 2:订阅型商品
  6. req.setPriceType(0)
  7. req.setDeveloperPayload("test")
  8. // 获取调用接口的Activity对象
  9. val activity: Activity = getActivity()
  10. // 调用createPurchaseIntent接口创建PMS商品订单
  11. val task = Iap.getIapClient(activity).createPurchaseIntent(req)
  12. task.addOnSuccessListener { result ->
  13. // 获取创建订单的结果
  14. // Status不支持序列化操作
  15. val status: Status = result.status
  16. if (status.hasResolution()) {
  17. try {
  18. // 6666是您自定义的常量
  19. // 启动IAP返回的收银台页面
  20. status.startResolutionForResult(activity, 6666)
  21. } catch (exp: SendIntentException) {
  22. }
  23. }
  24. }.addOnFailureListener { e ->
  25. if (e is IapApiException) {
  26. val apiException = e as IapApiException
  27. // Status不支持序列化操作
  28. val status: Status = apiException.status
  29. val returnCode = apiException.statusCode
  30. } else {
  31. // 其他外部错误
  32. }
  33. }
  34. override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  35. super.onActivityResult(requestCode, resultCode, data)
  36. if (requestCode == 6666) {
  37. if (data == null) {
  38. Log.e("onActivityResult", "data is null")
  39. return
  40. }
  41. // 调用parsePurchaseResultInfoFromIntent方法解析支付结果数据
  42. val purchaseResultInfo = Iap.getIapClient(this).parsePurchaseResultInfoFromIntent(data)
  43. when (purchaseResultInfo.returnCode) {
  44. OrderStatusCode.ORDER_STATE_CANCEL -> {
  45. }
  46. OrderStatusCode.ORDER_STATE_FAILED, OrderStatusCode.ORDER_PRODUCT_OWNED -> {
  47. }
  48. OrderStatusCode.ORDER_STATE_SUCCESS -> {
  49. // 支付成功
  50. val inAppPurchaseData = purchaseResultInfo.inAppPurchaseData
  51. val inAppPurchaseDataSignature = purchaseResultInfo.inAppDataSignature
  52. }
  53. else -> {
  54. }
  55. }
  56. }
  57. }

createPurchaseIntentWithPrice

展开

Method

Task<PurchaseIntentResult> createPurchaseIntentWithPrice(PurchaseIntentWithPriceReq purchaseIntentWithPriceReq)

应用可以调用此接口自行传入商品价格并完成支付,而不是从IAP PMS获取价格。此接口不提供商品信息自动全球化能力,需要您在接口中指定价格、币种和国家/地区。

本接口只返回包含IAP收银台页面的Status对象,应用需要自行启动收银台页面,启动方法见PurchaseIntentResult中对Status的说明。用户完成支付后应用可以在onActivityResult回调方法中通过parsePurchaseResultInfoFromIntent获取支付结果信息。

注意
  • 为避免资金损失,您在对支付结果验签成功后,必须校验InAppPurchaseData中的productId、price、currency等信息的一致性。
  • Status不支持序列化,请勿对IAP接口返回的Status对象执行序列化操作。
说明
  • 本接口当前只支持仅在中国大陆地区发布的应用,发布中国大陆地区以外地区的应用必须使用createPurchaseIntent接口。
  • 本接口仅支持消耗型商品和非消耗型商品,不支持订阅型商品。
  • 本接口后续将不再更新维护,建议开发者替换成createPurchaseIntent接口,以免影响后续版本升级。

Parameters

展开

Name

Description

purchaseIntentWithPriceReq

包含请求信息的PurchaseIntentWithPriceReq对象。

Returns

展开

Type

Description

Task<PurchaseIntentResult>

Task设置回调监听可获取接口请求结果。

  • 使用OnSuccessListener可获取到成功场景返回的数据,该场景下返回一个PurchaseIntentResult实例对象。
  • 使用OnFailureListener可获取失败场景的相关信息,该场景返回一个IapApiException异常对象。

Sample code:

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. // 构造PurchaseIntentWithPriceReq对象
  2. PurchaseIntentWithPriceReq req = new PurchaseIntentWithPriceReq();
  3. req.setCurrency("CNY");
  4. req.setDeveloperPayload("test");
  5. // priceType: 0: 消耗型; 1: 非消耗型
  6. req.setPriceType(0);
  7. req.setSdkChannel("1");
  8. req.setProductName("test");
  9. req.setAmount("1.00");
  10. req.setProductId("ConsumableProduct1");
  11. req.setServiceCatalog("X38");
  12. req.setCountry("CN");
  13. // 获取调用接口的Activity对象
  14. final Activity activity = getActivity();
  15. // 调用createPurchaseIntentWithPrice接口
  16. Task<PurchaseIntentResult> task = Iap.getIapClient(activity).createPurchaseIntentWithPrice(req);
  17. task.addOnSuccessListener(new OnSuccessListener<PurchaseIntentResult>() {
  18. @Override
  19. public void onSuccess(PurchaseIntentResult result) {
  20. // 获取支付结果
  21. String paymentData = result.getPaymentData();
  22. String paymentSignature = result.getPaymentSignature();
  23. // 验证paymentData的签名
  24. String publicKey = "XXX";
  25. // CipherUtil为自定义类,需要自定义doCheck方法
  26. if (CipherUtil.doCheck(paymentData, paymentSignature, publicKey)) {
  27. // 如果成功,则启动请求返回的IAP收银台页面
  28. // Status不支持序列化操作
  29. Status status = result.getStatus();
  30. if (status.hasResolution()) {
  31. try {
  32. status.startResolutionForResult(activity, 6666);
  33. } catch (IntentSender.SendIntentException exp) {
  34. }
  35. }
  36. }
  37. }
  38. }).addOnFailureListener(new OnFailureListener() {
  39. @Override
  40. public void onFailure(Exception e) {
  41. if (e instanceof IapApiException) {
  42. IapApiException apiException = (IapApiException) e;
  43. int returnCode = apiException.getStatusCode();
  44. switch (returnCode) {
  45. case OrderStatusCode.ORDER_HWID_NOT_LOGIN:
  46. case OrderStatusCode.ORDER_NOT_ACCEPT_AGREEMENT:
  47. // 帐号未登录或用户不同意支付协议
  48. // Status不支持序列化操作
  49. Status status = apiException.getStatus();
  50. if (status != null && status.hasResolution()) {
  51. try {
  52. status.startResolutionForResult(activity, 8888);
  53. } catch (IntentSender.SendIntentException exp) {
  54. }
  55. }
  56. break;
  57. case OrderStatusCode.ORDER_PRODUCT_OWNED:
  58. // 检查是否存在未交付的商品
  59. break;
  60. default:
  61. break;
  62. }
  63. }
  64. }
  65. });
  66. // 支付结果回调
  67. @Override
  68. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  69. if (requestCode == 6666) {
  70. if (data == null) {
  71. Log.e("onActivityResult", "data is null");
  72. return;
  73. }
  74. PurchaseResultInfo purchaseResultInfo = Iap.getIapClient(this).parsePurchaseResultInfoFromIntent(data);
  75. switch(purchaseResultInfo.getReturnCode()) {
  76. case OrderStatusCode.ORDER_STATE_CANCEL:
  77. // 用户取消支付
  78. break;
  79. case OrderStatusCode.ORDER_STATE_FAILED:
  80. case OrderStatusCode.ORDER_STATE_DEFAULT_CODE:
  81. case OrderStatusCode.ORDER_PRODUCT_OWNED:
  82. // 检查是否存在未交付的商品
  83. break;
  84. case OrderStatusCode.ORDER_STATE_SUCCESS:
  85. // 支付成功
  86. String inAppPurchaseData = purchaseResultInfo.getInAppPurchaseData();
  87. String inAppPurchaseDataSignature = purchaseResultInfo.getInAppDataSignature();
  88. // 使用您应用的IAP公钥验证签名
  89. // 若验签成功,必须校验InAppPurchaseData中的productId、price、currency等信息的一致性,验证一致后发货
  90. // 若用户购买商品为消耗型商品,您需要在发货成功后调用consumeOwnedPurchase接口进行消耗
  91. break;
  92. default:
  93. break;
  94. }
  95. return;
  96. }
  97. if (requestCode == 8888) {
  98. int returnCode = IapClientHelper.parseRespCodeFromIntent(data);
  99. if (returnCode == OrderStatusCode.ORDER_STATE_SUCCESS) {
  100. // 请求成功,需要再次发起createPurchaseIntentWithPrice请求
  101. }
  102. return;
  103. }
  104. }
收起
自动换行
深色代码主题
复制
  1. // 构造PurchaseIntentWithPriceReq对象
  2. val req = PurchaseIntentWithPriceReq()
  3. req.setCurrency("CNY")
  4. req.setDeveloperPayload("test")
  5. // priceType: 0: 消耗型; 1: 非消耗型
  6. req.setPriceType(0)
  7. req.setSdkChannel("1")
  8. req.setProductName("test")
  9. req.setAmount("1.00")
  10. req.setProductId("ConsumableProduct1")
  11. req.setServiceCatalog("X38")
  12. req.setCountry("CN")
  13. // 获取调用接口的Activity对象
  14. val activity: Activity = getActivity()
  15. // 调用createPurchaseIntentWithPrice接口
  16. val task = Iap.getIapClient(activity).createPurchaseIntentWithPrice(req)
  17. task.addOnSuccessListener { result ->
  18. // 获取支付结果
  19. val paymentData = result.getPaymentData()
  20. val paymentSignature = result.getPaymentSignature()
  21. // 验证paymentData的签名
  22. val publicKey = "XXX"
  23. // CipherUtil为自定义类,需要自定义doCheck方法
  24. if (CipherUtil.doCheck(paymentData, paymentSignature, publicKey)) {
  25. // 如果成功,则启动请求返回的IAP收银台页面
  26. // Status不支持序列化操作
  27. val status: Status = result.status
  28. if (status.hasResolution()) {
  29. try {
  30. status.startResolutionForResult(activity, 6666)
  31. } catch (exp: SendIntentException) {
  32. }
  33. }
  34. }
  35. }.addOnFailureListener { e ->
  36. if (e is IapApiException) {
  37. val apiException = e as IapApiException
  38. val returnCode = apiException.statusCode
  39. when (returnCode) {
  40. OrderStatusCode.ORDER_HWID_NOT_LOGIN, OrderStatusCode.ORDER_NOT_ACCEPT_AGREEMENT -> {
  41. // 帐号未登录或用户不同意支付协议
  42. // Status不支持序列化操作
  43. val status: Status? = apiException.status
  44. if (status != null && status.hasResolution()) {
  45. try {
  46. status.startResolutionForResult(activity, 8888)
  47. } catch (exp: SendIntentException) {
  48. }
  49. }
  50. }
  51. OrderStatusCode.ORDER_PRODUCT_OWNED -> {
  52. }
  53. else -> {
  54. }
  55. }
  56. }
  57. }
  58. // 支付结果回调
  59. override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  60. if (requestCode == 6666) {
  61. if (data == null) {
  62. Log.e("onActivityResult", "data is null")
  63. return
  64. }
  65. val purchaseResultInfo = Iap.getIapClient(this).parsePurchaseResultInfoFromIntent(data)
  66. when (purchaseResultInfo.returnCode) {
  67. OrderStatusCode.ORDER_STATE_CANCEL -> {
  68. }
  69. OrderStatusCode.ORDER_STATE_FAILED, OrderStatusCode.ORDER_PRODUCT_OWNED, OrderStatusCode.ORDER_STATE_DEFAULT_CODE -> {
  70. }
  71. OrderStatusCode.ORDER_STATE_SUCCESS -> {
  72. // 支付成功
  73. val inAppPurchaseData = purchaseResultInfo.inAppPurchaseData
  74. val inAppPurchaseDataSignature = purchaseResultInfo.inAppDataSignature
  75. }
  76. else -> {
  77. }
  78. }
  79. return
  80. }
  81. if (requestCode == 8888) {
  82. val returnCode = IapClientHelper.parseRespCodeFromIntent(data)
  83. if (returnCode == OrderStatusCode.ORDER_STATE_SUCCESS) {
  84. // 请求成功,需要再次发起createPurchaseIntentWithPrice请求
  85. }
  86. return
  87. }
  88. }

enablePendingPurchase

展开

Method

void enablePendingPurchase()

用于使能延迟付款型支付。若要在您的应用中使用延迟付款型支付功能,需要在发起购买前调用本接口。建议您在应用启动时调用本接口。

说明
  • 仅手机/平板支持延迟付款型支付,其他设备类型不支持。
  • 仅使用createPurchaseIntent接口购买一次性商品场景支持延迟付款型支付,包括消耗型商品、非消耗型商品。

Sample code

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. // 获取调用接口的Activity对象
  2. Activity activity = getActivity();
  3. Iap.getIapClient(activity).enablePendingPurchase();
收起
自动换行
深色代码主题
复制
  1. // 获取调用接口的Activity对象
  2. val activity: Activity = getActivity()
  3. Iap.getIapClient(activity).enablePendingPurchase()

isEnvReady

展开

Method

Task<IsEnvReadyResult> isEnvReady()

通过该接口可以判断当前设备登录的帐号所在的服务国家/地区是否在华为IAP支付服务支持结算的国家/地区中。

Returns

展开

Type

Description

Task<IsEnvReadyResult>

Task设置回调监听可获取接口请求结果。

  • 使用OnSuccessListener可获取到成功场景返回的数据,该场景下返回一个IsEnvReadyResult实例对象。
  • 使用OnFailureListener可获取失败场景的相关信息,该场景返回一个IapApiException异常对象。

Sample code

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. // 获取调用接口的Activity对象
  2. final Activity activity = getActivity();
  3. Task<IsEnvReadyResult> task = Iap.getIapClient(activity).isEnvReady();
  4. task.addOnSuccessListener(new OnSuccessListener<IsEnvReadyResult>() {
  5. @Override
  6. public void onSuccess(IsEnvReadyResult result) {
  7. // 获取接口请求的结果
  8. String carrierId = result.getCarrierId();
  9. }
  10. }).addOnFailureListener(new OnFailureListener() {
  11. @Override
  12. public void onFailure(Exception e) {
  13. if (e instanceof IapApiException) {
  14. IapApiException apiException = (IapApiException) e;
  15. // Status不支持序列化操作
  16. Status status = apiException.getStatus();
  17. if (status.getStatusCode() == OrderStatusCode.ORDER_HWID_NOT_LOGIN) {
  18. // 未登录帐号
  19. if (status.hasResolution()) {
  20. try {
  21. // 6666是您自定义的常量
  22. // 启动IAP返回的登录页面
  23. status.startResolutionForResult(activity, 6666);
  24. } catch (IntentSender.SendIntentException exp) {
  25. }
  26. }
  27. } else if (status.getStatusCode() == OrderStatusCode.ORDER_ACCOUNT_AREA_NOT_SUPPORTED) {
  28. // 用户当前登录的华为帐号所在的服务地不在华为IAP支持结算的国家/地区中
  29. }
  30. } else {
  31. // 其他外部错误
  32. }
  33. }
  34. });
  35. @Override
  36. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  37. super.onActivityResult(requestCode, resultCode, data);
  38. if (requestCode == 6666) {
  39. if (data != null) {
  40. // 使用parseRespCodeFromIntent方法获取接口请求结果
  41. int returnCode = IapClientHelper.parseRespCodeFromIntent(data);
  42. }
  43. }
  44. }
收起
自动换行
深色代码主题
复制
  1. // 获取调用接口的Activity对象
  2. val activity: Activity = getActivity()
  3. val task = Iap.getIapClient(activity).isEnvReady
  4. task.addOnSuccessListener { result ->
  5. // 获取接口请求的结果
  6. val carrierId = result.carrierId
  7. }.addOnFailureListener { e ->
  8. if (e is IapApiException) {
  9. val apiException = e as IapApiException
  10. // Status不支持序列化操作
  11. val status: Status = apiException.status
  12. if (status.getStatusCode() === OrderStatusCode.ORDER_HWID_NOT_LOGIN) {
  13. // 未登录帐号
  14. if (status.hasResolution()) {
  15. try {
  16. // 6666是您自定义的常量
  17. // 启动IAP返回的登录页面
  18. status.startResolutionForResult(activity, 6666)
  19. } catch (exp: SendIntentException) {
  20. }
  21. }
  22. } else if (status.getStatusCode() === OrderStatusCode.ORDER_ACCOUNT_AREA_NOT_SUPPORTED) {
  23. // 用户当前登录的华为帐号所在的服务地不在华为IAP支持结算的国家/地区中
  24. }
  25. } else {
  26. // 其他外部错误
  27. }
  28. }
  29. override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  30. super.onActivityResult(requestCode, resultCode, data)
  31. if (requestCode == 6666) {
  32. if (data != null) {
  33. // 使用parseRespCodeFromIntent方法获取接口请求结果
  34. val returnCode = IapClientHelper.parseRespCodeFromIntent(data)
  35. }
  36. }
  37. }

isSandboxActivated

展开

Method

Task<IsSandboxActivatedResult> isSandboxActivated(IsSandboxActivatedReq isSandboxActivatedReq)

通过该接口可以判断当前设备登录的华为帐号及应用的APK版本是否满足沙盒条件。

Parameters

展开

Name

Description

isSandboxActivatedReq

包含请求信息的IsSandboxActivatedReq对象。

Return

展开

Type

Description

Task<IsSandboxActivatedResult>

Task设置回调监听可获取接口请求结果。

  • 使用OnSuccessListener可获取到成功场景返回的数据,该场景下返回一个IsSandboxActivatedResult实例对象。
  • 使用OnFailureListener可获取失败场景的相关信息,该场景返回一个IapApiException异常对象。

Sample code:

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. // 获取调用接口的Activity对象
  2. final Activity activity = getActivity();
  3. IapClient mClient = Iap.getIapClient(activity);
  4. Task<IsSandboxActivatedResult> task = mClient.isSandboxActivated(new IsSandboxActivatedReq());
  5. task.addOnSuccessListener(new OnSuccessListener<IsSandboxActivatedResult>() {
  6. @Override
  7. public void onSuccess(IsSandboxActivatedResult result) {
  8. Log.i("IAP", "isSandboxActivated success");
  9. }
  10. }).addOnFailureListener(new OnFailureListener() {
  11. @Override
  12. public void onFailure(Exception e) {
  13. Log.e("IAP", "isSandboxActivated fail");
  14. if (e instanceof IapApiException) {
  15. IapApiException apiException = (IapApiException) e;
  16. int returnCode = apiException.getStatusCode();
  17. } else {
  18. // 其他外部错误
  19. }
  20. }
  21. });
收起
自动换行
深色代码主题
复制
  1. // 获取调用接口的Activity对象
  2. val activity: Activity = getActivity()
  3. val mClient = Iap.getIapClient(activity)
  4. val task = mClient.isSandboxActivated(IsSandboxActivatedReq())
  5. task.addOnSuccessListener { result ->
  6. Log.i("IAP", "isSandboxActivated success")
  7. }.addOnFailureListener { e ->
  8. Log.e("IAP", "isSandboxActivated fail")
  9. if (e is IapApiException) {
  10. val apiException = e as IapApiException
  11. val returnCode = apiException.statusCode
  12. } else {
  13. // 其他外部错误
  14. }
  15. }

obtainOwnedPurchaseRecord

展开

Method

Task<OwnedPurchasesResult> obtainOwnedPurchaseRecord(OwnedPurchasesReq ownedPurchasesReq)

此接口用于获取消耗型商品的历史消耗商品信息或订阅型商品的所有订阅收据。

  • 若查询商品类型为消耗型商品,此接口将返回商品列表中执行过发货和消耗操作的商品购买数据。
  • 若查询商品类型为订阅型商品,此接口将返回当前用户在本应用中的所有订阅收据。
说明

此接口不会返回非消耗型商品的购买信息,您需使用obtainOwnedPurchases接口获取非消耗型商品的购买记录。

Parameters

展开

Name

Description

ownedPurchasesReq

包含请求信息的OwnedPurchasesReq对象。

Returns

展开

Type

Description

Task<OwnedPurchasesResult>

Task设置回调监听可获取接口请求结果。

  • 使用OnSuccessListener可获取到成功场景返回的数据,该场景下返回一个OwnedPurchasesResult实例对象。
  • 使用OnFailureListener可获取失败场景的相关信息,该场景返回一个IapApiException异常对象。

Sample code:

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. // 构造OwnedPurchasesReq对象
  2. OwnedPurchasesReq req = new OwnedPurchasesReq();
  3. // 0:消耗型商品; 2:订阅型商品
  4. req.setPriceType(0);
  5. // 获取调用接口的Activity对象
  6. final Activity activity = getActivity();
  7. // 调用obtainOwnedPurchaseRecord接口
  8. Task<OwnedPurchasesResult> task = Iap.getIapClient(activity).obtainOwnedPurchaseRecord(req);
  9. task.addOnSuccessListener(new OnSuccessListener<OwnedPurchasesResult>() {
  10. @Override
  11. public void onSuccess(OwnedPurchasesResult result) {
  12. // 获取接口请求成功时的结果信息
  13. }
  14. }).addOnFailureListener(new OnFailureListener() {
  15. @Override
  16. public void onFailure(Exception e) {
  17. if (e instanceof IapApiException) {
  18. IapApiException apiException = (IapApiException) e;
  19. int returnCode = apiException.getStatusCode();
  20. } else {
  21. // 其他外部错误
  22. }
  23. }
  24. });
收起
自动换行
深色代码主题
复制
  1. // 构造OwnedPurchasesReq对象
  2. val req = OwnedPurchasesReq()
  3. // 0:消耗型商品; 2:订阅型商品
  4. req.setPriceType(0)
  5. // 获取调用接口的Activity对象
  6. val activity: Activity = getActivity()
  7. // 调用obtainOwnedPurchaseRecord接口
  8. val task = Iap.getIapClient(activity).obtainOwnedPurchaseRecord(req)
  9. task.addOnSuccessListener {
  10. // 获取接口请求成功时的结果信息
  11. }.addOnFailureListener { e ->
  12. if (e is IapApiException) {
  13. val apiException = e as IapApiException
  14. val returnCode = apiException.statusCode
  15. } else {
  16. // 其他外部错误
  17. }
  18. }

obtainOwnedPurchases

展开

Method

Task<OwnedPurchasesResult> obtainOwnedPurchases(OwnedPurchasesReq ownedPurchasesReq)

查询用户已订购商品的购买数据,包括消耗型商品、非消耗型商品和订阅型商品,一次请求只能查询一种类型的商品。

  • 若查询消耗型商品,IAP仅返回用户已购未消耗的购买数据。若有购买数据返回,说明可能存在因某些异常而导致未进行发货的情况,需要应用判断是否已发货,未发货则需要进行补发货处理,并调用consumeOwnedPurchase接口进行消耗。消耗成功的订单信息将不会在此接口返回,可通过obtainOwnedPurchaseRecord接口获取。
注意

如果您在消耗之后再进行发货,可能存在以下异常场景:调用消耗接口过程中,服务器消耗成功但因网络异常等原因没有成功将结果回调给端侧,从而造成服务器已经消耗但是端侧没有发货的场景。此场景后续很难处理,您需在发货成功之后再执行消耗操作。

  • 若查询非消耗型商品,IAP返回用户所有已订购商品的购买数据。
  • 若查询订阅型商品,IAP仅返回用户在当前应用下正生效的订阅关系,包括以下几种订阅关系:
    • 续期(正常使用,下周期会续费)。
    • 到期(下一周期不再续费,这个周期过后就变成已到期)。
    • 宽限期(宽限期内继续尝试扣费,扣费成功则进入续期状态,扣费失败则宽限期结束后变成已到期)。

Parameters

展开

Name

Description

ownedPurchasesReq

包含请求信息的OwnedPurchasesReq对象。

Returns

展开

Type

Description

Task<OwnedPurchasesResult>

Task设置回调监听可获取接口请求结果。

  • 使用OnSuccessListener可获取到成功场景返回的数据,该场景下返回一个OwnedPurchasesResult实例对象。
  • 使用OnFailureListener可获取失败场景的相关信息,该场景返回一个IapApiException异常对象。

Sample code:

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. // 构造一个OwnedPurchasesReq对象
  2. OwnedPurchasesReq ownedPurchasesReq = new OwnedPurchasesReq();
  3. // priceType: 0:消耗型商品; 1:非消耗型商品; 2:订阅型商品
  4. ownedPurchasesReq.setPriceType(0);
  5. // 获取调用接口的Activity对象
  6. final Activity activity = getActivity();
  7. // 调用obtainOwnedPurchases接口获取所有已购但未发货的消耗型商品
  8. Task<OwnedPurchasesResult> task = Iap.getIapClient(activity).obtainOwnedPurchases(ownedPurchasesReq);
  9. task.addOnSuccessListener(new OnSuccessListener<OwnedPurchasesResult>() {
  10. @Override
  11. public void onSuccess(OwnedPurchasesResult result) {
  12. // 获取执行结果
  13. if (result != null && result.getInAppPurchaseDataList() != null) {
  14. for (int i = 0; i < result.getInAppPurchaseDataList().size(); i++) {
  15. String inAppPurchaseData = result.getInAppPurchaseDataList().get(i);
  16. String InAppSignature = result.getInAppSignature().get(i);
  17. // 使用您应用的IAP公钥验证签名
  18. // 如果验签成功,确认每个商品的购买状态。确认商品已支付后,检查此前是否已发过货,未发货则进行发货操作。发货成功后执行消耗操作
  19. try {
  20. InAppPurchaseData inAppPurchaseDataBean = new InAppPurchaseData(inAppPurchaseData);
  21. int purchaseState = inAppPurchaseDataBean.getPurchaseState();
  22. } catch (JSONException e) {
  23. }
  24. }
  25. }
  26. }
  27. }).addOnFailureListener(new OnFailureListener() {
  28. @Override
  29. public void onFailure(Exception e) {
  30. if (e instanceof IapApiException) {
  31. IapApiException apiException = (IapApiException) e;
  32. Status status = apiException.getStatus();
  33. int returnCode = apiException.getStatusCode();
  34. } else {
  35. // 其他外部错误
  36. }
  37. }
  38. });
收起
自动换行
深色代码主题
复制
  1. // 构造一个OwnedPurchasesReq对象
  2. val ownedPurchasesReq = OwnedPurchasesReq()
  3. // priceType: 0:消耗型商品; 1:非消耗型商品; 2:订阅型商品
  4. ownedPurchasesReq.setPriceType(0)
  5. // 获取调用接口的Activity对象
  6. val activity: Activity = getActivity()
  7. // 调用obtainOwnedPurchases接口获取所有已购但未发货的消耗型商品
  8. val task = Iap.getIapClient(activity).obtainOwnedPurchases(ownedPurchasesReq)
  9. task.addOnSuccessListener { result ->
  10. // 获取执行结果
  11. if (result != null && result.getInAppPurchaseDataList() != null) {
  12. for (i in result.getInAppPurchaseDataList().indices) {
  13. val inAppPurchaseData = result.getInAppPurchaseDataList()[i]
  14. val InAppSignature = result.getInAppSignature()[i]
  15. // 使用您应用的IAP公钥验证签名
  16. // 如果验签成功,确认每个商品的购买状态。确认商品已支付后,检查此前是否已发过货,未发货则进行发货操作。发货成功后执行消耗操作
  17. try {
  18. val inAppPurchaseDataBean = InAppPurchaseData(inAppPurchaseData)
  19. val purchaseState = inAppPurchaseDataBean.purchaseState
  20. } catch (e: JSONException) {
  21. }
  22. }
  23. }
  24. }.addOnFailureListener { e ->
  25. if (e is IapApiException) {
  26. val apiException = e as IapApiException
  27. val status: Status = apiException.status
  28. val returnCode = apiException.statusCode
  29. } else {
  30. // 其他外部错误
  31. }
  32. }

obtainProductInfo

展开

Method

Task<ProductInfoResult> obtainProductInfo(ProductInfoReq productInfoReq)

此接口用于获取在AppGallery Connect配置的商品详情。如果您使用了华为PMS系统进行商品定价,可通过此接口从华为PMS获取商品详情,以保证和华为支付收银台显示的商品信息一致。

说明

请您避免从自有服务端获取商品信息,否则可能导致应用内商品价格和收银台价格不一致。

Parameters

展开

Name

Description

productInfoReq

包含请求信息的ProductInfoReq对象。

Returns

展开

Type

Description

Task<ProductInfoResult>

Task设置回调监听可获取接口请求结果。

  • 使用OnSuccessListener可获取到成功场景返回的数据,该场景下返回一个ProductInfoResult实例对象。
  • 使用OnFailureListener可获取失败场景的相关信息,该场景返回一个IapApiException异常对象。

Sample code:

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. List<String> productIdList = new ArrayList<>();
  2. // 查询的商品必须是您在AppGallery Connect网站配置的商品
  3. productIdList.add("ConsumeProduct1001");
  4. ProductInfoReq req = new ProductInfoReq();
  5. // priceType: 0:消耗型商品; 1:非消耗型商品; 2:订阅型商品
  6. req.setPriceType(0);
  7. req.setProductIds(productIdList);
  8. // 获取调用接口的Activity对象
  9. final Activity activity = getActivity();
  10. // 调用obtainProductInfo接口获取AppGallery Connect网站配置的商品的详情信息
  11. Task<ProductInfoResult> task = Iap.getIapClient(activity).obtainProductInfo(req);
  12. task.addOnSuccessListener(new OnSuccessListener<ProductInfoResult>() {
  13. @Override
  14. public void onSuccess(ProductInfoResult result) {
  15. // 获取接口请求成功时返回的商品详情信息
  16. List<ProductInfo> productList = result.getProductInfoList();
  17. }
  18. }).addOnFailureListener(new OnFailureListener() {
  19. @Override
  20. public void onFailure(Exception e) {
  21. if (e instanceof IapApiException) {
  22. IapApiException apiException = (IapApiException) e;
  23. int returnCode = apiException.getStatusCode();
  24. } else {
  25. // 其他外部错误
  26. }
  27. }
  28. });
收起
自动换行
深色代码主题
复制
  1. val productIdList: MutableList<String> = ArrayList()
  2. // 查询的商品必须是您在AppGallery Connect网站配置的商品
  3. productIdList.add("ConsumeProduct1001")
  4. val req = ProductInfoReq()
  5. // priceType: 0:消耗型商品; 1:非消耗型商品; 2:订阅型商品
  6. req.setPriceType(0)
  7. req.productIds = productIdList
  8. // 获取调用接口的Activity对象
  9. val activity: Activity = getActivity()
  10. // 调用obtainProductInfo接口获取AppGallery Connect网站配置的商品的详情信息
  11. val task = Iap.getIapClient(activity).obtainProductInfo(req)
  12. task.addOnSuccessListener { result ->
  13. // 获取接口请求成功时返回的商品详情信息
  14. val productList = result.getProductInfoList()
  15. }.addOnFailureListener { e ->
  16. if (e is IapApiException) {
  17. val apiException = e as IapApiException
  18. val returnCode = apiException.statusCode
  19. } else {
  20. // 其他外部错误
  21. }
  22. }

parsePurchaseResultInfoFromIntent

展开

Method

PurchaseResultInfo parsePurchaseResultInfoFromIntent(Intent intent)

调用createPurchaseIntent接口成功并拉起页面后,会通过Activity的onActivityResult方法回调支付结果,可用此方法解析支付结果数据,结果返回一个PurchaseResultInfo对象。

Parameters

展开

Name

Description

intent

包含支付结果信息的Intent对象。

Returns

展开

Type

Description

PurchaseResultInfo

包含支付结果信息的对象。

Sample code:

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. // 支付结果在拉起IAP页面的Activity对象的onActivityResult方法中返回
  2. @Override
  3. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  4. PurchaseResultInfo purchaseResultInfo = Iap.getIapClient(this).parsePurchaseResultInfoFromIntent(data);
  5. }
收起
自动换行
深色代码主题
复制
  1. // 支付结果在拉起IAP页面的Activity对象的onActivityResult方法中返回
  2. override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  3. val purchaseResultInfo = Iap.getIapClient(this).parsePurchaseResultInfoFromIntent(data)
  4. }

startIapActivity

展开

Method

Task<StartIapActivityResult> startIapActivity(StartIapActivityReq startIapActivityReq)

可用此方法拉起华为应用内支付的相关页面,包括:

  • 编辑订阅页
  • 管理订阅页
说明

IAP SDK 4.0.4.300版本增加此方法,用于替换之前版本提供的订阅管理页面跳转方法。

Parameters

展开

Name

Description

startIapActivityReq

包含请求信息的StartIapActivityReq对象。

Returns

展开

Type

Description

Task<StartIapActivityResult>

Task设置回调监听可获取接口请求结果。

  • 使用OnSuccessListener可获取到成功场景返回的数据,该场景下返回一个StartIapActivityResult实例对象。
  • 使用OnFailureListener可获取失败场景的相关信息,该场景返回一个IapApiException异常对象。

Sample code:

Java
Kotlin
收起
自动换行
深色代码主题
复制
  1. // 跳转到订阅管理页
  2. StartIapActivityReq req = new StartIapActivityReq();
  3. req.setType(StartIapActivityReq.TYPE_SUBSCRIBE_MANAGER_ACTIVITY);
  4. // 获取调用接口的Activity对象
  5. final Activity activity = getActivity();
  6. IapClient mClient = Iap.getIapClient(activity);
  7. Task<StartIapActivityResult> task = mClient.startIapActivity(req);
  8. task.addOnSuccessListener(new OnSuccessListener<StartIapActivityResult>() {
  9. @Override
  10. public void onSuccess(StartIapActivityResult result) {
  11. Log.i("startIapActivity", "onSuccess");
  12. if (result != null) {
  13. result.startActivity(activity);
  14. }
  15. }
  16. }).addOnFailureListener(new OnFailureListener() {
  17. @Override
  18. public void onFailure(Exception e) {
  19. Log.e("startIapActivity", "onFailure");
  20. }
  21. });
  22. // 跳转到订阅编辑页
  23. StartIapActivityReq req = new StartIapActivityReq();
  24. req.setSubscribeProductId("XXX");
  25. req.setType(StartIapActivityReq.TYPE_SUBSCRIBE_EDIT_ACTIVITY);
  26. // 获取调用接口的Activity对象
  27. final Activity activity = getActivity();
  28. IapClient mClient = Iap.getIapClient(activity);
  29. Task<StartIapActivityResult> task = mClient.startIapActivity(req);
  30. task.addOnSuccessListener(new OnSuccessListener<StartIapActivityResult>() {
  31. @Override
  32. public void onSuccess(StartIapActivityResult result) {
  33. Log.i("startIapActivity", "onSuccess");
  34. if (result != null) {
  35. result.startActivity(activity);
  36. }
  37. }
  38. }).addOnFailureListener(new OnFailureListener() {
  39. @Override
  40. public void onFailure(Exception e) {
  41. Log.e("startIapActivity", "onFailure");
  42. }
  43. });
收起
自动换行
深色代码主题
复制
  1. // 跳转到订阅管理页
  2. val req = StartIapActivityReq()
  3. req.setType(StartIapActivityReq.TYPE_SUBSCRIBE_MANAGER_ACTIVITY)
  4. // 获取调用接口的Activity对象
  5. val activity: Activity = getActivity()
  6. val mClient = Iap.getIapClient(activity)
  7. val task = mClient.startIapActivity(req)
  8. task.addOnSuccessListener { result ->
  9. Log.i("startIapActivity", "onSuccess")
  10. result?.startActivity(activity)
  11. }.addOnFailureListener { Log.e("startIapActivity", "onFailure") }
  12. // 跳转到订阅编辑页
  13. val req = StartIapActivityReq()
  14. req.setSubscribeProductId("XXX")
  15. req.setType(StartIapActivityReq.TYPE_SUBSCRIBE_EDIT_ACTIVITY)
  16. // 获取调用接口的Activity对象
  17. val activity: Activity = getActivity()
  18. val mClient = Iap.getIapClient(activity)
  19. val task = mClient.startIapActivity(req)
  20. task.addOnSuccessListener { result ->
  21. Log.i("startIapActivity", "onSuccess")
  22. result?.startActivity(activity)
  23. }.addOnFailureListener { Log.e("startIapActivity", "onFailure") }
在 API参考 中进行搜索
请输入您想要搜索的关键词