Flutter内购:如何获取订阅计划的ID及周期等详细信息?
解决in_app_purchase获取订阅计划ID与周期的问题
核心问题原因
你调用queryProductDetails时传入的是父订阅ID"no_ads",但Google Play中每个订阅计划(1-year-sub、6-months、monthly)都是独立的商品ID,必须直接查询这些计划ID才能获取对应计划的完整信息。
解决方案步骤
1. 修改商品ID查询逻辑
将查询的ID集合替换为三个订阅计划的ID,而非父订阅ID:
final response = await _iap.queryProductDetails({"1-year-sub", "6-months", "monthly"}); if (response.error == null) { _products = response.productDetails..sort((a, b) => a.rawPrice.compareTo(b.rawPrice)); }
此时每个返回的ProductDetails对象的id就是对应订阅计划的ID(比如"1-year-sub"),而非父订阅ID。
2. 解析订阅周期信息
ProductDetails包含subscriptionPeriod字段(类型为SubscriptionPeriod),可以通过该字段解析出订阅周期:
units:周期数量(比如1、6)unit:周期单位(枚举值:SubscriptionPeriodUnit.month、SubscriptionPeriodUnit.year等)
写一个工具函数转换为易读的中文描述:
String getSubscriptionPeriodText(SubscriptionPeriod period) { String unitText; switch (period.unit) { case SubscriptionPeriodUnit.day: unitText = "天"; break; case SubscriptionPeriodUnit.week: unitText = "周"; break; case SubscriptionPeriodUnit.month: unitText = "个月"; break; case SubscriptionPeriodUnit.year: unitText = "年"; break; default: unitText = ""; } return "${period.units}${unitText}"; }
3. 更新订阅页面代码
在页面中显示计划ID和解析后的周期,同时调整订阅判断逻辑:
... SizedBox(height: 5), ...purchaseProvider.products.map((product) { bool isPurchased = purchaseProvider.isSubscribed && purchaseProvider.subscribedProductId == product.id; // 解析订阅周期 String periodText = getSubscriptionPeriodText(product.subscriptionPeriod!); return ListTile( title: Text( "${product.title}\n- 计划ID: ${product.id}\n- 订阅周期: ${periodText}\n- 描述: ${product.description}" ), subtitle: Text("价格: ${product.price}"), trailing: isPurchased ? Icon(Icons.check, color: Colors.green) : ElevatedButton( onPressed: () { purchaseProvider.buyProduct(product); }, child: Text(product.price), ), ); }).toList(),
注意事项
- 确保Google Play开发者后台中,三个订阅计划的商品ID与你代码中传入的完全一致
subscriptionPeriod可能为null,需添加空安全判断(上面代码用了!,实际可根据业务场景做非空处理)- 订阅成功后,需记录用户购买的计划ID(而非父订阅ID),用于后续的订阅状态校验
内容的提问来源于stack exchange,提问作者Emerson
相关产品推荐
相关产品推荐

