queryPastPurchases method
Query 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
.
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 failedPurchaseDetails.verificationData
.
Implementation
Future<QueryPurchaseDetailsResponse> queryPastPurchases(
{String? applicationUserName}) async {
List<PurchasesResultWrapper> responses;
PlatformException? exception;
try {
responses = await Future.wait(<Future<PurchasesResultWrapper>>[
_billingClientManager.runWithClient(
(BillingClient client) => client.queryPurchases(ProductType.inapp),
),
_billingClientManager.runWithClient(
(BillingClient client) => client.queryPurchases(ProductType.subs),
),
]);
} on PlatformException catch (e) {
exception = e;
responses = <PurchasesResultWrapper>[
PurchasesResultWrapper(
responseCode: BillingResponse.error,
purchasesList: const <PurchaseWrapper>[],
billingResult: BillingResultWrapper(
responseCode: BillingResponse.error,
debugMessage: e.details.toString(),
),
),
PurchasesResultWrapper(
responseCode: BillingResponse.error,
purchasesList: const <PurchaseWrapper>[],
billingResult: BillingResultWrapper(
responseCode: BillingResponse.error,
debugMessage: e.details.toString(),
),
)
];
}
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<GooglePlayPurchaseDetails> pastPurchases = responses
.expand((PurchasesResultWrapper response) => response.purchasesList)
.expand((PurchaseWrapper purchaseWrapper) =>
GooglePlayPurchaseDetails.fromPurchase(purchaseWrapper))
.toList();
IAPError? error;
if (exception != null) {
error = IAPError(
source: kIAPSource,
code: exception.code,
message: exception.message ?? '',
details: exception.details);
} else if (errorMessage.isNotEmpty) {
error = IAPError(
source: kIAPSource,
code: kRestoredPurchaseErrorCode,
message: errorMessage);
}
return QueryPurchaseDetailsResponse(
pastPurchases: pastPurchases, error: error);
}