I have an application and I am trying to understand in-app billing. I want to do this : If a user buys an item with in-app billing. user can use this item with same account in different device without paying again. So my scenerio is this:
Assume that I have a application and it has in-app billing V3 service. And then a user purchases an "Managed Product" item and the user has an another device then the user wants to install this purcashed item in other device without paying again. But I read here, people talk about this problem:
BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED
At this point I am thinking to consume this product as soon as it is purchased. with this code:
mHelper.consumeAsync(inventory.getPurchase(SKU_MY_ITEM), mConsumeFinishedListener);
if it right way. what will the user see after clicking buy button in another device.(is it possible free purchase)
Also I am not sure what will happen, if the user uninstall and install again my app. what will user see if click a buy button. (purchase again or free purchase or a ERROR)
Can you give advice about in app-billing service for 1 account and many device and also about what will see a user if try to purchase in another device even everything goes right.
From here http://developer.android.com/google/play/billing/api.html :
Managed In-app Products
Managed in-app products are items that have their ownership
information tracked and managed by Google Play. When a user purchases
a managed in-app item, Google Play stores the purchase information for
each item on a per-user basis. This enables you to later query Google
Play at any time to restore the state of the items a specific user has
purchased. This information is persistent on the Google Play servers
even if the user uninstalls the application or if they change devices.
What you want to do is ( like in the example app ) query the inventory on successful setup of your in app service and consume any managed item thus granting access to it.
Related
I have developed an app in which I want to give a premium version of an app with ad removal and some extra features in-app products.
So, my question is how to verify if a user had purchased already; Then, when a user opens the app, I know if I should give them a premium interface.
Here's the documentation overview for In App Billing, where it says:
Google Play tracks and manages the ownership information of managed products. When a user purchases a managed product, Google Play stores the purchase information for each product on a per-user basis. This enables you to later query Google Play at any time to restore the state of the products a specific user has purchased. This information is persistent on the Google Play servers even if the user uninstalls the application or if they change devices.
To provide premium content, you'll need to create a managed product that doesn't get consumed in the app when the user purchases it. In order to query the user's in-app purchases, send a getPurchases() request, that will return all the current un-consumed products owned by the user.
If you find the premium content in this response, you know the user has purchased it and can grant them the premium interface.
Google Play Billing AIDL is now deprecated and will be removed in a future release. To implement Google Play Billing features, use the Google Play Billing library and to get purchases details for all the items bought within your app use: queryPurchases(skuType).
I am facing a critical edge case on my app. I will try to explain the situation.
I have an app which offers some premium content via in-app purchase. The user has one email id associated with Play Store on his device.
Here is the scenario:
1) The user logins in to the app using abc#gmail.com and purchases the premium content. This person has never purchased the premium content so his "isPremiumPurchased flag is false.
The purchase is successful and I grant him the premium content and change the flag to true. Works as expected.
2) The user logs out of his account in my app and logs in to my app again using a different account, say xyz#gmail.com. He goes on to purchase the premium content again. This account is a different account so his "isPremiumPurchased" flag is false.
This user has a separate account from the previous one, right? But if he tries to purchase, I always get "Item Already Owned", which is expected as well. The item was purchased already by another account associated with the same Play Store address, and now this account cannot purchase it.
What should the be ideal way to handle this scenario? I should not allow the second account to have access to the premium content. This is a completely separate account, isn't it? I cannot even consume the item. How can I solve this problem
If you want to differentiate the purchase based on the email used in your app, the purchase must be asociated to the email used to login to your app. I am not sure, but you can use developerPayload parameter for this.
Purchase:
iabHelper.launchPurchaseFlow(activity, SKU1, RC_REQUEST, purchaseListener, current_email);
Validation:
private boolean validateDeveloperPayload(Purchase purchaseDetails) {
String payload = purchaseDetails.getDeveloperPayload();
if(payload.equals(current_email)){
return true;
}
return false;
}
Very Simple. In app Purchases are associated with the primary account in Google Play store.
Say, you have an account myaccount#gmail.com associated to Google Play Store.
Here is the scenario:
1) The user logins in to the app using abc#gmail.com and purchases the
premium content. This person has never purchased the premium content
so his "isPremiumPurchased flag is false.
The purchase is successful and I grant him the premium content and
change the flag to true. Works as expected.
The premium content purchase is associated with myaccount#gmail.com not with abc#gmail.com which is local to your app.
2) The user logs out of his account in my app and logs in to my app
again using a different account, say xyz#gmail.com. He goes on to
purchase the premium content again. This account is a different
account so his "isPremiumPurchased" flag is false.
This user has a separate account from the previous one, right? But if
he tries to purchase, I always get "Item Already Owned", which is
expected as well.
The user logs out from yor app not from the Google Play. Thus when you check the purchse state of premium item, Google play responds you as it is purchased.
The item was purchased already by another account
associated with the same Play Store address, and now this account
cannot purchase it.
Please make sure where the account are being switched, is it inside your app or Google accounts?
Here is a small brief;
Download & Install app from playstore with account 'xxx#gmail.com', Purchase an item.
Add google accounts in device 'yyy#gmail.com' in which the item purchase not yet done.
Switch playstore to the account yyy#gmail.com and test item.
Item is in PURCHASE state only.
The account with which the app is downloaded is treated as PRIMARY ACCOUNT to check with purchase details from playstore
Download & Install app from playstore with account 'xxx#gmail.com', Purchase an item.
Add google accounts in device 'yyy#gmail.com' in which the item purchase not yet done.
Switch playstore to the account yyy#gmail.com and test item.
Item is in PURCHASE state only.
Remove account, xxx#gmail.com from the device, and check the item.
Item is in UNPURCHASED state.
Since 'xxx#gmail.com' is removed, primary account is 'yyy#gmail.com'.
Now the IN APP ITEMS for 'yyy#gmail.com' are not purchased.
I've implemented API version 3 of GooglePlay Inapp purchase.
I'm logged in with the same Google account on two devices.
On device #1, I've just purchased an item using this: https://developer.android.com/google/play/billing/billing_integrate.html#Purchase
When I immediately query the purchased items (on device #1) with: https://developer.android.com/google/play/billing/billing_integrate.html#QueryPurchases it returns the info of the in-app so everything is fine.
When I query the list of purchases on device #2, it won't return the item I've just purchased, it returns an empty list.
When I try to buy the item on device #2 it tells me I already own it.
Any ideas on why the purchase from device #1 is not reflected on device #2 ?
Please note that the inapps are Managed products, so Google should hande the syncing across different devices with the same google account, right ?
Invalidating a purchase to test it again
This applies to products that the user can buy only once. This means that you don’t consume the purchase. More on consumption later.
In this case, after you make a purchase, if you will try to purchase it again you will receive an error saying that you already own this item.
How do you get past that?
You refund the purchase from Google Play Console. But there’s a catch. When you refund it you will have to remove the entitlement for that product, or the user will still get the error that it already owns the item.
For that, you go into Order Management from Google Play Console main menu and select the Order you just made from your app. (If it’s a test order it will say Test: in front of the product name). Then in order details, you click refund and a screen with some options for a refund like the one below will appear.
In this screen, make sure to check the Remove entitlement box, so the user will no longer own the product in his Google Account. After you click refund you will be able to make a purchase again for the given product.
It seems that it takes a while for the changed to actually take place on GooglePlay. The device on which I buy the item, seems to cache that I did so, and instead of asking GooglePlay, it takes that from a local cache.
That's why another device did not know about the purchase.
It took about an hour for the second device to receive the purchase info from GooglePlay.
I got my current app in test with some items to testpurchase. And I´ve done that now but I need to do further testing on those items. Is there a way to simply "restore" those purchases so that I dont get that error "You already own this item" ?
There is a way:
Once an in-app product is purchased, it is considered to be "owned".
In-app products in the "owned" state cannot be purchased from Google
Play. You must send a consumption request for the "owned" in-app
product before Google Play makes it available for purchase again.
Consuming the in-app product reverts it to the "unowned" state, and
discards the previous purchase data.
I have working app that sells in-app products (InApp billing v3).
Recently I've made an update for this app and made a terrible mistake there: I consumed some of purchases I didn't want to consume.
I issued an update and users updated the app and then wrote me they have no purchased access. (As I found later, I consumed wrong items).
So I have some questions now:
Is there a way to restore consumed purchases or I should return payments to my users?
Is there a way to find out how many and which purchases were consumed?
If returning payments, is there a way to find out if user still has the product or is it consumed with out changing the app (through google services)?
Thanks.
According to what I have understood from your question, It seems like you want to purchase product only once.
What I wished to ask: is there a way to request information about consumed products like about owned products.
you can get response or it's information in any type(Managed Product, Unmanaged Product, Subscription) in the onActivityResult method() check my below link.
In-app billing-v3 error in activity result
but I would not prefer you to manage it customly as you told for one time purchase product(not consumable product). You should go with the Manage product.
Managed In-app Products:
Managed in-app products are items that have their ownership
information tracked and managed by Google Play. When a user purchases
a managed in-app item, Google Play stores the purchase information for
each item on a per-user basis. This enables you to later query Google
Play at any time to restore the state of the items a specific user has
purchased. This information is persistent on the Google Play servers
even if the user uninstalls the application or if they change devices.
for more information about product type
you can query any time you want and you will get the product information, and even you don't need to manage if user has already purchase this product or not.
Is there a way to restore cnsumed purchases or I should return payments to my users?
Better option is you should give the payments back to the user and for the next time check the whole app once using dummy product "android.test.purchased" and update your app.
Is there a wat to find out how many and which purchases were consumed?
You have to check in the Google wallet because all transaction should be handle by the it, check if it gives you product type or not. Using your google developer console credential you can signed into google wallet.
If returning payments is there a way to find out if user stil has the product or is it consumed with out changing the app (through google services)?
as per above answer you have to check in google wallet, according to my knowledge they are provide us all of information about product type with user detail.
Let me know if I have not properly understood your question.
Hope it will solve your problem.