From 19cf2afef058cf76ee6e9555b0384f2fbf2299f2 Mon Sep 17 00:00:00 2001 From: rmasa Date: Fri, 17 Jan 2025 11:12:04 +0100 Subject: [PATCH] GooglePlayPurchaseParam add possibility set selected offerToken --- .../in_app_purchase_android/CHANGELOG.md | 4 ++ .../src/in_app_purchase_android_platform.dart | 6 +- .../src/types/google_play_purchase_param.dart | 6 ++ .../in_app_purchase_android/pubspec.yaml | 2 +- ...in_app_purchase_android_platform_test.dart | 58 +++++++++++++++++++ 5 files changed, 73 insertions(+), 3 deletions(-) diff --git a/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md b/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md index 36b7371e7b2b..b970c742d3ac 100644 --- a/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md +++ b/packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.6+14 + +* GooglePlayPurchaseParam add possibility set selected offerToken + ## 0.3.6+13 * Updates androidx.annotation:annotation to 1.9.1. diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart index 333ccc83bc25..34df87027db1 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart @@ -142,13 +142,15 @@ class InAppPurchaseAndroidPlatform extends InAppPurchasePlatform { @override Future buyNonConsumable({required PurchaseParam purchaseParam}) async { ChangeSubscriptionParam? changeSubscriptionParam; + String? offerToken; if (purchaseParam is GooglePlayPurchaseParam) { changeSubscriptionParam = purchaseParam.changeSubscriptionParam; + offerToken = purchaseParam.offerToken; } - String? offerToken; - if (purchaseParam.productDetails is GooglePlayProductDetails) { + + if (offerToken == null && purchaseParam.productDetails is GooglePlayProductDetails) { offerToken = (purchaseParam.productDetails as GooglePlayProductDetails).offerToken; } diff --git a/packages/in_app_purchase/in_app_purchase_android/lib/src/types/google_play_purchase_param.dart b/packages/in_app_purchase/in_app_purchase_android/lib/src/types/google_play_purchase_param.dart index 2f91667b7735..0b5102806f5c 100644 --- a/packages/in_app_purchase/in_app_purchase_android/lib/src/types/google_play_purchase_param.dart +++ b/packages/in_app_purchase/in_app_purchase_android/lib/src/types/google_play_purchase_param.dart @@ -13,9 +13,15 @@ class GooglePlayPurchaseParam extends PurchaseParam { required super.productDetails, super.applicationUserName, this.changeSubscriptionParam, + this.offerToken, }); /// The 'changeSubscriptionParam' containing information for upgrading or /// downgrading an existing subscription. final ChangeSubscriptionParam? changeSubscriptionParam; + + /// For One-time product, "offerToken" shouldn't be filled. + /// For subscriptions, to get the offer token corresponding to the selected + /// offer call productDetails.subscriptionOfferDetails?.get(selectedOfferIndex)?.offerToken + final String? offerToken; } diff --git a/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml b/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml index 0932606e7ae8..933c2472e71c 100644 --- a/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml +++ b/packages/in_app_purchase/in_app_purchase_android/pubspec.yaml @@ -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/packages/tree/main/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.3.6+13 +version: 0.3.6+14 environment: sdk: ^3.5.0 diff --git a/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart b/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart index ee183eeba71a..eb1e68a2c1e6 100644 --- a/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart +++ b/packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart @@ -263,6 +263,64 @@ void main() { }); group('make payment', () { + test('buy non consumable subscribe offer, serializes and deserializes data', () async { + const ProductDetailsWrapper productDetails = dummySubscriptionProductDetails; + const String accountId = 'hashedAccountId'; + const String debugMessage = 'dummy message'; + const BillingResponse sentCode = BillingResponse.ok; + const BillingResultWrapper expectedBillingResult = BillingResultWrapper( + responseCode: sentCode, debugMessage: debugMessage); + + when(mockApi.launchBillingFlow(any)).thenAnswer((_) async { + // Mock java update purchase callback. + iapAndroidPlatform.billingClientManager.client.hostCallbackHandler + .onPurchasesUpdated(PlatformPurchasesResponse( + billingResult: convertToPigeonResult(expectedBillingResult), + purchases: [ + PlatformPurchase( + orderId: 'orderID1', + products: [productDetails.productId], + isAutoRenewing: false, + packageName: 'package', + purchaseTime: 1231231231, + purchaseToken: 'token', + signature: 'sign', + originalJson: 'json', + developerPayload: 'dummy payload', + isAcknowledged: true, + purchaseState: PlatformPurchaseState.purchased, + quantity: 1, + ) + ], + )); + + return convertToPigeonResult(expectedBillingResult); + }); + final Completer completer = Completer(); + PurchaseDetails purchaseDetails; + final Stream> purchaseStream = + iapAndroidPlatform.purchaseStream; + late StreamSubscription> subscription; + subscription = purchaseStream.listen((List details) { + purchaseDetails = details.first; + completer.complete(purchaseDetails); + subscription.cancel(); + }, onDone: () {}); + final GooglePlayPurchaseParam purchaseParam = GooglePlayPurchaseParam( + offerToken: productDetails.subscriptionOfferDetails?.first.offerIdToken, + productDetails: + GooglePlayProductDetails.fromProductDetails(productDetails).first, + applicationUserName: accountId); + final bool launchResult = await iapAndroidPlatform.buyNonConsumable( + purchaseParam: purchaseParam); + + final PurchaseDetails result = await completer.future; + expect(launchResult, isTrue); + expect(result.purchaseID, 'orderID1'); + expect(result.status, PurchaseStatus.purchased); + expect(result.productID, productDetails.productId); + }); + test('buy non consumable, serializes and deserializes data', () async { const ProductDetailsWrapper productDetails = dummyOneTimeProductDetails; const String accountId = 'hashedAccountId';