打造一站式應用內購買體驗,助力開發者商業增長

HarmonyOS_SDK發表於2024-10-08

隨著移動網際網路的發展,應用內購買已成為數字經濟的重要組成部分。使用者越來越追求便捷的支付體驗,應用內購買服務提供的購買和訂閱等能力滿足了使用者快速、無縫的支付需求,方便使用者一站式完成交易,幫助開發者實現收入多元化。

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}`);
  });
}

瞭解更多詳情>>

訪問應用內購買服務聯盟官網

獲取接入購買消耗型/非消耗型商品開發指導文件

獲取權益發放開發指導文件

相關文章