@@ -166,13 +166,57 @@ T? enumFromString<T>(Iterable<T> values, String value) {
166166 return values.firstWhereOrNull ((type) => type.toString ().split ('.' ).last == value);
167167}
168168
169- extension KVPurchasedItem on PurchasedItem {
169+ extension KVPurchasedItem on Purchase {
170170 String get keeVaultSubscriptionId {
171- final prefix = purchaseStateAndroid != null ? 'gp_' : 'ap_' ;
171+ final prefix = this is PurchaseAndroid ? 'gp_' : 'ap_' ;
172172 if (KeeVaultPlatform .isIOS) {
173173 // Apple does not give us the information needed to derive this information
174+ //TODO:f: maybe now available in purchaseToken with StoreKit2 but we already
175+ // have implemented support for the ID to be changed upon receiving the real
176+ // ID from the server so not likely to be worth changing this.
174177 return prefix;
175178 }
176179 return prefix + (purchaseToken ?? '' );
177180 }
178181}
182+
183+ ActiveSubscription purchaseAsActiveSubscription (Purchase purchase) {
184+ // Map platform-specific fields
185+ final bool ? autoRenewing = purchase is PurchaseAndroid ? purchase.autoRenewingAndroid : null ;
186+ final String ? basePlanId = purchase is PurchaseAndroid ? purchase.currentPlanId : null ;
187+ final String ? environmentIOS = purchase is PurchaseIOS ? purchase.environmentIOS : null ;
188+ final double ? expirationDateIOS = purchase is PurchaseIOS ? purchase.expirationDateIOS : null ;
189+ final RenewalInfoIOS ? renewalInfoIOS = purchase is PurchaseIOS ? purchase.renewalInfoIOS : null ;
190+
191+ // Calculate daysUntilExpirationIOS and willExpireSoon for iOS
192+ double ? daysUntilExpirationIOS;
193+ bool ? willExpireSoon;
194+ if (expirationDateIOS != null ) {
195+ final expirationDate = DateTime .fromMillisecondsSinceEpoch (expirationDateIOS.toInt ());
196+ final now = DateTime .now ();
197+ final daysUntilExpiration = expirationDate.difference (now).inDays;
198+ daysUntilExpirationIOS = daysUntilExpiration.toDouble ();
199+ // Consider subscription expiring soon if < 7 days remaining
200+ willExpireSoon = daysUntilExpiration > 0 && daysUntilExpiration < 7 ;
201+ }
202+
203+ // Create ActiveSubscription from Purchase
204+ return ActiveSubscription (
205+ productId: purchase.productId,
206+ transactionId: purchase.transactionIdFor ?? purchase.purchaseToken ?? '' ,
207+ purchaseToken: purchase.purchaseToken,
208+ transactionDate: purchase.transactionDate is String
209+ ? double .tryParse (purchase.transactionDate as String ) ?? 0.0
210+ : (purchase.transactionDate as num ? )? .toDouble () ?? 0.0 ,
211+ isActive: purchase.purchaseState == PurchaseState .Purchased ,
212+ autoRenewingAndroid: autoRenewing,
213+ basePlanIdAndroid: basePlanId,
214+ currentPlanId: purchase.currentPlanId,
215+ daysUntilExpirationIOS: daysUntilExpirationIOS,
216+ environmentIOS: environmentIOS,
217+ expirationDateIOS: expirationDateIOS,
218+ renewalInfoIOS: renewalInfoIOS,
219+ purchaseTokenAndroid: purchase is PurchaseAndroid ? purchase.purchaseToken : null ,
220+ willExpireSoon: willExpireSoon,
221+ );
222+ }
0 commit comments