HarmonyOS掌上记账APP开发实践第63篇:鸿蒙 IAP 商品配置与管理 — 从订阅商品到权益验证
2026/7/22 1:44:34 网站建设 项目流程

鸿蒙 IAP 商品配置与管理 — 从订阅商品到权益验证

文章简介

HarmonyOS 应用内支付(IAP,In-App Purchases)是鸿蒙生态中实现应用商业化的核心能力。MoneyTrack 作为一款记账应用,提供了会员订阅功能,允许用户购买自动续费订阅商品以解锁高级特性。本文从 IAP 商品配置的角度出发,详细介绍商品从 AGC 配置到客户端查询、本地缓存的完整链路,帮助开发者理解鸿蒙 IAP 商品管理的全流程。

核心知识点

1. IAP 商品配置完整流程

IAP 商品配置涉及三个关键环节:AppGallery Connect 后台配置、客户端 SDK 查询、本地缓存管理。以下流程图展示了完整链路:

AGC 控制台配置商品

配置商品 ID/价格/描述

发布应用版本

客户端 iap.create 初始化

调用 getProducts 查询商品

查询成功?

解析 iap.Product 列表

读取本地缓存商品

缓存商品信息到本地

渲染会员商品列表

用户点击购买

发起 createPurchase

2. iap.Product 的完整字段说明

鸿蒙 IAP 的iap.Product接口定义了商品的完整信息,开发者可通过这些字段向用户展示统一的商品信息界面:

字段类型说明
productIdstring商品唯一标识,需与 AGC 后台一致
pricestring格式化后的价格字符串,如 “¥6.00”
microPricenumber价格微单位,单位为分(1 元 = 100)
descriptionstring商品描述文本,支持多语言
titlestring商品名称标题
typeProductType商品类型:CONSUMABLE / NONCONSUMABLE / AUTORENEWABLE
statusProductStatus商品状态:ACTIVE / INACTIVE
subPeriodstring订阅周期描述,仅 AUTORENEWABLE 类型有效

在 MoneyTrack 中,ProductInfo类封装了 IAP 商品与本地权益模型的映射关系,确保商品信息在 UI 层以统一格式展示:

export class ProductInfo { type: iap.ProductType = iap?.ProductType.AUTORENEWABLE; productId: string = ''; privileges: MemberShipPrivilege[] = []; privacyName?: string = ''; privacyContent?: string = ''; }

3. 商品价格格式化

不同地区的用户看到的货币符号不同,鸿蒙 IAP SDK 已自动处理本地化格式。iap.Product.price返回的字符串已包含正确的货币符号和格式,开发者可直接用于 UI 展示。如果需要在本地自行格式化,可参照以下逻辑:

function formatPrice(microPrice: number, currency: string): string { const price = (microPrice / 100).toFixed(2); // 根据 currency 添加对应货币符号 const symbolMap: Record<string, string> = { 'CNY': '¥', 'USD': '$', 'JPY': '¥', 'EUR': '€', }; return `${symbolMap[currency] || ''}${price}`; }

4. 商品缓存策略

为了避免频繁调用 IAP SDK 查询商品列表(网络请求耗时且可能失败),MoneyTrack 采用「先缓存、兜底读」的策略。首次查询成功后,将商品信息序列化后写入本地首选项(Preferences),后续启动时先读缓存展示,再异步刷新:

// 商品缓存管理 async function cacheProducts(products: iap.Product[]): Promise<void> { const prefs = await preferences.getPreferences(getContext(), 'iap_cache'); const json = JSON.stringify(products.map(p => ({ productId: p.productId, price: p.price, title: p.title, description: p.description, }))); await prefs.put('products', json); await prefs.flush(); } async function getCachedProducts(): Promise<iap.Product[] | null> { const prefs = await preferences.getPreferences(getContext(), 'iap_cache'); const json = await prefs.get('products', ''); return json ? JSON.parse(json) : null; }

项目代码案例

MemberShipVM 的完整商品管理代码

MemberShipVM 是会员模块的核心 ViewModel,管理商品列表的查询、缓存和购买入口。其productInfoList: iap.Product[]属性存储 IAP SDK 查询返回的商品信息,视图层据此渲染会员卡片:

@ObservedV2 export class MemberShipVM { @Trace productInfoList: iap.Product[] = []; @Trace isMember: boolean = false; @Trace expiresTime: number = 0; // 查询 IAP 商品并缓存 async queryProducts(): Promise<void> { try { const products = await iap.getProducts(['membership_monthly', 'membership_yearly']); this.productInfoList = products; await cacheProducts(products); } catch (err) { hilog.error(0xFF00, 'MemberShipVM', `queryProducts err: ${JSON.stringify(err)}`); // 兜底:读取本地缓存 const cached = await getCachedProducts(); if (cached) this.productInfoList = cached; } } // 发起购买 buyProduct(productId: string, type: iap.ProductType): void { // 购买前可加入安全环境检测 iap.createPurchase({ productId, type, subscribeCallBack: (params: iap.PurchaseParams) => { if (params.finishStatus === iap.FinishStatus.FINISHED) { // 支付成功,进行服务端验证 this.handlePurchaseSuccess(params); } }, }); } private async handlePurchaseSuccess(params: iap.PurchaseParams): Promise<void> { // 将收据解码后发送至服务端验证 const payload = JWSUtil.decodeJwsObj(params.receipt); await UserApis.subscribeMembership({ receipt: payload }); } }

最佳实践

  • 商品 ID 命名规范:建议采用功能_类型_周期格式,如membership_autorenewable_monthly,便于后期扩展多商品。
  • 缓存兜底策略:网络异常时从本地缓存读取商品信息,保证页面不白屏。同时设置缓存过期时间(如 24 小时)。
  • 价格展示一致性:直接使用 IAP SDK 返回的price字段,不做额外格式化,避免汇率和本地化问题。
  • 商品状态校验:每次展示商品前检查status字段,避免显示已下架商品。

推荐参考文档

  • HarmonyOS IAP Kit 开发指南
  • AppGallery Connect IAP 商品配置文档
  • @kit.IAPKit API 参考
  • 鸿蒙首选项(Preferences)数据存储指南

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询