代码之家  ›  专栏  ›  技术社区  ›  RIZWAN ALI

Flutter IAP IOS可处理不同场景

  •  0
  • RIZWAN ALI  · 技术社区  · 2 年前

    我正在创建一个应用程序,我几乎完成了应用程序开发,只剩下应用程序内订阅。 我也做了一些工作,但无法处理下面列出的一些场景:

    1-如果用户在iPhone中登录的苹果id还没有订阅,那么流程就可以正常工作,购买就会发生,升级api也会命中。

    现在,假设我已经在我的一个帐户上购买了订阅,然后我注销并创建一个新帐户,然后用相同的苹果id为我的第二个帐户购买订阅,下面列出了情况:

    1-ios弹出窗口显示您已经拥有此项目,当我单击“确定”按钮时,升级api仍然会在没有购买的情况下命中。

    我想处理这个senario,并向用户显示这个苹果id已经订阅了,也许还有其他senario需要配置,直到我还没有面对

    截止日期太近了,我是第一次与IAP打交道 任何需要拯救的人都将不胜感激。

    这是我的代码:

      @override
      void initState() {
        final Stream<List<PurchaseDetails>> purchaseUpdated = _iap.purchaseStream;
    
        _subscription =
            purchaseUpdated.listen((List<PurchaseDetails> purchaseDetailsList) {
          for (PurchaseDetails purchaseDetails in purchaseDetailsList) {
            _iap.completePurchase(purchaseDetails);
          }
          _listenToPurchaseUpdated(purchaseDetailsList);
        }, onDone: () {
          _subscription.cancel();
        }, onError: (Object error) {});
    
        AddProvider addProvider = Provider.of<AddProvider>(context, listen: false);
        addProvider.initializeStatisticsPageInterstitialAd();
        handlePurchase();
        super.initState();
      }
    
      late StreamSubscription<List<PurchaseDetails>> _subscription;
      final List<PurchaseDetails> _purchases = [];
    
    // Inside your _listenToPurchaseUpdated method:
      void _listenToPurchaseUpdated(
          List<PurchaseDetails> purchaseDetailsList) async {
        for (PurchaseDetails purchaseDetails in purchaseDetailsList) {
          if (purchaseDetails.pendingCompletePurchase) {
            await _iap.completePurchase(purchaseDetails);
          }
    
          if (purchaseDetails.status == PurchaseStatus.pending) {
            CommonData.showCustomSnackbar(
                context, 'Please wait while fetching details..');
          } else {
            if (purchaseDetails.status == PurchaseStatus.error) {
              CommonData.showCustomSnackbar(context, 'Error');
            } else if (purchaseDetails.status == PurchaseStatus.canceled) {
              CommonData.showCustomSnackbar(context, 'Subscription is cancelled');
              _purchases.removeWhere(
                  (element) => element.productID == purchaseDetails.productID);
            } else if (purchaseDetails.status == PurchaseStatus.purchased) {
              bool valid = await _verifyPurchase(purchaseDetails);
              if (valid) {
                await _verifyPurchase(purchaseDetails);
                await hitUpgradeApi(
                    pri, pdi, pdi == "monthly_subscription" ? "monthly" : "yearly");
                upgradeToPro(purchaseDetails);
              } else {
                if (context.mounted) {
                  CommonData.showCustomSnackbar(context,
                      'This apple id have already active subcription,change the id or logged in with relative subscribed account');
                }
                return;
              }
            }
          }
        }
      }
    
      Future<bool> _verifyPurchase(PurchaseDetails purchaseDetails) async {
        if (purchaseDetails.status == PurchaseStatus.purchased) {
          st = purchaseDetails.status.toString();
          pdi = purchaseDetails.productID.toString();
          pri = purchaseDetails.purchaseID.toString();
          td = purchaseDetails.transactionDate.toString();
          if (st.isNotEmpty && pdi.isNotEmpty && pri.isNotEmpty && td.isNotEmpty) {
            return Future<bool>.value(true);
          }
        }
        CommonData.showCustomSnackbar(context, "Transaction failed");
        return Future<bool>.value(false);
      }
    
      Future<void> hitUpgradeApi(
          String purchaseTocken, String purchaseId, String plan) async {
        try {
          Map<String, dynamic> data = {
            "purchase_token": purchaseTocken,
            "purchase_id": purchaseId,
            "plan": plan
          };
          Dio dio = await CommonData.createDioWithAuthHeader();
          Response response = await dio.post(CommonData.subcriptionApi, data: data);
          if (response.statusCode == 200) {
            if (mounted) {
              CommonData.showCustomSnackbar(context, "Upgraded to pro");
              Navigator.of(context).pop();
            }
          }
        } on DioException catch (e) {
          if (e.type == DioExceptionType.unknown ||
              e.type == DioExceptionType.connectionError ||
              e.type == DioExceptionType.connectionTimeout) {
            if (mounted) {
              CommonData.showCustomSnackbar(context, "No internet connection");
            }
          } else {
            if (mounted) {
              CommonData.sshowDialog('Error', e.response!.data['message'], context);
            }
          }
        }
      }
    
      bool _isPurchased(String productId) {
        return _purchases.any((purchase) => purchase.productID == productId);
      }
    
      Future<void> handlePurchase() async {
        monthlyProductDetailsResponse = await _iap.queryProductDetails({
          'monthly_subscription',
        });
        yearlyProductDetailsResponse =
            await _iap.queryProductDetails({'yearly_subscription'});
      }
    
      Future<void> purchaseProduct(ProductDetails productDetails) async {
        try {
          final PurchaseParam purchaseParam =
              PurchaseParam(productDetails: productDetails);
          final purchaseDetailss = await _iap.buyNonConsumable(
            purchaseParam: purchaseParam,
          );
          //  _verifyPurchase(purchaseDetails);
          if (!purchaseDetailss) {
            if (context.mounted) {
              CommonData.showCustomSnackbar(context, "Some error occurred..");
            }
          } else {
            if (context.mounted) {
              CommonData.showCustomSnackbar(context, "Transaction failed");
            }
          }
        } catch (e) {
          print(e.toString());
          // completePurchase(productDetails.id);
        }
      }
    
      Future<void> upgradeToPro(PurchaseDetails purchaseDetails) async {
        _purchases.add(purchaseDetails);
      }
    
    0 回复  |  直到 2 年前