cozycodegh / cordova-plugin-inapppurchases

2023-2024 cordova plugin to add in-app purchases and subscriptions into an iOS or Android app
MIT License
9 stars 4 forks source link

Allow Android App to upgrade or downgrade #8

Closed marjika closed 10 months ago

marjika commented 10 months ago

Hello, thank you for this plugin. I have been working on a cordova app for several years now and am trying to test and then promote my app on the play store. I would like to allow my user to upgrade or downgrade through the three subscriptions I offer. Android implements upgrades and downgrades differently form App Store Connect. Android developer information offers this suggestion to implement upgrade and downgrade. Unfortunately my Java ability is pretty low, so I'm not sure how to execute those directions. I can see "BillingFlowParams billingFlowParams" in the IabHelper.java file, line 645, in the launchBillingFlowAsync method which is used in the InAppBilling.java file, lines 483 and 492, eventually going back to the purchase method on line 593 in the same file. You would need to pass back the old and new subscriptions and the replacement mode indicating any change in the billing and access because of the upgrade or downgrade in the inAppPurchase.purchase() method. I have looked through the code, forks, and pull requests and don't see any indication that this has been addressed so please let me know if this has already been implemented. Thanks in advance, Marjika

cozycodegh commented 10 months ago

Hi Marjika,

Currently this has not been implemented. Thanks for the link, looks like it would be just adding another line to the purchase call, which uses the purchase token and an upgrade type in order to upgrade and downgrade.

I could look into adding this for Android only sometime this week. Is that what was needed for your app?

marjika commented 10 months ago

Hi, Thank you for your reply!

Yes, this is specifically for the Android part of my app. I can upgrade and downgrade automatically (sort of) with iOS as they have a built-in functionality where you order the different pricing levels within one subscription and the app store does the rest.

Not being familiar with the Android Billing library and with my very basic Java knowledge, I wasn't sure if there was an object, either a JSON object sent to the Java billing code or the IabNext object (when that was created, what could be accessed there) or some other object from Android's billing library, with information about the previous subscription that could be accessed or if that specifically should just be added to the purchase call. I am already saving the purchase token to the user's subscription so I can get the subscription when I get a renewal notification, so that would be easy for me to just get and add to the purchase call on an upgrade/downgrade if the arguments allowed it.

