Skip to content

Commit 378ce7b

Browse files
committed
Replaced proration mode with replacement mode
1 parent ab1630b commit 378ce7b

File tree

13 files changed

+62
-73
lines changed

13 files changed

+62
-73
lines changed

packages/in_app_purchase/in_app_purchase/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
* Clients on versions of Flutter that still support iOS 11 can continue to use this
66
package with iOS 11, but will not receive any further updates to the iOS implementation.
77

8+
## 3.1.14
9+
10+
* Replaces deprecated ProrationMode in Android's billing client with ReplacementMode
11+
812
## 3.1.13
913

1014
* Updates minimum required plugin_platform_interface version to 2.1.7.

packages/in_app_purchase/in_app_purchase/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: in_app_purchase
22
description: A Flutter plugin for in-app purchases. Exposes APIs for making in-app purchases through the App Store and Google Play.
33
repository: https://github.com/flutter/packages/tree/main/packages/in_app_purchase/in_app_purchase
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
5-
version: 3.1.13
5+
version: 3.1.14
66

77
environment:
88
sdk: ^3.1.0
@@ -21,7 +21,7 @@ flutter:
2121
dependencies:
2222
flutter:
2323
sdk: flutter
24-
in_app_purchase_android: ^0.3.0
24+
in_app_purchase_android: ^0.3.3
2525
in_app_purchase_platform_interface: ^1.0.0
2626
in_app_purchase_storekit: ^0.3.4
2727

packages/in_app_purchase/in_app_purchase_android/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 0.3.3
2+
* Replaces deprecated ProrationMode in Android's billing client with ReplacementMode
3+
14
## 0.3.2
25

36
* Adds UserChoiceBilling APIs to platform addition.

packages/in_app_purchase/in_app_purchase_android/android/src/main/java/io/flutter/plugins/inapppurchase/MethodCallHandlerImpl.java

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,8 @@ static final class BillingChoiceMode {
101101
static final int USER_CHOICE_BILLING = 2;
102102
}
103103

104-
// TODO(gmackall): Replace uses of deprecated ProrationMode enum values with new
105-
// ReplacementMode enum values.
106-
// https://github.com/flutter/flutter/issues/128957.
107-
@SuppressWarnings(value = "deprecation")
108-
private static final int PRORATION_MODE_UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY =
109-
com.android.billingclient.api.BillingFlowParams.ProrationMode
110-
.UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY;
104+
private static final int REPLACEMENT_MODE_UNKNOWN_REPLACEMENT_MODE =
105+
BillingFlowParams.SubscriptionUpdateParams.ReplacementMode.UNKNOWN_REPLACEMENT_MODE;
111106

