Are auto-renewing android in-app subscriptions have to be consumed? - java

After hours reading documentation about android in-app product and subscription I am still stuck asking me about consumption process regarding in-app auto-renewing subscription.
What Google says about consuming
It's up to you to decide if you want to handle your managed products as non-consumable or consumable items
Non-consumable products
Typically, you would not implement consumption for managed products that can only be purchased once in your application and provide a permanent benefit. Once purchased, these products will be permanently associated to the user's Google account. An example of a non-consumable managed product is a premium upgrade or a level pack.
Consumable products
In contrast, you can implement consumption for products that can be made available for purchase multiple times. Typically, these products provide certain temporary effects. For example, the user's in-game character might gain life points or gain extra gold coins in their inventory. Dispensing the benefits or effects of the purchased product in your application is called provisioning the managed product. You are responsible for controlling and tracking how managed products are provisioned to the users.
In the other hand the Google Play Billing tell us that we have the following types of in-app products :
One-time products (managed products)
Rewarded products
Subscriptions
Reading this we could think that subscriptions aren't managed product..
I am trying to refacto a part of an app, at the moment the current version get the inventory (with an IabHelper), get the last monthly purchase (proceed automatically by google), send the information to our API to get user premium again and consume this last purchase after the API result.
Because I am now checking the monthly payments directly from our API, to remove this part from the Android app :
Do we absolutely have to consume the monthly purchase proceed automatically with the auto-renewing Google in-app ?

After working around in-app subscription (with our own API/Server) process for Android and iOS app, I think I found my answer.
When a Android or iOS user makes a subscription, my app (in my case) completes the transaction and sends it to our own API (through /android_purchase POST) with some parameters (see the workflow above).
Right after our API verifies the transaction with Google (through /verify) and sends back the answer to our apps (giving the user access to premium content or not depending on the /verify result)
But how your API can know if the user cancel the subscription or just know if the subscription has been renewed correctly ?
Actually (and a lot of developer reading this know that) Google and Apple allow you to give them an API endpoint to get notified (in my case /in_app_notifications).
Thanks to this feature, Google will notify us for each renewal or cancelation or even the first subscription action.
You can find some documentation about it here https://developer.android.com/google/play/billing/realtime_developer_notifications.html
This kind of workflow let us implement a clean workflow without any front-side check. Actually some apps check the last user payment at each app launch to notify the API and keep the user premium or not.
What if the user doesn't open your app for two months ?
Do you really think that the subscription is canceled by Google and Apple ?...
In my mind the answer is no. For me, this workflow demonstrates that it's not the case. In the same way, if your android app doesn't consume the item purchased (in my case of a monthly in-app subscription) it won't "break" the subscription. Android will renew it at the end of the month and notify your API.
I know that my answer is not complete, and may be some developers will share some others searches, but I was struggling with this question about in-app subscription process and I wanted to share my findings to save your time if you are in the same situation !

Related

Is there anyway to test subscription items of google in-app billing without making their state active in google play console?

I have a problem with testing subscription items in my app. Regarding the In-App billing documents that I read and stack-overflow posts,
as far as I understood, for testing Subscription Items in In-app billing we have two options:
Solo testing (Which is not possible for subscription items). So this Item is not possible for us.
Google docs: Note: Static responses cannot be used to test subscriptions.
The product Id which is trying to purchase should be active in Google play console. Since we can not make them active because production users will see those items, we need to find another way.
Google docs: To be available for purchase, a product needs to be active, and its app needs to be published.
Questions:
Is there any way to test subscription items without making them active in Google play console?
Is there any sandbox mode just like apple in-app purchase or Amazon in-app purchase?
If a subscription item is 'active' in the play console, users wouldn't be able to see it unless your app specifically queries for the sku (the product ID that was set in the Play Console).
For example, in the official play billing sample app, we store all the skus that are defined in the play console and only query for the skus we have defined in the app code. This means that we can add additional in-app products in the play console without production users seeing it as long as the code that queries for the products isn't shipped to production as well.

Handling in-app purchases / consumable products across sessions/devices?