I am planning on using the recommended replacement modes (i.e. CHARGE_PRORATED_PRICE on upgrade and DEFERRED on downgrade) so I'm happy either way works best, either send upgrade or downgrade as just two options for the replacement mode if that's easier for error handling or allow whatever replacement mode options are available (found here: https://developer.android.com/google/play/billing/subscriptions#replacement-modes) for that method call ".setSubscriptionReplacementMode(ReplacementMode.[replacement mode])" and have that as another parameter/argument in the inAppPurchases.purchase() method.

Please let me know if I'm not explaining myself well enough here. I've only been working with the play store a short time so I'm still unfamiliar with the libraries, etc.

Thanks, Marjika


From: CozyCode @.> Sent: Wednesday, December 13, 2023 9:26 AM To: cozycodegh/cordova-plugin-inapppurchases @.> Cc: Marjika Howarth @.>; Author @.> Subject: Re: [cozycodegh/cordova-plugin-inapppurchases] Allow Android App to upgrade or downgrade (Issue #8)

Hi Marjika,

Currently this has not been implemented. Thanks for the link, looks like it would be just adding another line to the purchase call, which uses the purchase token and an upgrade type in order to upgrade and downgrade.

I could look into adding this for Android only sometime this week. Is that what was needed for your app?

— Reply to this email directly, view it on GitHubhttps://github.com/cozycodegh/cordova-plugin-inapppurchases/issues/8#issuecomment-1854259319, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AGGJ75FG4BQJ7BW2AZX5PA3YJHJL7AVCNFSM6AAAAABASFEAOOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNJUGI2TSMZRHE. You are receiving this because you authored the thread.Message ID: @.***>

cozycodegh commented 10 months ago

Yeah, I see what you’re saying.

The plugin now has the new subscription upgrade replacement modes. The purchase call is updated to have an optional argument for the replacement mode. There is an inAppPurchases.subscriptionReplacementMode object with the modes, so it can be called: inAppPurchase.purchase(product_id,inAppPurchases.subscriptionReplacementMode.CHARGE_FULL_PRICE); The purchase token will be sent along automatically.

To update the plugin, add and remove the plugin and Android platform https://cozycode.ca/post?pon=cordova-plugin-inapppurchases

cozycodegh commented 10 months ago

Ah, I realized that this isn’t working for different replacement modes as that’s for switching across subscriptions. It will need the purchase token or the product id to switch from. The new update will be out soon!

cozycodegh commented 10 months ago

The plugin released today has the subscription upgrades in Android with the command: inAppPurchase.purchase(new_product_id, upgrading_product_id, inAppPurchases.subscriptionReplacementMode.DEFERRED); It can be called with the new subscription's product id, current subscription’s product id, and the replacement mode.

See the parameters on the purchase document: https://github.com/cozycodegh/cordova-plugin-inapppurchases/blob/main/docs/purchase.md

marjika commented 10 months ago

Hello, Thank you for that update you published last week. I have been testing the new code in my app, and I have a question about a problem that I've had with downgrading a subscription. For testing purposes, I have been logging the returned receipt from the inapppurchases plugin following purchase in my AWS logs. Following, the update, rebuild, reupload to play store, I attempted to upgrade a subscription from a "monthly_individual" to a "monthly_family", which I got to work after a little debugging of my code. The receipt is pasted below upgrade I add the "productType" property for use in my app and back end, and in this case, it matches the expected purchased product (I use a shortened form for my subscription object, but I handle the differences). However, when I attempted a downgrade today from a "monthly_coparents" subscription to "monthly_individual", the receipt returned from inapppurchases productId did not match the expected product id that the user switched to and the completePurchase() method failed (the purchase() method succeeded but not completePurchase()). This picture shows the log for the downgrade where the productId and expected product type do not sync up. The productId returned in the receipt is the old one, not the new productId as it was when I upgraded. downgrade In both cases, I use the inapppurchases.purchase() method with the new product id first, the old (existing) product id second, and subscriptionReplacementMode as CHARGE_PRORATED_PRICE for upgrade and DEFERRED for downgrade. In both cases, I use the completePurchase() method using the new subscription id. It worked fine for upgrade and not for downgrade. Normally, I would feel that I did something wrong in my code, but because the receipt comes back with the wrong purchaseId in the second case, I suspect that has something to do with completePurchase() throwing an error. When that happens, I get a cancelled test subscription from the play store after a few minutes. I'd appreciate any help or advice you could give me.
Also, the purchaseToken was removed from the receipt in the purchase method (line 245ish in billing-android.js) after the last upgrade. I added that back into the code myself for my own build so it was fine, but it definitely helps to have it there for unique subscription identification. Thank you, thank you again for your help so far. It is wonderful for a small, one-person operation like mine to have these tools in trying to create a new app when I don't have the knowledge of Java and Swift (? I think) to do it myself.

cozycodegh commented 10 months ago

Looks like for the deferred purchases it returns the original product id so the complete purchase doesn’t go through afterwards… I think it will be completed if you completePurchase with the original product id, instead of the new one for those.

Ah, thanks the purchaseToken was missing from the android file.

Big fan of the Cordova project for putting apps together. Great to program in HTML and JS.

marjika commented 9 months ago

Good morning, thanks for your response and Happy New Year! I adjusted my code to use the original product id with completePurchase() on a downgrade as you suggested and that seems to work well. The purchase completes without errors, and the subscription renews every 5 minutes as expected in the test environment I'm using. I'll keep testing and be in touch if there are any more issues, but this has been a very helpful feature, essential for upgrading and downgrading subscriptions for Android devices. Thanks again for your suggestions and help!