I am trying to implement a subscription in my flutter application, with server side verification. My code is pretty much a copy of the example of in_app_purchase package
Future<void> _listenToPurchaseUpdated(
List<PurchaseDetails> purchaseDetailsList) async {
for (final PurchaseDetails purchaseDetails in purchaseDetailsList) {
if (purchaseDetails.status == PurchaseStatus.pending) {
showPendingUI();
} else {
if (purchaseDetails.status == PurchaseStatus.error) {
handleError(purchaseDetails.error!);
} else if (purchaseDetails.status == PurchaseStatus.purchased ||
purchaseDetails.status == PurchaseStatus.restored) {
final bool valid = await _verifyPurchase(purchaseDetails);
if (valid) {
unawaited(deliverProduct(purchaseDetails));
} else {
_handleInvalidPurchase(purchaseDetails);
return;
}
}
if (Platform.isAndroid) {
if (!_kAutoConsume && purchaseDetails.productID == _kConsumableId) {
final InAppPurchaseAndroidPlatformAddition androidAddition =
_inAppPurchase.getPlatformAddition<
InAppPurchaseAndroidPlatformAddition>();
await androidAddition.consumePurchase(purchaseDetails);
}
}
if (purchaseDetails.pendingCompletePurchase) {
await _inAppPurchase.completePurchase(purchaseDetails);
}
}
}
}
My _verifyPurchase method calls backend to verify the authenticity of the purchase, and returns a validity status.
The problem with Apple implementation is that, it streams all the purchases to this method. That means that all the old purchases are going through this method. If a user is subscribed for two years, every time they open the application, this method is invoked 24 times. That is not ideal and causes problems.
I tried filtering expired transactions, but I couldn't decode the verification data on the mobile, so I cannot access expiration date.
How can I tell a new purchase, from an already verified one?
By using the purchases_flutter package you can first fetch your products, show them to the users (if not yet subscribed) and than offer a buy button for each product.
Fetch products, you will geht a List of StoreProduct
Show the StoreProduct list to users and create a buy option, something like this: