restorePurchases method

  1. @override
Future<void> restorePurchases({
  1. String? applicationUserName,
})

Restore all previous purchases.

The applicationUserName should match whatever was sent in the initial PurchaseParam, if anything. If no applicationUserName was specified in the initial PurchaseParam, use null.

Restored purchases are delivered through the purchaseStream with a status of PurchaseStatus.restored. You should listen for these purchases, validate their receipts, deliver the content and mark the purchase complete by calling the completePurchase method for each purchase.

This does not return consumed products. If you want to restore unused consumable products, you need to persist consumable product information for your user on your own server.

See also:

  • refreshPurchaseVerificationData, for reloading failed PurchaseDetails.verificationData.

Implementation

@override
Future<void> restorePurchases({
  String? applicationUserName,
}) async {
  List<PurchasesResultWrapper> responses;

  responses = await Future.wait(<Future<PurchasesResultWrapper>>[
    billingClientManager.runWithClient(
      (BillingClient client) => client.queryPurchases(ProductType.inapp),
    ),
    billingClientManager.runWithClient(
      (BillingClient client) => client.queryPurchases(ProductType.subs),
    ),
  ]);

  final Set<String> errorCodeSet = responses
      .where((PurchasesResultWrapper response) =>
          response.responseCode != BillingResponse.ok)
      .map((PurchasesResultWrapper response) =>
          response.responseCode.toString())
      .toSet();

  final String errorMessage =
      errorCodeSet.isNotEmpty ? errorCodeSet.join(', ') : '';

  final List<PurchaseDetails> pastPurchases = responses
      .expand((PurchasesResultWrapper response) => response.purchasesList)
      .expand((PurchaseWrapper purchaseWrapper) =>
          GooglePlayPurchaseDetails.fromPurchase(purchaseWrapper))
      .map((GooglePlayPurchaseDetails details) =>
          details..status = PurchaseStatus.restored)
      .toList();

  if (errorMessage.isNotEmpty) {
    throw InAppPurchaseException(
      source: kIAPSource,
      code: kRestoredPurchaseErrorCode,
      message: errorMessage,
    );
  }

  _purchaseUpdatedController.add(pastPurchases);
}