112107
private static final String TAG = "InAppPurchasePlugin";
113108
private static final String LOAD_PRODUCT_DOC_URL =
@@ -202,9 +197,9 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
202197
(String) call.argument("obfuscatedProfileId"),
203198
(String) call.argument("oldProduct"),
204199
(String) call.argument("purchaseToken"),
205-
call.hasArgument("prorationMode")
206-
? (int) call.argument("prorationMode")
207-
: PRORATION_MODE_UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY,
200+
call.hasArgument("replacementMode")
201+
? (int) call.argument("replacementMode")
202+
: REPLACEMENT_MODE_UNKNOWN_REPLACEMENT_MODE,
208203
result);
209204
break;
210205
case MethodNames.QUERY_PURCHASES_ASYNC:
@@ -337,7 +332,7 @@ private void launchBillingFlow(
337332
@Nullable String obfuscatedProfileId,
338333
@Nullable String oldProduct,
339334
@Nullable String purchaseToken,
340-
int prorationMode,
335+
int replacementMode,
341336
MethodChannel.Result result) {
342337
if (billingClientError(result)) {
343338
return;
@@ -381,7 +376,7 @@ private void launchBillingFlow(
381376
}
382377

383378
if (oldProduct == null
384-
&& prorationMode != PRORATION_MODE_UNKNOWN_SUBSCRIPTION_UPGRADE_DOWNGRADE_POLICY) {
379+
&& replacementMode != REPLACEMENT_MODE_UNKNOWN_REPLACEMENT_MODE) {
385380
result.error(
386381
"IN_APP_PURCHASE_REQUIRE_OLD_PRODUCT",
387382
"launchBillingFlow failed because oldProduct is null. You must provide a valid oldProduct in order to use a proration mode.",
@@ -430,24 +425,13 @@ private void launchBillingFlow(
430425
BillingFlowParams.SubscriptionUpdateParams.newBuilder();
431426
if (oldProduct != null && !oldProduct.isEmpty() && purchaseToken != null) {
432427
subscriptionUpdateParamsBuilder.setOldPurchaseToken(purchaseToken);
433-
// Set the prorationMode using a helper to minimize impact of deprecation warning suppression.
434-
setReplaceProrationMode(subscriptionUpdateParamsBuilder, prorationMode);
428+
subscriptionUpdateParamsBuilder.setSubscriptionReplacementMode(replacementMode);
435429
paramsBuilder.setSubscriptionUpdateParams(subscriptionUpdateParamsBuilder.build());
436430
}
437431
result.success(
438432
fromBillingResult(billingClient.launchBillingFlow(activity, paramsBuilder.build())));
439433
}
440434

441-
// TODO(gmackall): Replace uses of deprecated setReplaceProrationMode.
442-
// https://github.com/flutter/flutter/issues/128957.
443-
@SuppressWarnings(value = "deprecation")
444-
private void setReplaceProrationMode(
445-
BillingFlowParams.SubscriptionUpdateParams.Builder builder, int prorationMode) {
446-
// The proration mode value has to match one of the following declared in
447-
// https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.ProrationMode
448-
builder.setReplaceProrationMode(prorationMode);
449-
}
450-
451435
private void consumeAsync(String purchaseToken, final MethodChannel.Result result) {
452436
if (billingClientError(result)) {
453437
return;

packages/in_app_purchase/in_app_purchase_android/android/src/test/java/io/flutter/plugins/inapppurchase/MethodCallHandlerTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -807,13 +807,13 @@ public void launchBillingFlow_ok_Proration_with_null_OldProduct() {
807807
String accountId = "account";
808808
String queryOldProductId = "oldFoo";
809809
String oldProductId = null;
810-
int prorationMode = BillingFlowParams.ProrationMode.IMMEDIATE_AND_CHARGE_PRORATED_PRICE;
810+
int replacementMode = BillingFlowParams.SubscriptionUpdateParams.ReplacementMode.CHARGE_PRORATED_PRICE;
811811
queryForProducts(unmodifiableList(asList(productId, queryOldProductId)));
812812
HashMap<String, Object> arguments = new HashMap<>();
813813
arguments.put("product", productId);
814814
arguments.put("accountId", accountId);
815815
arguments.put("oldProduct", oldProductId);
816-
arguments.put("prorationMode", prorationMode);
816+
arguments.put("replacementMode", replacementMode);
817817
MethodCall launchCall = new MethodCall(LAUNCH_BILLING_FLOW, arguments);
818818

819819
// Launch the billing flow

packages/in_app_purchase/in_app_purchase_android/example/lib/main.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,8 @@ class _MyAppState extends State<_MyApp> {
427427
changeSubscriptionParam: oldSubscription != null
428428
? ChangeSubscriptionParam(
429429
oldPurchaseDetails: oldSubscription,
430-
prorationMode: ProrationMode
431-
.immediateWithTimeProration)
430+
replacementMode:
431+
ReplacementMode.withTimeProration)
432432
: null);
433433
if (productDetails.id == _kConsumableId) {
434434
_inAppPurchasePlatform.buyConsumable(

packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_client_wrapper.dart

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ class BillingClient {
215215
/// existing subscription.
216216
/// The [oldProduct](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.Builder#setOldPurchaseToken(java.lang.String)) and [purchaseToken] are the product id and purchase token that the user is upgrading or downgrading from.
217217
/// [purchaseToken] must not be `null` if [oldProduct] is not `null`.
218-
/// The [prorationMode](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.Builder#setReplaceProrationMode(int)) is the mode of proration during subscription upgrade/downgrade.
218+
/// The [replacementMode](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode(int)) is the mode of replacement during subscription upgrade/downgrade.
219219
/// This value will only be effective if the `oldProduct` is also set.
220220
Future<BillingResultWrapper> launchBillingFlow(
221221
{required String product,
@@ -224,7 +224,7 @@ class BillingClient {
224224
String? obfuscatedProfileId,
225225
String? oldProduct,
226226
String? purchaseToken,
227-
ProrationMode? prorationMode}) async {
227+
ReplacementMode? replacementMode}) async {
228228
assert((oldProduct == null) == (purchaseToken == null),
229229
'oldProduct and purchaseToken must both be set, or both be null.');
230230
final Map<String, dynamic> arguments = <String, dynamic>{
@@ -234,8 +234,8 @@ class BillingClient {
234234
'obfuscatedProfileId': obfuscatedProfileId,
235235
'oldProduct': oldProduct,
236236
'purchaseToken': purchaseToken,
237-
'prorationMode': const ProrationModeConverter().toJson(prorationMode ??
238-
ProrationMode.unknownSubscriptionUpgradeDowngradePolicy)
237+
'replacementMode': const ReplacementModeConverter()
238+
.toJson(replacementMode ?? ReplacementMode.unknownReplacementMode)
239239
};
240240
return BillingResultWrapper.fromJson(
241241
(await channel.invokeMapMethod<String, dynamic>(
@@ -619,74 +619,74 @@ class ProductTypeConverter implements JsonConverter<ProductType, String?> {
619619
String toJson(ProductType object) => _$ProductTypeEnumMap[object]!;
620620
}
621621

622-
/// Enum representing the proration mode.
622+
/// Enum representing the replacement mode.
623623
///
624624
/// When upgrading or downgrading a subscription, set this mode to provide details
625-
/// about the proration that will be applied when the subscription changes.
625+
/// about the replacement that will be applied when the subscription changes.
626626
///
627-
/// Wraps [`BillingFlowParams.ProrationMode`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.ProrationMode)
627+
/// Wraps [`BillingFlowParams.SubscriptionUpdateParams.ReplacementMode`](https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.SubscriptionUpdateParams.ReplacementMode)
628628
/// See the linked documentation for an explanation of the different constants.
629629
@JsonEnum(alwaysCreate: true)
630-
enum ProrationMode {
630+
enum ReplacementMode {
631631
// WARNING: Changes to this class need to be reflected in our generated code.
632632
// Run `flutter packages pub run build_runner watch` to rebuild and watch for
633633
// further changes.
634634

635635
/// Unknown upgrade or downgrade policy.
636636
@JsonValue(0)
637-
unknownSubscriptionUpgradeDowngradePolicy,
637+
unknownReplacementMode,
638638

639639
/// Replacement takes effect immediately, and the remaining time will be prorated
640640
/// and credited to the user.
641641
///
642642
/// This is the current default behavior.
643643
@JsonValue(1)
644-
immediateWithTimeProration,
644+
withTimeProration,
645645

646646
/// Replacement takes effect immediately, and the billing cycle remains the same.
647647
///
648648
/// The price for the remaining period will be charged.
649649
/// This option is only available for subscription upgrade.
650650
@JsonValue(2)
651-
immediateAndChargeProratedPrice,
651+
chargeProratedPrice,
652652

653653
/// Replacement takes effect immediately, and the new price will be charged on next
654654
/// recurrence time.
655655
///
656656
/// The billing cycle stays the same.
657657
@JsonValue(3)
658-
immediateWithoutProration,
658+
withoutProration,
659659

660660
/// Replacement takes effect when the old plan expires, and the new price will
661661
/// be charged at the same time.
662-
@JsonValue(4)
662+
@JsonValue(6)
663663
deferred,
664664

665665
/// Replacement takes effect immediately, and the user is charged full price
666666
/// of new plan and is given a full billing cycle of subscription, plus
667667
/// remaining prorated time from the old plan.
668668
@JsonValue(5)
669-
immediateAndChargeFullPrice,
669+
chargeFullPrice,
670670
}
671671

672-
/// Serializer for [ProrationMode].
672+
/// Serializer for [ReplacementMode].
673673
///
674674
/// Use these in `@JsonSerializable()` classes by annotating them with
675-
/// `@ProrationModeConverter()`.
676-
class ProrationModeConverter implements JsonConverter<ProrationMode, int?> {
675+
/// `@ReplacementModeConverter()`.
676+
class ReplacementModeConverter implements JsonConverter<ReplacementMode, int?> {
677677
/// Default const constructor.
678-
const ProrationModeConverter();
678+
const ReplacementModeConverter();
679679

680680
@override
681-
ProrationMode fromJson(int? json) {
681+
ReplacementMode fromJson(int? json) {
682682
if (json == null) {
683-
return ProrationMode.unknownSubscriptionUpgradeDowngradePolicy;
683+
return ReplacementMode.unknownReplacementMode;
684684
}
685-
return $enumDecode(_$ProrationModeEnumMap, json);
685+
return $enumDecode(_$ReplacementModeEnumMap, json);
686686
}
687687

688688
@override
689-
int toJson(ProrationMode object) => _$ProrationModeEnumMap[object]!;
689+
int toJson(ReplacementMode object) => _$ReplacementModeEnumMap[object]!;
690690
}
691691

692692
/// Features/capabilities supported by [BillingClient.isFeatureSupported()](https://developer.android.com/reference/com/android/billingclient/api/BillingClient.FeatureType).

packages/in_app_purchase/in_app_purchase_android/lib/src/billing_client_wrappers/billing_client_wrapper.g.dart

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/in_app_purchase/in_app_purchase_android/lib/src/in_app_purchase_android_platform.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class InAppPurchaseAndroidPlatform extends InAppPurchasePlatform {
155155
oldProduct: changeSubscriptionParam?.oldPurchaseDetails.productID,
156156
purchaseToken: changeSubscriptionParam
157157
?.oldPurchaseDetails.verificationData.serverVerificationData,
158-
prorationMode: changeSubscriptionParam?.prorationMode),
158+
replacementMode: changeSubscriptionParam?.replacementMode),
159159
);
160160
return billingResultWrapper.responseCode == BillingResponse.ok;
161161
}

packages/in_app_purchase/in_app_purchase_android/lib/src/types/change_subscription_param.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ class ChangeSubscriptionParam {
1010
/// Creates a new change subscription param object with given data
1111
ChangeSubscriptionParam({
1212
required this.oldPurchaseDetails,
13-
this.prorationMode,
13+
this.replacementMode,
1414
});
1515

1616
/// The purchase object of the existing subscription that the user needs to
1717
/// upgrade/downgrade from.
1818
final GooglePlayPurchaseDetails oldPurchaseDetails;
1919

20-
/// The proration mode.
20+
/// The replacement mode.
2121
///
2222
/// This is an optional parameter that indicates how to handle the existing
2323
/// subscription when the new subscription comes into effect.
24-
final ProrationMode? prorationMode;
24+
final ReplacementMode? replacementMode;
2525
}

packages/in_app_purchase/in_app_purchase_android/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: in_app_purchase_android
22
description: An implementation for the Android platform of the Flutter `in_app_purchase` plugin. This uses the Android BillingClient APIs.
33
repository: https://github.com/flutter/packages/tree/main/packages/in_app_purchase/in_app_purchase_android
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+in_app_purchase%22
5-
version: 0.3.2
5+
version: 0.3.3
66

77
environment:
88
sdk: ^3.1.0

packages/in_app_purchase/in_app_purchase_android/test/billing_client_wrappers/billing_client_wrapper_test.dart

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -430,16 +430,15 @@ void main() {
430430
const ProductDetailsWrapper productDetails = dummyOneTimeProductDetails;
431431
const String accountId = 'hashedAccountId';
432432
const String profileId = 'hashedProfileId';
433-
const ProrationMode prorationMode =
434-
ProrationMode.immediateAndChargeProratedPrice;
433+
const ReplacementMode prorationMode = ReplacementMode.chargeProratedPrice;
435434

436435
expect(
437436
await billingClient.launchBillingFlow(
438437
product: productDetails.productId,
439438
accountId: accountId,
440439
obfuscatedProfileId: profileId,
441440
oldProduct: dummyOldPurchase.products.first,
442-
prorationMode: prorationMode,
441+
replacementMode: prorationMode,
443442
purchaseToken: dummyOldPurchase.purchaseToken),
444443
equals(expectedBillingResult));
445444
final Map<dynamic, dynamic> arguments = stubPlatform
@@ -452,7 +451,7 @@ void main() {
452451
expect(
453452
arguments['purchaseToken'], equals(dummyOldPurchase.purchaseToken));
454453
expect(arguments['prorationMode'],
455-
const ProrationModeConverter().toJson(prorationMode));
454+
const ReplacementModeConverter().toJson(prorationMode));
456455
});
457456

458457
test(
@@ -469,16 +468,15 @@ void main() {
469468
const ProductDetailsWrapper productDetails = dummyOneTimeProductDetails;
470469
const String accountId = 'hashedAccountId';
471470
const String profileId = 'hashedProfileId';
472-
const ProrationMode prorationMode =
473-
ProrationMode.immediateAndChargeFullPrice;
471+
const ReplacementMode prorationMode = ReplacementMode.chargeFullPrice;
474472

475473
expect(
476474
await billingClient.launchBillingFlow(
477475
product: productDetails.productId,
478476
accountId: accountId,
479477
obfuscatedProfileId: profileId,
480478
oldProduct: dummyOldPurchase.products.first,
481-
prorationMode: prorationMode,
479+
replacementMode: prorationMode,
482480
purchaseToken: dummyOldPurchase.purchaseToken),
483481
equals(expectedBillingResult));
484482
final Map<dynamic, dynamic> arguments = stubPlatform
@@ -491,7 +489,7 @@ void main() {
491489
expect(
492490
arguments['purchaseToken'], equals(dummyOldPurchase.purchaseToken));
493491
expect(arguments['prorationMode'],
494-
const ProrationModeConverter().toJson(prorationMode));
492+
const ReplacementModeConverter().toJson(prorationMode));
495493
});
496494

497495
test('handles null accountId', () async {

packages/in_app_purchase/in_app_purchase_android/test/in_app_purchase_android_platform_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ void main() {
814814
oldPurchaseDetails: GooglePlayPurchaseDetails.fromPurchase(
815815
dummyUnacknowledgedPurchase)
816816
.first,
817-
prorationMode: ProrationMode.deferred,
817+
replacementMode: ReplacementMode.deferred,
818818
));
819819
await iapAndroidPlatform.buyNonConsumable(purchaseParam: purchaseParam);
820820

0 commit comments

Comments
 (0)