Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[in_app_purchase]IAP/android add cancel status #4095

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.2.0

* BREAKING CHANGE : Refactor to handle new `PurchaseStatus` named `canceled`. This means developers
can distinguish between an error and user cancellation.

## 0.1.6

* Require Dart SDK >= 2.14.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,12 @@ class InAppPurchaseAndroidPlatform extends InAppPurchasePlatform {
}
final List<Future<PurchaseDetails>> purchases =
resultWrapper.purchasesList.map((PurchaseWrapper purchase) {
return _maybeAutoConsumePurchase(
GooglePlayPurchaseDetails.fromPurchase(purchase)..error = error);
final GooglePlayPurchaseDetails googlePlayPurchaseDetails =
GooglePlayPurchaseDetails.fromPurchase(purchase)..error = error;
if (resultWrapper.responseCode == BillingResponse.userCanceled) {
googlePlayPurchaseDetails.status = PurchaseStatus.canceled;
}
return _maybeAutoConsumePurchase(googlePlayPurchaseDetails);
}).toList();
if (purchases.isNotEmpty) {
return Future.wait(purchases);
Expand All @@ -270,7 +274,9 @@ class InAppPurchaseAndroidPlatform extends InAppPurchasePlatform {
PurchaseDetails(
purchaseID: '',
productID: '',
status: PurchaseStatus.error,
status: resultWrapper.responseCode == BillingResponse.userCanceled
? PurchaseStatus.canceled
: PurchaseStatus.error,
transactionDate: null,
verificationData: PurchaseVerificationData(
localVerificationData: '',
Expand Down
4 changes: 2 additions & 2 deletions packages/in_app_purchase/in_app_purchase_android/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: in_app_purchase_android
description: An implementation for the Android platform of the Flutter `in_app_purchase` plugin. This uses the Android BillingClient APIs.
repository: https://github.com/flutter/plugins/tree/master/packages/in_app_purchase/in_app_purchase_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
version: 0.1.6
version: 0.2.0

environment:
sdk: ">=2.14.0 <3.0.0"
Expand All @@ -20,7 +20,7 @@ dependencies:
collection: ^1.15.0
flutter:
sdk: flutter
in_app_purchase_platform_interface: ^1.1.0
in_app_purchase_platform_interface: ^1.3.0
json_annotation: ^4.3.0
meta: ^1.3.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,74 @@ void main() {
purchaseParam: purchaseParam, autoConsume: false);
expect(null, await consumeCompleter.future);
});

test(
'should get canceled purchase status when response code is BillingResponse.userCanceled',
() async {
final SkuDetailsWrapper skuDetails = dummySkuDetails;
final String accountId = "hashedAccountId";
const String debugMessage = 'dummy message';
final BillingResponse sentCode = BillingResponse.userCanceled;
final BillingResultWrapper expectedBillingResult = BillingResultWrapper(
responseCode: sentCode, debugMessage: debugMessage);
stubPlatform.addResponse(
name: launchMethodName,
value: buildBillingResultMap(expectedBillingResult),
additionalStepBeforeReturn: (_) {
// Mock java update purchase callback.
MethodCall call = MethodCall(kOnPurchasesUpdated, {
'billingResult': buildBillingResultMap(expectedBillingResult),
'responseCode': BillingResponseConverter().toJson(sentCode),
'purchasesList': [
{
'orderId': 'orderID1',
'sku': skuDetails.sku,
'isAutoRenewing': false,
'packageName': "package",
'purchaseTime': 1231231231,
'purchaseToken': "token",
'signature': 'sign',
'originalJson': 'json',
'developerPayload': 'dummy payload',
'isAcknowledged': true,
'purchaseState': 1,
}
]
});
iapAndroidPlatform.billingClient.callHandler(call);
});
Completer consumeCompleter = Completer();
// adding call back for consume purchase
final BillingResponse expectedCode = BillingResponse.userCanceled;
final BillingResultWrapper expectedBillingResultForConsume =
BillingResultWrapper(
responseCode: expectedCode, debugMessage: debugMessage);
stubPlatform.addResponse(
name: consumeMethodName,
value: buildBillingResultMap(expectedBillingResultForConsume),
additionalStepBeforeReturn: (dynamic args) {
String purchaseToken = args['purchaseToken'];
consumeCompleter.complete(purchaseToken);
});

Completer completer = Completer();
PurchaseDetails purchaseDetails;
Stream purchaseStream = iapAndroidPlatform.purchaseStream;
late StreamSubscription subscription;
subscription = purchaseStream.listen((_) {
purchaseDetails = _.first;
completer.complete(purchaseDetails);
subscription.cancel();
}, onDone: () {});
final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam(
productDetails: GooglePlayProductDetails.fromSkuDetails(skuDetails),
applicationUserName: accountId);
await iapAndroidPlatform.buyConsumable(purchaseParam: purchaseParam);

// Verify that the result has an error for the failed consumption
GooglePlayPurchaseDetails result = await completer.future;
expect(result.status, PurchaseStatus.canceled);
});
});

group('complete purchase', () {
Expand Down