From cdc541e2d3990cc3bb52d14220dded7d2dc682c0 Mon Sep 17 00:00:00 2001 From: Paolo Date: Sat, 25 Apr 2026 00:00:03 +0200 Subject: [PATCH] Auto-sync: 20260425_000000 --- ios/Podfile.lock | 14 ++++ lib/global_data.dart | 1 + lib/services/subscription_service.dart | 77 +++++++++++++++++++ macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 16 ++++ pubspec.yaml | 3 + 6 files changed, 113 insertions(+) create mode 100644 lib/services/subscription_service.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2ea6172..716a55f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1483,7 +1483,13 @@ PODS: - printing (1.0.0): - Flutter - PromisesObjC (2.4.0) + - purchases_flutter (8.11.0): + - Flutter + - PurchasesHybridCommon (= 14.3.0) + - PurchasesHybridCommon (14.3.0): + - RevenueCat (= 5.32.0) - RecaptchaInterop (101.0.0) + - RevenueCat (5.32.0) - share_plus (0.0.1): - Flutter - shared_preferences_foundation (0.0.1): @@ -1519,6 +1525,7 @@ DEPENDENCIES: - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - printing (from `.symlinks/plugins/printing/ios`) + - purchases_flutter (from `.symlinks/plugins/purchases_flutter/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - syncfusion_flutter_pdfviewer (from `.symlinks/plugins/syncfusion_flutter_pdfviewer/ios`) @@ -1560,7 +1567,9 @@ SPEC REPOS: - nanopb - OrderedSet - PromisesObjC + - PurchasesHybridCommon - RecaptchaInterop + - RevenueCat EXTERNAL SOURCES: app_tracking_transparency: @@ -1605,6 +1614,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/permission_handler_apple/ios" printing: :path: ".symlinks/plugins/printing/ios" + purchases_flutter: + :path: ".symlinks/plugins/purchases_flutter/ios" share_plus: :path: ".symlinks/plugins/share_plus/ios" shared_preferences_foundation: @@ -1671,7 +1682,10 @@ SPEC CHECKSUMS: permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d printing: 54ff03f28fe9ba3aa93358afb80a8595a071dd07 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + purchases_flutter: 3570127ba41583a75e553d68a763367007830eff + PurchasesHybridCommon: 7f0944cc5411bdcd1ea5d69affa6a6f9aaf87b13 RecaptchaInterop: 11e0b637842dfb48308d242afc3f448062325aba + RevenueCat: 7e1d0768fb287c9983173c9b28e39ccbeeb828a9 share_plus: de6030e33b4e106470e09322d87cf2a4258d2d1d shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb syncfusion_flutter_pdfviewer: 90dc48305d2e33d4aa20681d1e98ddeda891bc14 diff --git a/lib/global_data.dart b/lib/global_data.dart index 2133a92..805562e 100644 --- a/lib/global_data.dart +++ b/lib/global_data.dart @@ -7,6 +7,7 @@ class GlobalData { static String? idScambioTemporaneo; static String? chiaveSegretaCorrente; static String? idSessione; + static bool isPro = false; // Stato abbonamento RevenueCat // --- DATI GENERALI (NON CANCELLATI DAI RESET PARZIALI) --- static String data_incidente = ""; diff --git a/lib/services/subscription_service.dart b/lib/services/subscription_service.dart new file mode 100644 index 0000000..3070ab0 --- /dev/null +++ b/lib/services/subscription_service.dart @@ -0,0 +1,77 @@ +import 'dart:io'; +import 'package:flutter/services.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:cid_app/global_data.dart'; + +class SubscriptionService { + // TODO: Inserisci qui le tue API Key prese dalla dashboard di RevenueCat + static const _appleApiKey = 'appl_YOUR_APPLE_API_KEY_HERE'; + static const _googleApiKey = 'goog_YOUR_GOOGLE_API_KEY_HERE'; + static const entitlementID = 'pro'; // Il nome dell'entitlement su RevenueCat + + static Future init() async { + await Purchases.setLogLevel(LogLevel.debug); + + PurchasesConfiguration? configuration; + + if (Platform.isAndroid) { + configuration = PurchasesConfiguration(_googleApiKey); + } else if (Platform.isIOS) { + configuration = PurchasesConfiguration(_appleApiKey); + } + + if (configuration != null) { + await Purchases.configure(configuration); + await checkSubscriptionStatus(); + + // Ascolta i cambiamenti di stato (es. rinnovi in background) + Purchases.addCustomerInfoUpdateListener((customerInfo) { + _updateProStatus(customerInfo); + }); + } + } + + static Future checkSubscriptionStatus() async { + try { + final customerInfo = await Purchases.getCustomerInfo(); + _updateProStatus(customerInfo); + } on PlatformException catch (e) { + print('Errore controllo abbonamento: \${e.message}'); + } + } + + static void _updateProStatus(CustomerInfo customerInfo) { + if (customerInfo.entitlements.all[entitlementID] != null && + customerInfo.entitlements.all[entitlementID]!.isActive) { + GlobalData.isPro = true; + } else { + GlobalData.isPro = false; + } + // TODO: Notifica l'interfaccia utente se necessario (es. tramite un Provider o ValueNotifier) + } + + static Future purchasePackage(Package package) async { + try { + final customerInfo = await Purchases.purchasePackage(package); + _updateProStatus(customerInfo); + return GlobalData.isPro; + } on PlatformException catch (e) { + final errorCode = PurchasesErrorHelper.getErrorCode(e); + if (errorCode != PurchasesErrorCode.purchaseCancelledError) { + print('Errore acquisto: \${e.message}'); + } + return false; + } + } + + static Future restorePurchases() async { + try { + final customerInfo = await Purchases.restorePurchases(); + _updateProStatus(customerInfo); + return GlobalData.isPro; + } on PlatformException catch (e) { + print('Errore ripristino: \${e.message}'); + return false; + } + } +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 0ed0071..02223a2 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -16,6 +16,7 @@ import mobile_scanner import open_file_mac import package_info_plus import printing +import purchases_flutter import share_plus import shared_preferences_foundation import syncfusion_pdfviewer_macos @@ -34,6 +35,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PrintingPlugin.register(with: registry.registrar(forPlugin: "PrintingPlugin")) + PurchasesFlutterPlugin.register(with: registry.registrar(forPlugin: "PurchasesFlutterPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SyncfusionFlutterPdfViewerPlugin.register(with: registry.registrar(forPlugin: "SyncfusionFlutterPdfViewerPlugin")) diff --git a/pubspec.lock b/pubspec.lock index d9aa7df..b0c1f8e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -485,6 +485,14 @@ packages: description: flutter source: sdk version: "0.0.0" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 + url: "https://pub.dev" + source: hosted + version: "2.4.4" geoclue: dependency: transitive description: @@ -1045,6 +1053,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + purchases_flutter: + dependency: "direct main" + description: + name: purchases_flutter + sha256: "8d34712aa3201f675eeccaacf45c0b7b025575fc9d0378b2619bb61246e76064" + url: "https://pub.dev" + source: hosted + version: "8.11.0" qr: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 8efddc6..c538033 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -25,6 +25,9 @@ dependencies: # Per aprire il PDF appena generato open_file: ^3.3.2 + # --- ABBONAMENTI IN-APP --- + purchases_flutter: ^8.1.1 + # --- FIREBASE E SICUREZZA --- firebase_core: ^3.10.1 cloud_firestore: ^5.6.2