鸿蒙flutter第三方库适配 - 应用内购买演示应用
运行效果图应用内购买演示是一款展示完整购买流程的示例应用,帮助开发者了解和掌握应用内购买的实现方式。应用展示了消耗品、非消耗品、订阅三种商品类型的购买流程,包含商品展示、购买验证、购买记录管理、恢复购买等完整功能。用户可以体验真实的购买交互流程,了解应用内购买的最佳实践。应用以优雅的紫色为主色调,象征尊贵与品质。涵盖商店、我的、记录、设置四大模块。用户可以浏览商品、完成购买、查看记录、管理设置,体
应用内购买演示应用
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
适配的第三方库地址:
- shared_preferences - 数据存储
- local_auth - 生物认证
- intl - 日期格式化
一、项目概述
运行效果图







1.1 应用简介
应用内购买演示是一款展示完整购买流程的示例应用,帮助开发者了解和掌握应用内购买的实现方式。应用展示了消耗品、非消耗品、订阅三种商品类型的购买流程,包含商品展示、购买验证、购买记录管理、恢复购买等完整功能。用户可以体验真实的购买交互流程,了解应用内购买的最佳实践。
应用以优雅的紫色为主色调,象征尊贵与品质。涵盖商店、我的、记录、设置四大模块。用户可以浏览商品、完成购买、查看记录、管理设置,体验完整的应用内购买流程。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 商品展示 | 展示可购买的商品列表 | 列表组件 |
| 商品分类 | 消耗品、非消耗品、订阅 | 分类展示 |
| 购买流程 | 完整的购买交互流程 | 模拟购买 |
| 生物认证 | 购买前指纹/面容验证 | local_auth |
| 购买记录 | 查看历史购买记录 | 本地存储 |
| 恢复购买 | 恢复已购买的项目 | 数据恢复 |
| 我的物品 | 查看已拥有的物品 | 状态管理 |
| 购买动画 | 流畅的购买交互动画 | AnimationController |
1.3 商品类型定义
| 序号 | 类型名称 | 描述 | 特点 |
|---|---|---|---|
| 1 | 消耗品 | 可重复购买的商品 | 如金币、道具,购买后数量增加 |
| 2 | 非消耗品 | 一次购买永久拥有 | 如去广告、主题包,购买后标记已拥有 |
| 3 | 订阅 | 按周期付费的服务 | 如VIP会员,有有效期限制 |
1.4 购买状态定义
| 序号 | 状态名称 | 描述 | 颜色 |
|---|---|---|---|
| 1 | 处理中 | 购买请求处理中 | 橙色 |
| 2 | 已完成 | 购买成功完成 | 绿色 |
| 3 | 失败 | 购买失败 | 红色 |
| 4 | 已恢复 | 购买记录已恢复 | 蓝色 |
| 5 | 已取消 | 用户取消购买 | 灰色 |
1.5 商品信息字段
| 序号 | 字段名称 | 是否必填 | 说明 |
|---|---|---|---|
| 1 | 商品ID | ✅ | 唯一标识符 |
| 2 | 商品名称 | ✅ | 显示名称 |
| 3 | 商品描述 | ✅ | 详细描述 |
| 4 | 价格 | ✅ | 商品价格 |
| 5 | 货币符号 | 可选 | 默认为¥ |
| 6 | 商品类型 | ✅ | 消耗品/非消耗品/订阅 |
| 7 | 图标 | 可选 | 商品图标 |
| 8 | 是否热门 | 可选 | 标记热门商品 |
| 9 | 折扣信息 | 可选 | 显示折扣标签 |
1.6 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 数据存储 | shared_preferences | >= 2.2.2 |
| 生物认证 | local_auth | >= 2.3.0 |
| 日期格式 | intl | >= 0.19.0 |
| 目标平台 | 鸿蒙OS / Android / iOS | API 21+ |
1.7 项目结构
lib/
└── main_in_app_purchase.dart
├── InAppPurchaseDemoApp # 应用入口
├── ProductType # 商品类型枚举
├── PurchaseStatus # 购买状态枚举
├── Product # 商品模型
├── PurchaseRecord # 购买记录模型
├── InAppPurchaseHomePage # 主页面(底部导航)
├── _buildStorePage # 商店页面
├── _buildProductsPage # 我的物品页
├── _buildHistoryPage # 购买记录页
├── _buildSettingsPage # 设置页
├── _purchaseProduct # 购买商品
└── _restorePurchases # 恢复购买
二、系统架构
2.1 整体架构图
2.2 类图设计
2.3 页面导航流程
2.4 购买流程
三、核心模块设计
3.1 数据模型设计
3.1.1 商品类型枚举 (ProductType)
enum ProductType {
consumable(label: '消耗品', description: '可重复购买,如金币、道具'),
nonConsumable(label: '非消耗品', description: '一次购买永久拥有'),
subscription(label: '订阅', description: '按周期付费,如会员');
final String label;
final String description;
const ProductType({
required this.label,
required this.description,
});
}
3.1.2 购买状态枚举 (PurchaseStatus)
enum PurchaseStatus {
pending(label: '处理中', color: Colors.orange),
completed(label: '已完成', color: Colors.green),
failed(label: '失败', color: Colors.red),
restored(label: '已恢复', color: Colors.blue),
cancelled(label: '已取消', color: Colors.grey);
final String label;
final Color color;
const PurchaseStatus({
required this.label,
required this.color,
});
}
3.1.3 商品模型 (Product)
class Product {
final String id;
final String name;
final String description;
final double price;
final String currency;
final ProductType type;
final String? icon;
final bool isPopular;
final String? discount;
String get formattedPrice => '$currency${price.toStringAsFixed(2)}';
}
3.1.4 商品类型分布
3.2 页面结构设计
3.2.1 主页面布局
3.2.2 商店页结构
3.2.3 商品卡片结构
3.3 购买处理逻辑
3.4 数据存储逻辑
四、UI设计规范
4.1 配色方案
应用以优雅的紫色为主色调,象征尊贵与品质:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #6200EE (Purple) | 导航、主题元素 |
| 辅助色 | #7C4DFF | 次要按钮 |
| 第三色 | #B388FF | 背景装饰 |
| 强调色 | #3700B3 | 重要操作 |
| 背景色 | #FAFAFA | 页面背景 |
| 卡片背景 | #FFFFFF | 信息卡片 |
| 成功色 | #4CAF50 | 购买成功 |
| 失败色 | #F44336 | 购买失败 |
| 处理色 | #FF9800 | 处理中 |
4.2 状态配色
| 状态 | 色值 | 视觉效果 |
|---|---|---|
| 处理中 | #FF9800 | 橙色 |
| 已完成 | #4CAF50 | 绿色 |
| 失败 | #F44336 | 红色 |
| 已恢复 | #2196F3 | 蓝色 |
| 已取消 | #9E9E9E | 灰色 |
4.3 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 页面标题 | 24px | Bold | 主色 |
| 商品名称 | 16px | Bold | 黑色 |
| 商品描述 | 12px | Regular | 灰色 |
| 价格 | 16px | Bold | 主色 |
| 状态标签 | 12px | Bold | 状态色 |
| 按钮文字 | 14px | Medium | 白色 |
4.4 组件规范
4.4.1 热门推荐卡片
┌─────────────────────────────────────┐
│ 💎 500金币 [赠送10%] │
│ │
│ 超值金币包 │
│ 额外赠送50金币 │
│ │
│ ¥25.00 [购买] │
└─────────────────────────────────────┘
4.4.2 商品卡片
┌─────────────────────────────────────┐
│ ┌────┐ 100金币 │
│ │ 💰 │ 基础金币包,适合新手玩家 │
│ └────┘ ¥6.00 已拥有: 5 [购买] │
└─────────────────────────────────────┘
4.4.3 已拥有商品卡片
┌─────────────────────────────────────┐
│ ┌────┐ 去广告 │
│ │ 🚫 │ 永久移除应用内广告 │
│ └────┘ ¥18.00 [✓已拥有]│
└─────────────────────────────────────┘
4.4.4 购买记录卡片
┌─────────────────────────────────────┐
│ [✓] 500金币 │
│ ¥25.00 │
│ 04-12 14:30 [已完成] │
└─────────────────────────────────────┘
4.4.5 购买成功对话框
┌─────────────────────────────────────┐
│ ┌────┐ │
│ │ ✓ │ │
│ └────┘ │
│ │
│ 购买成功! │
│ 500金币 │
│ │
│ [确定] │
└─────────────────────────────────────┘
五、核心功能实现
5.1 商品展示实现
Widget _buildProductCard(Product product) {
final isOwned = _ownedProducts.contains(product.id);
final isPurchasing = _currentPurchasingProduct == product.id;
final count = _consumableCount[product.id] ?? 0;
return Card(
elevation: 2,
margin: const EdgeInsets.only(bottom: 12),
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Container(
width: 56,
height: 56,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.primaryContainer,
borderRadius: BorderRadius.circular(12),
),
child: Center(
child: Text(product.icon ?? '📦', style: const TextStyle(fontSize: 28)),
),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(product.name, style: Theme.of(context).textTheme.titleMedium),
Text(product.description, style: Theme.of(context).textTheme.bodySmall),
Text(product.formattedPrice, style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
],
),
),
_buildBuyButton(product),
],
),
),
);
}
5.2 购买流程实现
Future<void> _purchaseProduct(Product product) async {
if (_isPurchasing) return;
if (_useBiometric && _isBiometricAvailable) {
final authenticated = await _authenticateWithBiometric();
if (!authenticated) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('认证失败,无法完成购买')),
);
return;
}
}
setState(() {
_isPurchasing = true;
_currentPurchasingProduct = product.id;
});
_pulseController.repeat(reverse: true);
await Future.delayed(const Duration(seconds: 2));
final success = math.Random().nextDouble() > 0.1;
if (success) {
final record = PurchaseRecord(
id: 'purchase_${DateTime.now().millisecondsSinceEpoch}',
productId: product.id,
productName: product.name,
price: product.price,
purchaseTime: DateTime.now(),
status: PurchaseStatus.completed,
transactionId: 'TXN${DateTime.now().millisecondsSinceEpoch}',
);
setState(() {
_purchaseHistory.insert(0, record);
if (product.type == ProductType.consumable) {
_consumableCount[product.id] = (_consumableCount[product.id] ?? 0) + 1;
} else {
_ownedProducts.add(product.id);
}
_isPurchasing = false;
_currentPurchasingProduct = null;
});
await _savePurchaseHistory();
await _saveOwnedProducts();
_showPurchaseSuccessDialog(product);
}
}
5.3 生物认证实现
Future<bool> _authenticateWithBiometric() async {
try {
return await _localAuth.authenticate(
localizedReason: '请验证身份以完成购买',
options: const AuthenticationOptions(
stickyAuth: true,
biometricOnly: true,
),
);
} catch (e) {
debugPrint('生物认证失败: $e');
return false;
}
}
5.4 数据存储实现
Future<void> _savePurchaseHistory() async {
final prefs = await SharedPreferences.getInstance();
final historyJson = _purchaseHistory.map((r) =>
'${r.id}|${r.productId}|${r.productName}|${r.price}|${r.purchaseTime.millisecondsSinceEpoch}|${r.status.name}|${r.transactionId ?? ''}'
).toList();
await prefs.setStringList('purchase_history', historyJson);
}
Future<void> _loadPurchaseHistory() async {
final prefs = await SharedPreferences.getInstance();
final historyJson = prefs.getStringList('purchase_history') ?? [];
setState(() {
_purchaseHistory.clear();
for (var json in historyJson) {
final parts = json.split('|');
if (parts.length >= 6) {
_purchaseHistory.add(PurchaseRecord(
id: parts[0],
productId: parts[1],
productName: parts[2],
price: double.tryParse(parts[3]) ?? 0,
purchaseTime: DateTime.fromMillisecondsSinceEpoch(int.tryParse(parts[4]) ?? 0),
status: PurchaseStatus.values.firstWhere(
(s) => s.name == parts[5],
orElse: () => PurchaseStatus.completed,
),
));
}
}
});
}
5.5 恢复购买实现
Future<void> _restorePurchases() async {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('恢复购买'),
content: const Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text('正在恢复购买记录...'),
],
),
),
);
await Future.delayed(const Duration(seconds: 2));
Navigator.pop(context);
final restoredCount = _purchaseHistory
.where((r) => r.status == PurchaseStatus.completed)
.length;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('已恢复 $restoredCount 个购买记录')),
);
}
六、交互设计
6.1 购买流程
6.2 商品浏览流程
6.3 恢复购买流程
七、扩展功能规划
7.1 后续版本规划
7.2 功能扩展建议
7.2.1 真实支付集成
支付功能:
- 对接应用商店支付
- 支付结果验证
- 收据处理
- 退款处理
7.2.2 订阅管理
订阅功能:
- 订阅状态管理
- 到期提醒
- 自动续费
- 订阅历史
7.2.3 促销活动
促销功能:
- 限时折扣
- 批量优惠
- 优惠券系统
- 会员专享
八、注意事项
8.1 开发注意事项
-
支付安全:确保支付流程安全可靠
-
数据验证:验证购买收据的真实性
-
错误处理:妥善处理各种支付异常
-
状态同步:确保购买状态正确同步
-
用户体验:提供清晰的购买反馈
8.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 购买失败 | 网络问题 | 提示用户重试 |
| 认证失败 | 设备不支持 | 使用密码认证 |
| 数据丢失 | 本地存储问题 | 云端备份 |
| 重复扣款 | 重复请求 | 请求去重 |
| 恢复失败 | 记录不存在 | 提示用户 |
8.3 使用技巧
🛒 应用内购买使用技巧 🛒
购买技巧
- 确认商品信息再购买
- 开启生物认证保护
- 保存购买凭证
- 及时查看购买记录
管理技巧
- 定期查看已购物品
- 及时恢复购买记录
- 注意订阅到期时间
- 合理规划消费
安全技巧
- 不要分享账户信息
- 定期检查购买记录
- 发现异常及时反馈
- 使用官方渠道购买
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
| Android | API 21+ |
| iOS | 12.0+ |
9.2 依赖配置
在 pubspec.yaml 中添加以下依赖:
dependencies:
flutter:
sdk: flutter
shared_preferences: ^2.2.2
local_auth: ^2.3.0
intl: ^0.19.0
9.3 运行命令
# 查看可用设备
flutter devices
# 运行到Web服务器
flutter run -d web-server -t lib/main_in_app_purchase.dart --web-port 8150
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_in_app_purchase.dart
# 运行到Android设备
flutter run -d android lib/main_in_app_purchase.dart
# 代码分析
flutter analyze lib/main_in_app_purchase.dart
9.4 权限配置
Android权限 (android/app/src/main/AndroidManifest.xml)
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
iOS权限 (ios/Runner/Info.plist)
<key>NSFaceIDUsageDescription</key>
<string>需要面容识别权限以验证购买</string>
十、总结
应用内购买演示应用通过整合商品展示、购买流程、生物认证、购买记录、恢复购买等功能,为开发者提供了完整的应用内购买实现参考。应用展示了消耗品、非消耗品、订阅三种商品类型的处理方式,包含热门推荐、折扣标签、拥有状态等实用功能。
核心功能涵盖商品展示、购买流程、生物认证、购买记录、恢复购买、我的物品、购买动画、数据存储八大模块。开发者可以参考本应用了解应用内购买的最佳实践,快速实现自己的应用内购买功能。
应用采用 Material Design 3 设计规范,以优雅的紫色为主色调,象征尊贵与品质。通过本应用,希望能够帮助开发者更好地理解和实现应用内购买功能,提升应用的商业化能力。
应用内购买演示——掌握商业化的关键
更多推荐




所有评论(0)