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,
);
}