Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flutter IAP how to "Restore Purchases"

I am using flutter_inapp_purchase for my flutter app's IAP of non-Consumable product. For IOS, it does need to include a "Restore Purchases" feature to allow users to restore the previously purchased in-app purchases. May I know how to create "Restore" button and initiate the restore process when the "Restore" button is tapped by the user?

  Future<Null> _buyProduct(IAPItem item) async {
    try {
      PurchasedItem purchased= await 
  FlutterInappPurchase.buyProduct(item.productId);
      print('purcuased - ${purchased.toString()}');
    } catch (error) {
      print('$error');
    }
  }

  Future<Null> _getProduct() async {
    List<IAPItem> items = await FlutterInappPurchase.getProducts(_productLists);
    for (var item in items) {
      print('${item.toString()}');
      this._items.add(item);
    }

    setState(() {
      this._items = items;
    });
  }
like image 234
GPH Avatar asked Oct 21 '25 02:10

GPH


2 Answers

For devs using official flutter dev package https://pub.dev/packages/in_app_purchase:

Restore purchases (needed for iOS non-consumable, auto-renewable subscription, or non-renewing subscription) is simply calling

Future<QueryPurchaseDetailsResponse> queryPastPurchases

which under the hood calls

_observer.getRestoredTransactions

What you should do here is to iterate all purchases with status PurchaseStatus.purchased or Purchase.error and call

InAppPurchaseConnection.instance.completePurchase(purchase);

then validate receipts with Apple and deliver owned purchases

taken from class InAppPurchaseConnection:

/// You are responsible for completing every [PurchaseDetails] whose /// [PurchaseDetails.status] is [PurchaseStatus.purchased] or /// [[PurchaseStatus.error]. Completing a [PurchaseStatus.pending] purchase /// will cause an exception. /// /// This throws an [UnsupportedError] on Android.

  • If a purchase is not completed ([completePurchase] is not called on the purchase object) from the last app session. Purchase updates will happen when a new app session starts instead.

You will probably do that anyways on the app launch but Apple now requires restore purchases option for all non-consumable and auto-renewable inapp products, otherwise your app will be rejected in the review process.

https://developer.apple.com/documentation/storekit/in-app_purchase/offering_completing_and_restoring_in-app_purchases

If your app sells non-consumable, auto-renewable subscription, or non-renewing subscription products, you must provide a UI that allows them to be restored. Your customers expect your content to be available on all their devices and indefinitely; see In-App Purchase for more information.

like image 128
voytez Avatar answered Oct 22 '25 16:10

voytez


According to the Plugin documentation you can use the API

getAvailablePurchases

enter image description here

That looking at the library native code, this method is link to

// getAvailablePurchases
- (void)getAvailableItems:(FlutterResult)result {
    [[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
    flutterResult = result;
}

And from Apple docs:

Declaration

func restoreCompletedTransactions()

Discussion

Use this method to restore finished transactions—that is, transactions for which you have already called finishTransaction(_:). You call this method in one of the following situations: To install purchases on additional devices To restore purchases for an application that the user deleted and reinstalled

So adding a Widget Button (the one you like most) is up to you, and you can put it wherever you want.

Then in the onClick event call getAvailableItems and manage the previously bought purchases of the users and reinstall them in the user's device.

like image 32
shadowsheep Avatar answered Oct 22 '25 17:10

shadowsheep



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!