首页 > 解决方案 > 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);
            }
          }
        });
      }
     
    }

标签: flutterin-app-purchase

解决方案


确保使用您正在调用的断点

InAppPurchaseConnection.instance.completePurchase(purchase);

也许在它被调用之前发生了一些事情。

也许在两者之间调用了 dispose() 。


推荐阅读