qs_ios_purchase 1.0.7
qs_ios_purchase: ^1.0.7 copied to clipboard
一个iOS Storekit2内购插件
qs_ios_purchase #
qs_ios_purchase 是一个基于 iOS StoreKit 2 的 Flutter 内购插件,封装了商品查询、购买、恢复购买、交易校验、历史交易判断,以及 VIP、取消免费试用、取消自动续订等事件监听能力。
当前插件仅支持 iOS,最低系统版本为 iOS 15.0。
当前文档对应插件版本
1.0.7,底层依赖QSInAppPurchase 1.3.0。
功能特性 #
- 获取 App Store Connect 中配置的内购商品信息
- 发起消耗型、非消耗型、非续期订阅、自动续期订阅购买
- 恢复购买
- 校验当前交易状态
- 判断当前账号是否存在历史交易
- 监听 VIP 状态变化
- 监听取消免费试用、取消自动续订事件
- 支持取消事件处理失败后的补偿通知
安装 #
在项目的 pubspec.yaml 中添加依赖:
dependencies:
qs_ios_purchase: ^1.0.7
如果需要本地调试,可以使用路径依赖:
dependencies:
qs_ios_purchase:
path: ../qs_ios_purchase
然后执行:
flutter pub get
iOS 配置 #
- 在 App Store Connect 中创建内购商品,并记录商品 ID。
- 确认 iOS 工程的 Deployment Target 不低于
15.0。 - 确认项目已经启用 In-App Purchase 能力。
- 使用真机、Sandbox 账号或 TestFlight 测试完整内购流程。
引入 #
只需导入插件主入口即可使用 QsIosPurchase、QsProductDetail、QsPurchaseResult 及其相关枚举:
import 'package:qs_ios_purchase/qs_ios_purchase.dart';
API 总览 #
| API | 返回值 | 说明 |
|---|---|---|
initialize(...) |
Future<void> |
注册原生监听并订阅四类事件回调 |
getProducts(productIds: ...) |
Future<List<QsProductDetail>> |
获取指定商品的详情 |
requestPurchase(productId: ...) |
Future<QsPurchaseResult> |
发起购买 |
restorePurchase() |
Future<QsPurchaseResult> |
恢复购买 |
checkTransactions() |
Future<QsPurchaseResult?> |
校验当前是否存在有效交易 |
hasHistoryTransactions() |
Future<bool> |
判断当前账号是否存在历史交易 |
handleCancelAutoRenewFailure(id: ...) |
Future<void> |
上报取消自动续订事件处理失败 |
handleCancelFreeTrialFailure(id: ...) |
Future<void> |
上报取消免费试用事件处理失败 |
基础使用 #
1. 初始化监听 #
如果业务需要接收 VIP 状态或取消订阅事件,建议在应用启动后调用 initialize。重复调用时,插件会先取消旧的 Dart 事件订阅,再注册新的回调。
Future<void> initPurchase() async {
await QsIosPurchase.initialize(
onVipChange: (isVip) {
// VIP 状态变化
print('isVip: $isVip');
},
onCancelFreeTrial: (transactionId) {
// 用户取消免费试用
print('cancel free trial: $transactionId');
},
onCancelAutoRenew: (transactionId) {
// 用户取消自动续订
print('cancel auto renew: $transactionId');
},
onCancelFreeTrialEveryTime: () {
// 每次检测到取消免费试用时触发
print('cancel free trial event');
},
);
}
回调参数说明:
onVipChange:返回最新 VIP 状态,参数类型为bool。onCancelFreeTrial:返回取消免费试用对应的交易 ID。onCancelAutoRenew:返回取消自动续订对应的交易 ID。onCancelFreeTrialEveryTime:每次检测到取消免费试用时触发,不携带参数。- 原生事件的类型不符合约定时,VIP、取消免费试用和取消自动续订事件会被忽略。
2. 获取商品列表 #
final products = await QsIosPurchase.getProducts(
productIds: [
'your_product_id',
'your_subscription_id',
],
);
for (final product in products) {
print('${product.id}: ${product.currencyPrice}');
}
getProducts 成功时返回 List<QsProductDetail>;原生侧返回错误信息或平台调用失败时会抛出 PlatformException。
3. 发起购买 #
final result = await QsIosPurchase.requestPurchase(
productId: 'your_product_id',
);
switch (result.status) {
case QsPurchaseStatus.success:
print('购买成功: ${result.transactionID}');
break;
case QsPurchaseStatus.cancel:
print('用户取消购买');
break;
case QsPurchaseStatus.error:
default:
print('购买失败: ${result.errorMessage}');
break;
}
购买成功后,返回结果中会包含商品 ID、交易 ID、原始交易 ID、订阅时间、原始订阅时间和价格等信息。
requestPurchase 会从最近一次 getProducts 获取的商品中查找目标商品。找不到商品时返回 QsPurchaseStatus.error,不会自动重新查询商品。
4. 恢复购买 #
final result = await QsIosPurchase.restorePurchase();
if (result.status == QsPurchaseStatus.success) {
print('恢复购买成功');
} else {
print('恢复购买失败: ${result.errorMessage}');
}
5. 校验交易 #
final result = await QsIosPurchase.checkTransactions();
if (result?.status == QsPurchaseStatus.success) {
print('存在有效交易');
} else {
print('没有有效交易: ${result?.errorMessage}');
}
6. 判断是否存在历史交易 #
final hasHistory = await QsIosPurchase.hasHistoryTransactions();
print('是否存在历史交易: $hasHistory');
7. 取消事件处理失败后的补偿 #
如果业务侧处理取消自动续订或取消免费试用事件失败,可以调用对应方法通知原生侧重新处理。
await QsIosPurchase.handleCancelAutoRenewFailure(id: transactionId);
await QsIosPurchase.handleCancelFreeTrialFailure(id: transactionId);
数据模型 #
QsProductDetail #
商品信息包含以下常用字段:
id:商品 IDproductType:商品类型price:原始价格数值currencyPrice:带货币符号的本地化价格discountPrice:优惠价格数值discountCurrencyPrice:带货币符号的本地化优惠价格discountRate:折扣比例trialPeriodValue:试用周期数值trialPeriodUnit:试用周期单位subscriptionPeriodValue:订阅周期数值subscriptionPeriodUnit:订阅周期单位languageCode:价格区域语言码regionCode:价格区域地区码weekAveragePrice:按周折算价格paymentMode:优惠支付模式isEligibleForIntroOffer:是否有资格享受订阅优惠isFreeTrial:是否为可用的免费试用商品isDiscount:是否为可用的折扣商品
QsPurchaseResult #
购买、恢复购买和交易校验结果包含以下字段:
status:操作状态errorMessage:错误信息productID:商品 IDtransactionID:交易 IDoriginalTransactionID:原始交易 IDsubscriptionDate:订阅时间originalSubscriptionDate:原始订阅时间price:交易价格
枚举说明 #
QsPurchaseStatus #
success:操作成功error:操作失败cancel:用户取消
QsProductType #
consumable:消耗型商品nonConsumable:非消耗型商品nonRenewable:非续期订阅autoRenewable:自动续期订阅
QsPeriodUnit #
day:天week:周month:月year:年
QsPaymentMode #
payAsYouGo:按周期支付优惠价payUpFront:预付优惠价freeTrial:免费试用
注意事项 #
initialize用于注册事件监听;需要接收 VIP 或取消订阅事件时,应在相关业务开始前完成初始化。- 商品 ID 必须与 App Store Connect 中配置的商品 ID 完全一致。
- StoreKit 2 需要 iOS 15.0 及以上系统。
- 内购流程建议在真机、Sandbox 账号和 TestFlight 环境中完整验证。
- 购买接口会从已获取的商品中查找对应商品,购买前必须先调用
getProducts获取目标商品。 getProducts或方法通道调用失败时可能抛出PlatformException;购买、恢复购买和交易校验的业务结果通过QsPurchaseResult.status返回。checkTransactions的公开返回类型允许为空;当前默认 MethodChannel 实现会在无有效结果时返回error状态结果。- 业务侧收到取消免费试用或取消自动续订事件后,如果处理失败,请调用对应的补偿方法,便于后续重新处理。