From 42de2be04400861f3cc9ac933c8f70eac125aa56 Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Thu, 22 Oct 2020 22:50:24 +0200 Subject: [PATCH] Android: Confirm pending purchases There seems to be a race condition which results in some purchases not being confirmed. --- lib/iap.dart | 58 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/lib/iap.dart b/lib/iap.dart index d488873d..d2a629c3 100644 --- a/lib/iap.dart +++ b/lib/iap.dart @@ -15,6 +15,7 @@ import 'package:gitjournal/utils/logger.dart'; class InAppPurchases { static Future confirmProPurchaseBoot() async { clearTransactionsIos(); + confirmPendingPurchases(); if (Features.alwaysPro) { return; @@ -103,23 +104,48 @@ class InAppPurchases { } static Future clearTransactionsIos() async { - if (Platform.isIOS) { - final transactions = await SKPaymentQueueWrapper().transactions(); - for (final transaction in transactions) { - try { - if (transaction.transactionState == - SKPaymentTransactionStateWrapper.purchased) { - continue; - } - if (transaction.transactionState == - SKPaymentTransactionStateWrapper.restored) { - continue; - } + if (!Platform.isIOS) { + return; + } - if (transaction.transactionState != - SKPaymentTransactionStateWrapper.purchasing) { - await SKPaymentQueueWrapper().finishTransaction(transaction); - } + final transactions = await SKPaymentQueueWrapper().transactions(); + for (final transaction in transactions) { + try { + if (transaction.transactionState == + SKPaymentTransactionStateWrapper.purchased) { + continue; + } + if (transaction.transactionState == + SKPaymentTransactionStateWrapper.restored) { + continue; + } + + if (transaction.transactionState != + SKPaymentTransactionStateWrapper.purchasing) { + await SKPaymentQueueWrapper().finishTransaction(transaction); + } + } catch (e, stackTrace) { + logException(e, stackTrace); + } + } + } + + static void confirmPendingPurchases() async { + // On iOS this results in a "Sign in with Apple ID" dialog + if (!Platform.isAndroid) { + return; + } + + InAppPurchaseConnection.enablePendingPurchases(); + final iapCon = InAppPurchaseConnection.instance; + + var pastPurchases = await iapCon.queryPastPurchases(); + for (var pd in pastPurchases.pastPurchases) { + if (pd.pendingCompletePurchase) { + Log.i("Pending Complete Purchase - ${pd.productID}"); + + try { + await iapCon.completePurchase(pd); } catch (e, stackTrace) { logException(e, stackTrace); }