flutter - Flutter In App 购买(订阅)三天后自动退款
问题描述
我已经集成了flutter in_app_purchase订阅(android),但它总是在3天后自动退款
我正在使用以下代码进行颤振订阅。我在代码中找不到实际问题,请帮助我在此代码中遗漏的内容
导入“飞镖:异步”; 导入“飞镖:io”; 导入“包:颤振/material.dart”; 导入“包:url_launcher/url_launcher.dart”; 导入“包:in_app_purchase/in_app_purchase.dart”; 导入'util/ConsumableStore.dart'; const bool _kAutoConsume = true; const String _kConsumableId = '消耗品'; 常量列表 _kProductIds = ['subscription_item', 'purchase_item']; 类 StoreScreenNew 扩展 StatefulWidget { @覆盖 _StoreScreenState createState() => _StoreScreenState(); } 类 _StoreScreenState 扩展状态 { 最终 InAppPurchaseConnection _connection = InAppPurchaseConnection.instance; 流订阅>_订阅; 列表 _notFoundIds = []; 列出_products = []; 列出_purchases = []; 布尔 _isAvailable = 假; bool _purchasePending = false; 布尔_加载=真; 字符串 _queryProductError; bool _isConnected = false; 字符串商店名称 = ""; @覆盖 无效初始化状态(){ checkInternet().then((onValue) { 设置状态((){ _isConnected = onValue; }); }); 流购买已更新 = InAppPurchaseConnection.instance.purchaseUpdatedStream; _subscription = purchaseUpdated.listen((purchaseDetailsList) { _listenToPurchaseUpdated(purchaseDetailsList); }, onDone: () { _subscription.cancel(); },onError:(错误){ // 在这里处理错误。 }); 初始化存储信息(); super.initState(); } 未来 checkInternet() 异步 { 尝试 { 最终结果 = 等待 InternetAddress.lookup('google.com'); if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) { 返回 Future.value(true); } 别的 { 返回 Future.value(false); } } 关于 SocketException 捕获 (_) { 返回 Future.value(false); } } 未来 initStoreInfo() 异步 { 如果(平台.isIOS){ storeName = "iTunes"; } 别的 { storeName = "Play 商店"; } final bool isAvailable = await _connection.isAvailable(); 如果(!isAvailable){ 设置状态((){ _isAvailable = isAvailable; _产品 = []; _purchases = []; _notFoundIds = []; _purchasePending = 假; _loading = 假; }); 返回; } ProductDetailsResponse productDetailResponse = 等待_connection.queryProductDetails(_kProductIds.toSet()); if (productDetailResponse.error != null) { 设置状态((){ _queryProductError = productDetailResponse.error.message; _isAvailable = isAvailable; _products = productDetailResponse.productDetails; _purchases = []; _notFoundIds = productDetailResponse.notFoundIDs; _purchasePending = 假; _loading = 假; }); 返回; } 如果(productDetailResponse.productDetails.isEmpty){ 设置状态((){ _queryProductError = null; _isAvailable = isAvailable; _products = productDetailResponse.productDetails; _purchases = []; _notFoundIds = productDetailResponse.notFoundIDs; _purchasePending = 假; _loading = 假; }); 返回; } final QueryPurchaseDetailsResponse purchaseResponse = 等待_connection.queryPastPurchases(); if (purchaseResponse.error != null) { // 处理查询过去的购买错误.. } 最终列表验证购买 = []; for (purchaseDetails purchase in purchaseResponse.pastPurchases) { 如果(等待_verifyPurchase(购买)){ 验证购买。添加(购买); } } 设置状态((){ _isAvailable = isAvailable; _products = productDetailResponse.productDetails; _purchases = 验证购买; _notFoundIds = productDetailResponse.notFoundIDs; _purchasePending = 假; _loading = 假; }); } @覆盖 无效处置(){ _subscription.cancel(); super.dispose(); } @覆盖 小部件构建(BuildContext 上下文){ 列表堆栈 = []; 如果(_queryProductError == null){ 堆栈.add( 列表显示( 孩子们: [ _buildConnectionCheckTile(), _buildProductList(), 添加隐私(), 添加链接() ], ), ); } 别的 { stack.add(中心( 孩子:文本(_queryProductError), )); } 如果(_purchasePending){ 堆栈.add( 堆( 孩子们: [ 不透明度( 不透明度:0.3, 孩子:const ModalBarrier(dismissible:false,颜色:Colors.grey), ), 中心( 孩子:CircularProgressIndicator(), ), ], ), ); } 返回材料应用程序( 家:脚手架( 应用栏:应用栏( backgroundColor: Theme.of(context).primaryColor, automaticImplyLeading: true, 标题:文本('PRO', 风格:Theme.of(context).textTheme.headline5), 领先:图标按钮( 图标:图标(Icons.arrow_back), onPressed: () => Navigator.pop(context, false), )), 正文:_isConnected ? 堆( 孩子:堆栈, ) : 中心( 孩子:列( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, 孩子们: [ 大小盒( 高度:10, ), 容器( 边距:EdgeInsets.all(20), 孩子:文本( "检查您的互联网连接,然后重试。", textAlign: TextAlign.center, 样式:TextStyle(颜色:Colors.black45,fontSize:26), )) ])), ), ); } 卡 _buildConnectionCheckTile() { 如果(_加载){ return Card(child: ListTile(title: const Text('尝试连接...'))); } 最终小部件 storeHeader = ListTile( 前导:图标(_isAvailable?Icons.check:Icons.block, 颜色:_isAvailable ? Colors.green : ThemeData.light().errorColor), 标题:文字( '商店是' + (_isAvailable ? 'available' : 'unavailable') + '.'), ); 最后列出孩子= [ !_isAvailable 吗?storeHeader : 容器() ]; 如果(!_isAvailable){ 儿童.addAll([ 分频器(), 列表瓦片( title: Text('未连接', 样式:TextStyle(颜色:ThemeData.light().errorColor)), 副标题:常量文本( '无法连接到支付处理器。此应用程序是否已正确配置?有关说明,请参阅示例 README。'), ), ]); } return Card(child: Column(children: children)); } 卡 _buildProductList() { 如果(_加载){ 退货卡( 孩子:(ListTile( 领先:CircularProgressIndicator(), 标题:文本('正在获取产品...')))); } 如果(!_isAvailable){ 返回卡(); } 最终 ListTile productHeader = ListTile( 标题:文字( '可用选项', 样式:TextStyle(字体大小:20), ), ); 列出产品列表 = []; 如果(_notFoundIds.isNotEmpty){ productList.add(ListTile( title: Text('[${_notFoundIds.join(", ")}] 未找到', 样式:TextStyle(颜色:ThemeData.light().errorColor)), 副标题:文字( '这个应用程序需要特殊配置才能运行。有关说明,请参阅 example/README.md。'))); } 地图购买 = Map.fromEntries(_purchases.map((PurchaseDetails 购买) { if (purchase.pendingCompletePurchase) { InAppPurchaseConnection.instance.completePurchase(purchase); } return MapEntry(purchase.productID, purchase); })); productList.addAll(_products.map( (产品详情产品详情){ PurchaseDetails previousPurchase = purchase[productDetails.id]; 返回容器( 装饰:盒子装饰( 边界半径:边界半径.圆形(10), 颜色:颜色。白色, 盒子阴影:[ BoxShadow(颜色:Colors.grey,spreadRadius:1), ], ), 边距:EdgeInsets.all(5), 填充:EdgeInsets.all(10), 孩子:列( 孩子们: [ 文本( productDetails.title, textAlign: TextAlign.center, 样式:文本样式( 字体大小:14, fontWeight: FontWeight.bold, 颜色: 上一个购买!= null ?Colors.green : Colors.black), ), 大小盒( 高度:10, ), 分频器(), 大小盒( 高度:10, ), 文本( productDetails.description, textAlign: TextAlign.left, ), 大小盒( 身高:20, ), 分频器(), 容器( 对齐:Alignment.bottomRight, 孩子:previousPurchase!= null ? 容器( 填充:常量 EdgeInsets.all(10.0), 装饰:新盒子装饰( 形状:BoxShape.circle, 颜色:颜色。绿色, ), 孩子:图标( Icons.check, 尺寸:30, 颜色:颜色。白色, )) :平面按钮( 孩子:文本( productDetails.price, 风格:TextStyle(字体大小:18), ), 颜色:Colors.green[800], 文本颜色:颜色.白色, 按下:(){ PurchaseParam purchaseParam = PurchaseParam( 产品详情:产品详情, 应用程序用户名:空, 沙盒测试:假); if (productDetails.id == _kConsumableId) { _connection.buyConsumable( 购买参数:购买参数, 自动消费:_kAutoConsume || 平台.isIOS); } 别的 { _connection.buyNonConsumable( 购买参数:购买参数); } }, )) ], ), ); }, )); 退货卡( 边距:EdgeInsets.all(10), 海拔:0, 孩子:列( 孩子们: [ 产品标题, 分频器(), ] + 产品列表, )); } 无效 showPendingUI() { 设置状态((){ _purchasePending = true; }); } 无效交付产品(PurchaseDetails purchaseDetails)异步{ if (purchaseDetails.productID == _kConsumableId) { 等待 ConsumableStore.save(purchaseDetails.purchaseID); App.setPurchasesStatus(true); 设置状态((){ _purchasePending = 假; }); } 别的 { 设置状态((){ _purchases.add(purchaseDetails); _purchasePending = 假; }); } } 无效句柄错误(IAPError 错误){ 设置状态((){ _purchasePending = 假; }); } 未来 _verifyPurchase(PurchaseDetails purchaseDetails) { 返回 Future.value(true); } 无效_handleInvalidPurchase(PurchaseDetails purchaseDetails){ } 无效_listenToPurchaseUpdated(列出purchaseDetailsList){ purchaseDetailsList.forEach((PurchaseDetails purchaseDetails) async { 如果(purchaseDetails.status == PurchaseStatus.pending){ showPendingUI(); } 别的 { 如果(purchaseDetails.status == PurchaseStatus.error){ 处理错误(purchaseDetails.error); } else if (purchaseDetails.status == PurchaseStatus.purchased) { 布尔有效 = 等待 _verifyPurchase(purchaseDetails); 如果(有效){ 交付产品(购买详情); } 别的 { _handleInvalidPurchase(purchaseDetails); 返回; } } 如果(平台.isAndroid){ if (!_kAutoConsume && purchaseDetails.productID == _kConsumableId) { 等待 InAppPurchaseConnection.instance .consumePurchase(purchaseDetails); } } if (purchaseDetails.pendingCompletePurchase) { 等待 InAppPurchaseConnection.instance .completePurchase(purchaseDetails); } } }); } }
解决方案
确保使用您正在调用的断点
InAppPurchaseConnection.instance.completePurchase(purchase);
也许在它被调用之前发生了一些事情。
也许在两者之间调用了 dispose() 。
推荐阅读
- r - 具有条件段着色的 R 棒棒糖
- php - 调用函数时更改 PHP 中的字体颜色
- javascript - Nuxt ^2.0.0 和 Firebase 托管
- jquery - ReactJS:jquery 库问题
- sql - 如何识别存储过程中视图的使用列
- wpf - 如何正确对齐 ItemsControl 中的数字
- jquery - d3 相当于 jQuery find("*")
- go - 当并非所有 Struct 值都可以转换为 interface{} 时,重命名 JSON 标记
- spring-mvc - Polymer:为什么我需要使用 npm 和 bower?
- asp.net - GraphQL.NET 如何将枚举添加到 GraphQL 类型