import 'dart:io'; import 'package:aitrainer_app/model/cache.dart'; import 'package:aitrainer_app/service/logging.dart'; import 'package:flutter/services.dart'; import 'package:purchases_flutter/purchases_flutter.dart'; import 'package:aitrainer_app/model/product.dart' as wtproduct; class RevenueCatPurchases with Logging { static final RevenueCatPurchases _singleton = RevenueCatPurchases._internal(); Offering? _offering; String? appUserId; factory RevenueCatPurchases() { return _singleton; } RevenueCatPurchases._internal(); Offering? get offering => _offering; Future initPlatform() async { if (Cache().userLoggedIn != null) { await Purchases.setDebugLogsEnabled(true); await Purchases.setup("yLxGFWaeRtThLImqznvBnUEKjgArSsZE", appUserId: Cache().userLoggedIn!.customerId.toString()); appUserId = await Purchases.appUserID; log("AppUserId: $appUserId"); await Purchases.setAllowSharingStoreAccount(true); await this.restore(); } } Future restore() async { if (appUserId != null) { try { //PurchaserInfo purchaserInfo = await Purchases.restoreTransactions(); PurchaserInfo purchaserInfo = await Purchases.getPurchaserInfo(); if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) { Cache().hasPurchased = true; log(" ******************************************** "); log(" Purchase active ! "); } else { log(" ** No subscription active"); } } on PlatformException catch (e) { log("Purchaserinfo not reachable " + e.toString()); } } bool inTrial = Cache().userLoggedIn!.trialDate != null && DateTime.now().difference(Cache().userLoggedIn!.trialDate!).inDays < 10; log("Trial mode: $inTrial date: ${Cache().userLoggedIn!.trialDate}"); if (Cache().userLoggedIn!.admin == 1 || inTrial || Cache().userLoggedIn!.lifeLong == 1) { Cache().hasPurchased = true; log(" -- Purchased -- "); } } Future getOfferings() async { if (appUserId == null) { await initPlatform(); } log(" .. acessing offerings..."); try { Offerings offerings = await Purchases.getOfferings(); if (offerings.current != null && offerings.current!.availablePackages.isNotEmpty) { // Display packages for sale _offering = offerings.current; } else { log("No current offerings"); } } on PlatformException catch (e) { // optional error handling log("!!!! Getting offerings error " + e.toString()); } return _offering; } Future makePurchase(wtproduct.Product product) async { try { if (_offering == null) { _offering = await getOfferings(); } if (_offering != null) { String productId = Platform.isAndroid ? product.productIdAndroid! : product.productIdIos!; Package? selectedPackage; log("Nr of packages: " + _offering!.availablePackages.length.toString() + " ProductId: " + productId); for (var package in _offering!.availablePackages) { log("package to check " + package.product.identifier.toString()); if (package.product.identifier == productId) { selectedPackage = package; log("**** Selected package to purchase" + package.product.identifier); break; } } if (selectedPackage != null) { PurchaserInfo purchaserInfo = await Purchases.purchasePackage(selectedPackage); if (purchaserInfo.entitlements.all["wt_subscription"] != null && purchaserInfo.entitlements.all["wt_subscription"]!.isActive) { Cache().hasPurchased = true; log(" -- Purchased -- "); } } else { log("!!!! No Selected package to purchase"); throw Exception("Purchase was not successful"); } } else { log("!!!! No active offering"); } } on PlatformException catch (e) { var errorCode = PurchasesErrorHelper.getErrorCode(e); if (errorCode == PurchasesErrorCode.invalidReceiptError) { log("iOS Sandbox invalid receipt"); Cache().hasPurchased = true; log(" -- Purchased -- "); return; } log(e.toString()); if (errorCode == PurchasesErrorCode.purchaseCancelledError) { throw Exception("Purchase was cancelled"); } else { throw Exception("Purchase was not successful"); } } } }