Question

[Flutter] Payment pending - how to cancel on iOS?

  • 25 February 2022
  • 2 replies
  • 1392 views

Badge +4

[using Flutter SDK] on iOS when I call Purchases.purchaseProduct and it throws the exception(s) 

PurchasesErrorCode.paymentPendingError
or
PurchasesErrorCode.storeProblemError
The docs suggest that this is not an error and to inform the user that the purchase is pending.

For some customers, they do not succeed in setting up a valid payment method at this point. 

I have instances where the actual purchase comes through 30+ days later (when a payment method is finally established, probably for another reason).  At this point the payment is taken but the user may have uninstalled my app by then! 
Ideally, I would like to cancel the pending purchase in the App Store at this point and then require my users to go through the purchase flow a second time.
How can I programatically cancel a pending purchase on iOS or at the very least, see this state outside of the purchaseProduct exception and report it to the user? 

 


2 replies

Userlevel 6
Badge +8

Hey @Mark Chaplin!

Unfortunately you aren’t able to cancel pending purchases, as it means a purchase has been made and it’s waiting to be completed. A customer might be able to manage their purchase manually from https://reportaproblem.apple.com, but that might require the payment to first be completed.

Pending payments might end up taking several days to complete, but it does seem strange that it is taking 30 days in some cases. Ultimately, we’ll pick up on transactions as soon as they are completed and don’t have a way to see pending transactions outside of the purchase methods.

Badge +1

You can also clear the old transaction, here’s an example in Flutter using the package

in_app_purchase_storekit
Future<void> _clearPendingPurchases() async {
if (isIOS || isMacOs) {
try {
final transactions = await SKPaymentQueueWrapper().transactions();
for (final transaction in transactions) {
try {
await SKPaymentQueueWrapper().finishTransaction(transaction);
} catch (e) {
debugPrint("Error clearing pending purchases::in::loop");
debugPrint(e.toString());
rethrow;
}
}
} catch (e) {
debugPrint("Error clearing pending purchases");
debugPrint(e.toString());
rethrow;
}
}
}

 

Reply