I'm using a tool called in_app_purchase (version: ^3.1.4 ) to manage subscriptions in my app. It's working well, and I'm able to give users access to the product they're subscribing to.
Right now, my app is in test mode. I get emails from Google to let me know if a subscription has been canceled, renewed, or if it's new.
When a subscription is renewed, I want to know about it so I can update the user's account. To do that, I use a method called restorePurchases() to check past purchases. I then compare the date of the latest purchase with the one I have stored in my FireStore database. If the new purchase is more recent than the last one, I update the user's account and give them access to the product they're subscribed to.
Bellow is how I implemented that logic:
-
initState method:
@override void initState() { super.initState(); final Stream purchaseUpdated = _inAppPurchase.purchaseStream; _subscription = purchaseUpdated.listen( (purchaseDetailsList) { loggy.info("I AM LISTENING...."); _listenToPurchaseUpdated(purchaseDetailsList); }, onDone: () { _subscription.cancel(); }, onError: (error) { // handle error here. }, ); _inAppPurchase.restorePurchases();//here I trigger the purchaseStream each time initState is called }
_listenToPurchaseUpdated method:
Future<void> _listenToPurchaseUpdated(purchaseDetailsList) async {
for (final PurchaseDetails purchaseDetails in purchaseDetailsList) {
if (purchaseDetails.status == PurchaseStatus.pending) {
showPendingUI();
} else {
if (purchaseDetails.status == PurchaseStatus.error) {
hendleError(purchaseDetails);
} else if (purchaseDetails.status == PurchaseStatus.purchased ||
purchaseDetails.status == PurchaseStatus.restored) {
if (!mounted) return;
final lastTransactionDate =
await SubscriptionService().getLastTransactionDate();
if (lastTransactionDate.isNotEmpty) {
loggy.info(
"last transaction date: $lastTransactionDate",
);
}
loggy.info(
"current transaction date: ${purchaseDetails.transactionDate}",
);
if (lastTransactionDate.isEmpty ||
lastTransactionDate != purchaseDetails.transactionDate) {
final bool isRecentRenewal = DateTime.fromMillisecondsSinceEpoch(
int.parse(purchaseDetails.transactionDate!),
).isAfter(
DateTime.fromMillisecondsSinceEpoch(
int.parse(lastTransactionDate),
),
);
if (isRecentRenewal) {
loggy.info("delivering product in progress....");
await deliverProduct(purchaseDetails);
}
}
}
if (purchaseDetails.pendingCompletePurchase) {
await _inAppPurchase.completePurchase(purchaseDetails);
}
}
}
}
In the above method, I'm just getting the last transactionDate that was stored in FireStore and comparing it with the current transactionDate, this field can be found on:
purchaseDetails.transactionDate
Unfortunately, when the subscription is renewed, I can't detect it in the app, and the transactionDate remains the same:
from flutter: Can't detect subscription renewal (in_app_purchase)
No comments:
Post a Comment