Is there a way to check which users bought when a consumable of my app? Not in the app itself but in the developer console/order management. Currently I only see an order id and a token, but would need some custom information or at least the user's email address or sth like that...
Nope. You'll need to link purchases to userIds yourself. Google will link that purchase to the users Play Store account, so they can potentially restore the purchase if they've reinstalled the app or gotten a new phone.
If you don't want to manage your own server, it may be worth using a tool like RevenueCat, that offer a purchase/subscription backend-as-a-service.
Related
In my android application I want to let users to authenticate with google or facebook account.
I've implemented sign-in with google already.
I'll try to implement sign-in with facebook soon.
I've read about IAP in android:
https://developer.android.com/google/play/billing/billing_overview
https://droidmentor.com/inapppurchase-subscription/
at least what I understand it is about google account authentication.
So I wonder is it possible to make IAP in android application if the user is authenticated with facebook account ?
I cant find examples or explanations by now.
Any good examples/explanations about IAP with google is also very appreciated because I still don't have a clear vision on IAP.
fyi: In my app user will be able to buy "virtual tickets pack" (e.g.: 10, 15, 20 tickets) and to add them to their profile. and later they will "consume" tickets one by one.
Best Regards
My understanding is that you already have a user system that you are using to provide a Google login to your customers. When you add Facebook login, you'll probably want to match both Google and Facebook logins with your own custom user ID. It's always a good idea to have a custom ID of your own so that you can map it to different types of logins.
When purchasing through Google Play Billing, the purchase gets associated with the user's phone Google account and you can also provide an optional way of associating a purchase with your own user account system. In order to do that, when building the BillingFlowParams, call setAccountId and pass your account's system custom ID.
To provide the best experience persisting purchases during installs or across devices you should also be saving the purchases on your server's database. In order to do that in a secure manner, you will also have to implement server-side receipt validation. If you want to avoid most of these headaches, I recommend you to use a service like RevenueCat.
IAP can only be done through the user's google account, as that is what one needs to use any part of the Play Store. The user's google account is also where the credit card/other payment methods are stored for each user.
In spite of the above, the way users log into your app has nothing to do with them using the IAP system. When a user will choose to use an IAP, the google account data will be provided by the android device/Play Store, not by your app (Off subject:the process is similar on iOS if you ever get to try there).
What your app needs to do, is receive the confirmation of purchase from the IAP sdk and then mark on your server that this particular user has purchased this item. Basically for any purchases (no matter the payment provider) you would usually mark in your DB the following:
what the user has purchased
how much did he pay
when did he pay
provider's id of the purchase, so you can later match the accounting reports with the payment provider's report
where he payed from (IP can be a good indicator, although in the age of VPNs not necessarily 100% acurate)(this can be useful for your marketing decisions)
mark that this user now has access to the item he purchased and if it is a time limited item, mark when it expires, so you are able to later check if he still has the right to access it.
Disclaimer:
I have not used the android IAP system directly before. I have implemented mobile app payment systems before using iOS IAP and on android Braintree payments. But the process is most likely very similar with android IAPs as well.
Is it possible to check what date the app was actually purchased, Not the in-app purchases, the actual date the user purchased the original application from the google store. I have found things like packageInfo.firstInstallTime, but that changes if you clear the device and reinstall etc.
I'm not sure if this is on-topic, but the only way to store data across installations is to persist it somewhere (like a server). You would have to get the gmail account associated with the purchase, associate a purchase ID and then check purchase date.
This is flawed because a re-install on a new device would look the same as a re-install on an existing device. It's also possible for a user to have two devices with the same gmail account, and therefore two (or more) active, valid installs and a single purchase. Most, but not all devices have a unique device ID.
And while there is no Official Google Play API (to request the data from Google), here is a good link for unofficial/creative options for search and content, but nothing for transaction data (which would probably lead to security risks without an official API):
how to get information of google play store in my android application?
is that OK and safe to set a value in SharedPreference to flag that the user have purchased this item? What if user hack this value in SharedPreference. Or I need to connect IAP service everytime to check that before user can use it?
(1) What is the best practice when I use Google Android IAP V3?
(2) And also if user's device have no Google Play installed, I may want to use paypal to make the payment, but how to track the purchase and unlock the features for users if I ask user to use simple paypal payment to get a license key? I do not want to use any other billing SDK, if with Paypal web page to buy the license, How to implement this?
(1) What is the best practice when I use Google Android IAP V3?
--> official document says that only payment transaction will be handle by google play itself, but in the application you have to set your business logic how you handle UI integration and other things after product purchase. You can also go with the in app purchase v3.
(2) And also if user's device have no Google Play installed, I may want to use paypal to make the payment, but how to track the purchase and unlock the features for users if I ask user to use simple paypal payment to get a license key? I do not want to use any other billing SDK, if with Paypal web page to buy the license, How to implement this?
--> You can ask user to update google play version dynamically. Google developer doc says more than 90% device using 2.2 os with installed google play store. I could not say any thing about paypal transaction because I haven't use it before, but yes in app purchase using v3 is very simple to implement and understand the payment process.
How to use in your application
Three way to manage your application's product data.
1) SharedPrefrence:
you can use the share prefrence value and check whether it is purchased or not. if in case user uninstalled the app and then re-install the app then you can check whether user has purchased or not, at this you get the item is already purchased. And you have to manage the user to access your application data.
2) local database:
you can also use local sqlite database to store the purchase detail and purchase status. and same as above if user clear data or uninstall the app then request for the purchase item again and check whether user purchased item or not.
or
2) Server database:
It is the better way compare to above if you are using web server to store the user data. In this type, you doesn't even need to manage for the second time for the case if user uninstall the app or clear the application data.
3) obfuscation: (Most efficient way compare to shared prefrence)
EDIT:
is that OK and safe to set a value in SharedPreference to flag that the user have purchased this item? What if user hack this value in SharedPreference. Or I need to connect IAP service everytime to check that before user can use it?
While I am searching on internet I found Nikolay Elenkov's answer like below:
If you just save a flag in shared preferences, any user with a rooted
device can flip the flag at will and be 'subscribed' without paying.
So you should at least do some obfuscation. Here's a sample way to do
it. Additionally, there is an API to check for subscription state, so
you should check periodically to make sure the subscription is valid.
more information check Nikolay Elenkov's answer
What is the best for billing Either In app purchase or Paypal?
It is depends on the product type,
--> In app billing: Best for google in app billing,
For the digital products including downloadable content such as media
files or
photos, virtual content such as game levels or potions, premium
services and features, and more.
http://developer.android.com/google/play/billing/index.html
--> Paypal: Best for Paypal billing,
For physical content or product do you want to share. You are not
permitted to sell physical goods or services using 'In-App Purchasing'
since the goods purchased via this method must relate directly to the
app using them.
Purchase physical product from iPhone app without Apple in app purchase
Hope it will help you.
from the documentation:
Because the Google Play client now caches In-app Billing information
locally on the device, you can use the Version 3 API to query for this
information more frequently, for example through a getPurchases call.
Unlike with previous versions of the API, many Version 3 API calls
will be serviced through cache lookups instead of through a network
connection to Google Play, which significantly speeds up the API's
response time.
Which basically means you can look up the purchase each time and the Play Store app will respond pretty much right away.
From my experience I can assure you of one thing.
** In fact it's bad to put a flag with a bool saying if it's premium or not **.
What I do is obfuscate the shared code
After I create some strange strings or numbers that only identify through the code inside the app if the user is a premium user.
Along with this, except for a numeric code within the database that identifies the type of purchase. So by checking both I can make sure the user is premium.
At this point if they want to cheat me with the root of the phone they should first understand how the code of my app works and then understand where to interact, because if only the shared preferences change, nothing will change and they will be whipped.
** This doesn't translate to high security, but at least the security level is higher and the root won't be able to get a reward that easily. Also because they should understand what are the exact codes to insert in the shared, in the database and look for them by removing the obfuscation. I honestly don't think it's worth it for them. **
As what Kuffs has mentioned, it is best to query the app-side implementation of the In-App Billing library which in turn queries the device's Google Play client. This will ensure that the purchase history most recently obtained from the Google Play servers would be reliable and relatively fresh information.
Also, keep in mind that if you are distributing the app on Google Play you MUST use the Google Play payment mechanism via In-App Billing. As it stands, Google Play and Wallet do NOT yet support Paypal or wire/bank transfer methods so you should not integrate the option if you are releasing it on Play.
http://play.google.com/about/developer-content-policy.html#payments
I'm developing an app where you can remove ads an unlock some content with an upgrade with in-app billing.
My question is: how should I determine if the app is upgraded or not? It has to work offline, so after purchase state change the app has to know if it is upgraded. My idea is storing the main gmail account's address encrypted with sharedfreferences. This way the sharedpreferences file only works with one account, so people can't share it to get the paid content free. But using personal information like email adress requires risky premissions, so users may not download the app.
Is there any solution for this problem, which works offline and doesn't requires personal information?
My understanding of SharedPreferences was that any data stored by an app is private to that app. Using a putString() for example, you could hash and store something when a user purchases the upgrade. The something could be a hash of their email address, the transaction ID, it doesn't really matter.
Then on startup, check for the existence of this key and depending on that result, either display or remove the ads.
I have a few questions connected to Android In-App Billing:
Is it possible to make a purchase from non-Market app? I understand that it would be a vulnerability, but I have no opportunity to find out if it's possible or not.
How can I get purchase state for a particular product? As far as I understand it can be done using RESTORE_TRANSACTIONS request, but it's not recommended to use very often. That's not a theoretical problem. My application allows users to buy content using in-app billing. Content can be downloaded from a server, and server must allow content downloading only if it was purchased. But it can't check if content was purchased or not without using signed response from Android Market.
How can I get price and description of an item from Android Market? Seems that I know the answer and it's "there's no way it can be done", but maybe I'm wrong. It would be very useful to have a possibility of retrieving item's price.
It's very interesting to me how you solved/are going to solve these problems in your apps. Answer to any of these questions will be appreciated.
In order:
1- Nope. The in-app billing process is part of Market. If the app comes from elsewhere, there's no way for Market to verify the origin/authenticity of the application.
2- It's your responsibility to store the purchase state for a particular product. From the doc:
You must set up a database or some other mechanism for storing users' purchase information.
RESTORE_TRANSACTIONS should be reserved for reinstalls or first-time installs on a device.
3- Unfortunately, at this time you're right. File a feature request!
In the meantime, one option is to set up a website with appengine, store listings of all your content & pricing there, and then manually sync prices listed on your appengine server with the updated prices in Market. Then have your Android app pull the data from the AppEngine server. This is much better than hardcoding price values into the app itself, since you don't need to have everyone update the app immediately to see accurate pricing whenever you change something. The only caveat of this method is that if the user is in a different country, in-app billing will display an approximated price in their native currency, and there's no way for you to determine exactly what price will be displayed to them.
Related, One of the Android Developer Advocates is giving a talk on LVL/IAP at IO, called "Evading Pirates and Stopping Vampires using License Verification Library, In-App Billing, and App Engine." - It would definitely be worth your while to watch when they release the session videos on the website.