ETJava Beta | Java    注册   登录
  • 搜索:
  • 打造一站式应用内支付体验,助力开发者商业增长

    发表于      阅读(1)     博客类别:Crawler     转自:https://www.cnblogs.com/HarmonyOSSDK/p/18451910
    如有侵权 请联系我们删除  (页面底部联系我们)  

    随着移动互联网的发展,应用内支付已成为数字经济的重要组成部分。用户越来越追求便捷的支付体验,应用内支付服务提供的购买和订阅等能力满足了用户快速、无缝的支付需求,方便用户一站式完成交易,帮助开发者实现收入多元化。

    HarmonyOS SDK应用内支付服务(IAP Kit)为用户精心打造了一种流畅且高效的应用内支付体验,同时为开发者提供了便捷快速的接入指南。开发者能够将更多的精力投入到提升应用核心业务的质量和创新上,进而促进商业价值的实现和增长。

    通过集成应用内支付服务所提供的系统级API,开发者可以迅速部署一个功能完备的支付平台,无缝地实现应用内购买功能。用户可以在应用内轻松购买一系列虚拟商品,种类丰富,包括但不限于一次性使用的消耗品、长期使用的非消耗品,以及提供持续价值的自动续期订阅服务等等。本文重点带开发者了解如何接入购买消耗型/非消耗型商品

    image

    场景介绍

    通过应用内支付服务,用户可以在应用内购买各种类型的虚拟商品,包括消耗型商品、非消耗型商品和自动续期订阅商品。

    •消耗型商品:使用一次后即消耗掉,随使用减少,需要再次购买的商品。例:游戏货币,游戏道具等。

    •非消耗型商品:一次性购买,永久拥有,无需消耗。例:游戏中额外的游戏关卡、应用中无时限的高级会员等。

    •自动续期订阅商品:用户购买后在一段时间内允许访问增值功能或内容,周期结束后可以选择自动续期购买下一期的服务。例:视频连续包月会员。

    购买消耗型/非消耗型商品接入流程

    在接入消耗型/非消耗型商品购买能力前,需在华为AppGallery Connect网站配置商品,录入商品ID和商品价格等信息。用户在开发者应用内发起购买时,应用需要调用createPurchase接口来拉起IAP Kit收银台,收银台会展示商品名称、商品价格等信息,用户可在收银台完成商品购买。

    image

    开发步骤

    1.判断当前登录的华为账号所在的服务地是否支持应用内支付。

    在使用应用内支付之前,应用需要向IAP Kit发送queryEnvironmentStatus请求,以此判断用户当前登录的华为账号所在的服务地是否在IAP Kit支持结算的国家/地区中。

    import { iap } from '@kit.IAPKit';
    import { common } from '@kit.AbilityKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    queryEnvironmentStatus() {
      const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
      iap.queryEnvironmentStatus(context).then(() => {
        // 请求成功
        console.info('Succeeded in querying environment status.');
      }).catch((err: BusinessError) => {
        // 请求失败
        console.error(`Failed to query environment status. Code is ${err.code}, message is ${err.message}`);
      });
    }
    }
    

    2.查询商品信息

    通过queryProducts来获取在AppGallery Connect上配置的商品信息。发起请求时,需在请求参数QueryProductsParameter中携带相关的商品ID,并根据实际配置指定其productType。

    当接口请求成功时,IAP Kit将返回商品信息Product的列表。应用可以使用Product包含的商品价格、名称和描述等信息,向用户展示可供购买的商品列表。

    import { iap } from '@kit.IAPKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    queryProducts() {
      const queryProductParam: iap.QueryProductsParameter = {
        // iap.ProductType.CONSUMABLE:消耗型商品;
        // iap.ProductType.NONCONSUMABLE:非消耗型商品;
        productType: iap.ProductType.CONSUMABLE,
        // 查询的商品必须是开发者在AppGallery Connect网站配置的商品
        productIds: ['ohos_consume_001']
      };
      const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
      iap.queryProducts(context, queryProductParam).then((result) => {
        // 请求成功
        console.info('Succeeded in querying products.');
        // 展示商品信息
        // ...
      }).catch((err: BusinessError) => {
        // 请求失败
        console.error(`Failed to query products. Code is ${err.code}, message is ${err.message}`);
      });
    }
    

    3.发起购买

    用户发起购买时,应用可通过向IAP Kit发送createPurchase请求来拉起IAP Kit收银台。发起请求时,需在请求参数PurchaseParameter中携带此前已在华为AppGallery Connect网站上配置并生效的商品ID,并根据实际配置指定其productType。

    当用户购买成功时,应用将接收到一个CreatePurchaseResult对象,其purchaseData字段包括了此次购买的结果信息。可参见对返回结果验签对purchaseData.jwsPurchaseOrder进行解码验签,验证成功可得到PurchaseOrderPayload的JSON字符串。

    当用户购买失败时,需要针对code为iap.IAPErrorCode.PRODUCT_OWNEDiap.IAPErrorCode.SYSTEM_ERROR的场景,检查是否需要补发货,确保权益发放,具体请参见权益发放

    import { iap } from '@kit.IAPKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    // JWTUtil为自定义类,可参见Sample Code工程。
    import { JWTUtil } from '../commom/JWTUtil';
    
    createPurchase() {
      const createPurchaseParam: iap.PurchaseParameter = {
        // 购买的商品必须是开发者在AppGallery Connect网站配置的商品
        productId: 'ohos_consume_001',
        // iap.ProductType.CONSUMABLE:消耗型商品;
        // iap.ProductType.NONCONSUMABLE:非消耗型商品;
        productType: iap.ProductType.CONSUMABLE
      }
      const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
      iap.createPurchase(context, createPurchaseParam).then(async (result) => {
        console.info('Succeeded in creating purchase.');
        const jwsPurchaseOrder: string = JSON.parse(result.purchaseData).jwsPurchaseOrder;
        const purchaseStr = JWTUtil.decodeJwtObj(jwsPurchaseOrder);
        // 需自定义PurchaseOrderPayload类,包含的信息请参见PurchaseOrderPayload
        const purchaseOrderPayload = JSON.parse(purchaseStr) as PurchaseOrderPayload;
        // 处理发货
        // ...
        // 发货成功后向IAP Kit发送finishPurchase请求,确认发货,完成购买
        // finishPurchase请求的参数来源于purchaseOrderPayload
        // ...
      }).catch((err: BusinessError) => {
        // 请求失败
        console.error(`Failed to create purchase. Code is ${err.code}, message is ${err.message}`);
        if (err.code === iap.IAPErrorCode.PRODUCT_OWNED || err.code === iap.IAPErrorCode.SYSTEM_ERROR) {
          // 参见权益发放检查是否需要补发货,确保权益发放
          // ...
        }
      })
    }
    

    4.完成购买

    对PurchaseData.jwsPurchaseOrder解码验签成功后,如果PurchaseOrderPayload.purchaseOrderRevocationReasonCode为空,则代表购买成功,即可发放相关权益。如果开发者同时接入了服务端关键事件通知,为了避免重复发货,建议先检查此笔订单是否已发货,未发货再发放相关权益。发货成功后记录PurchaseOrderPayload等信息,用于后续检查是否已发货。

    发货成功后,应用需要发送finishPurchase请求确认发货,以此通知IAP服务器更新商品的发货状态,完成购买流程。发送finishPurchase请求时,需在请求参数FinishPurchaseParameter中携带PurchaseOrderPayload中的productType、purchaseToken、purchaseOrderId。请求成功后,IAP服务器会将相应商品标记为已发货。

    对于消耗型商品,应用成功执行finishPurchase之后,IAP服务器会将相应商品重新设置为可购买状态,用户即可再次购买该商品。

    import { iap } from '@kit.IAPKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    /**
     * 确认发货,完成购买
     *
     * @param purchaseOrder 购买数据,来源于购买请求
     */
    finishPurchase(purchaseOrder: PurchaseOrderPayload) {
      const finishPurchaseParam: iap.FinishPurchaseParameter = {
        productType: purchaseOrder.productType,
        purchaseToken: purchaseOrder.purchaseToken,
        purchaseOrderId: purchaseOrder.purchaseOrderId
      };
      const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
      iap.finishPurchase(context, finishPurchaseParam).then((result) => {
        // 请求成功
        console.info('Succeeded in finishing purchase.');
      }).catch((err: BusinessError) => {
        // 请求失败
        console.error(`Failed to finish purchase. Code is ${err.code}, message is ${err.message}`);
      });
    }
    

    了解更多详情>>

    访问应用内支付服务联盟官网

    获取接入购买消耗型/非消耗型商品开发指导文档

    获取权益发放开发指导文档