My question is centered around handling in-app purchases for consumables with Google's In-App Billing API. (https://developer.android.com/google/play/billing/api.html#consumetypes)
Their documentation describes consumables as:
Consumable products
In contrast, you can implement consumption for products that can be made available for purchase multiple times. Typically, these products provide certain temporary effects. For example, the user's in-game character might gain life points or gain extra gold coins in their inventory. Dispensing the benefits or effects of the purchased product in your application is called provisioning the managed product. You are responsible for controlling and tracking how managed products are provisioned to the users.
A consumable item is something that could be purchased several times (like in game currency, an in game item or upgrade that is used, etc.), whereas a non-consumable can only be purchased once (no-ads, a skin / character, etc.)
In the documentation on consuming a purchase (https://developer.android.com/training/play-billing-library/purchase-iab-products.html), it also mentions:
How you use the consumption mechanism in your app is up to you. Typically, you would implement consumption for products with temporary benefits that users may want to purchase multiple times, such as in-game currency or replenishable game tokens. You would typically not want to implement consumption for products that are purchased once and provide a permanent effect, such as a premium upgrade.
It's your responsibility to control and track how the in-app product is provisioned to the user. For example, if the user purchased in-game currency, you should update the player's inventory with the amount of currency purchased.
My question is how to keep track of user inventory for consumable products? The documentation and various videos seem to quickly gloss over this, basically saying the app must apply the effects of the consumable when it gets confirmation of a successful purchase. But that isn't really the full picture. What if a user signs out and signs back in with a different account? Or they switch to a new phone, they should have the product on that phone.
You can't really save record of the purchase in SharedPreferences or a persistent cache because it is tied to the phone. If a user signs in on a different phone then they should have the benefits of all the purchases they made.
Take the following example:
A game starts players with 1000 gold. Player buys 500 more gold through an in-app purchase, then spends 200 gold. If player buys a new phone and installs that app on that phone, they should have 1300 gold.
How is this normally accomplished?
Do you need to run a private server that keeps track of purchases/consumption of such things separate from Google?
Thanks!!
I am implementing in-app purchase myself.
Do you need to run a private server that keeps track of purchases/consumption of such things separate from Google?
Yes of course as Google suggests in Security Best Practices
It's highly recommended to validate purchase details on a server that you trust. If you cannot use a server, however, it's still possible to validate these details within your app on a device.
Your second question
What if a user signs out and signs back in with a different account?
Tie the orderId to account or device.
In the first case, you can easily manage the purchase when the user switches the devices(another reason to get a private server).
While in the second case you can allow switching accounts on the same device.
So it's up to you which one to select.
You need to Synchronize local consumption to the server.
This is the flow for Verifying the purchase:
User clicks “BUY” button.
Makes payment with google.
App receives “receipt” from google and store it locally
Send this “RECEIPT” to the Server.
The Server sends the “purchaseToken” to Google Play Developer API for validation
The Google Play Developer API sends response with status code.
Store the RECEIPT in the server database (If we you to keep history of purchases by users).
This is the flow for Consuming the product:
The user opens the app.
App assigns values to the Resources by reading from local storage.
App tries to synchronize with the Server.(checks last updated timestamp)
Different scenarios:
Synchronization Successful: Assigns Resource values from the server. Set newly retrieved values in the local storage.
Synchronization Failed: Keep Resource values and try again.
User consumes the Resource.
App updates local values in Resource and sync with the server.(checks last updated timestamp)
I used Following articles:
Tutorial: How to Implement In-app Billing in Android LINK
Article on implementing InApp purchase LINK.
How to verify purchase for android app in server side (google play in app billing v3) LINK.
Another SO answer LINK.
Another SO answer LINK.
Code Project Sample LINK.

Offering users pro features vs normal users

For about 2 years I've been developing a business card reader application and I've published 2 versions of it on the Google Play Store (one paid and another free).
Recently I've decided to offer cloud storage for those business cards. I've created my PHP backend and it's almost contested, but I am facing one major issue.
I would like to offer the free users a chance to test my service and offer them a limited number of cloud cards, while the pro users would have unlimited number of cards to store.
I don't know what would be the best approach to accomplish this in order to offer my existing pro users this functionality while limiting them to only one account/app paid.
I was thinking about in-app purchases, but I don't see how I could unlock the purchase for the users who already both the app.
I am open to any suggestion!
In your MySQL database, add a column for cloud services expiry date. Now in PHP if your user chose try, store the date a month from now, and if they chose purchase, enter the date their purchase expires. Finally, before a user uses the service, check if the date has expired to determine whether to let them use the cloud service.

Android In-App Purchases responsibility

I am using Google Play In-App billing version 3. I want to users to pay to unlock level packs in my game. This will be a consumable purchase obviously.
If I consume these level pack purchases, am I responsible for tracking whether a level pack has been purchased, or can I rely on the billing API for this?
If I can rely on the billing API for this and the device has no network connection, will the device have a local cache of purchases I can query?
Personally, I think level packs are more suitable for managed (unconsumable) items.
You can create many sku(s) which correspond to each level pack.
Query items code looks like http://developer.android.com/training/in-app-billing/list-iab-products.html#QueryDetails or http://developer.android.com/training/in-app-billing/purchase-iab-products.html#QueryPurchases.
And yes, purchase items are cached locally by google play service, see description in above 2nd link.

Is there a way to forbid users from refunding in-app product

Right now I have my app set up so when the user completes a purchase, a TextView appears with a link to a Google Doc. If the user then cancels their purchase and gets a refund, they can easily just have downloaded and saved the Google Doc before refunding, correct?
If I am looking at this wrong, please correct me. If not, what can I do to solve this? Can I take away the option to refund this purchase? Is there a better way to go about providing a user with a .doc file after a purchase? I am asking this because since releasing the latest version of my app with this in-app purchase, I have seen all 4 purchases be refunded so far.
Example below of a "cancelled order":
Make your app free, and have the option to get the Google Doc available as an in-app purchase.
From "In-App Purchase Policy":
In-app purchases are different than other Android app purchases on
Google Play in two ways:
There is no 15-minute refund period - all refunds are at the discretion of the developer
Restoring in-app purchases are the responsibility of the developer
What you are doing is charging the user to download the app from the store. This purchase can be refunded within 15 minutes.
If you implement an in app purchase, as in the user downloads the app free, and there is a purchase button inside the app to reveal the download, then they cannot get a refund for that.
Just make sure that user will be able to download the full file after the refund period (15 minutes) will pass. Before that he should be able to download some sample file to decide if he want to get refund or not. You cannot just disable refund option, even if this would be possible it would be definitely bad practice...

Categories

Resources