I use Google LVL and Google Inapp Billing API ver 3 in my java application for Android. Of course I use (slightly modified) LVL library project from Google extras and IAP jar that Google suggests.
LVL library LicenseValidator in verifyLicense receives ResponseData with user-id in it. It is said in Google docs that it is an unique user ID, representing user's google account used for purchase. So I assumed (and made sure in tests) it is the same string (for example, "ANlOH<...>ppA==") on all devices where user has logged in with the same Google account.
So here is my iap purchase protection scheme in short.
Before the purchase app sends user-id to my server. It generates an encrypted payload from user-id and sends it back. App makes a purchase request and puts payload in it. App receives a receipt signed by Google, that holds the same payload. App sends this receipt to my server with the current user-id. Server makes signature and other checks, compares user-ids from payload and from sender and if everything is fine sends files of iap item to the app.
In another scenario, when the user reinstalls the app to this or another device, app gets receipts belonging to him from InAppBilling, sends them to my server with the current user-id. Server performs the same checks and - if everything is fine - sends all needed files to the app.
This approach with small differences works well on other platforms. But I have experiencing some strange glitches recently on Android app. My server logs receipt check issues and I have found strange errors: user with one user-id sent correctly signed receipts belonging to another user-id (payload in receipt holds that another user-id). When I started to investigate I've found that one of such strange "hacker attack" messages belongs to one of my test devices while other belong to real users (according to order-ids in receipts).
This test device with Android 4.4.2 has several google accounts added in Settings. Previously I was sure that Google uses the first account. I saw such log messages:
InAppBillingUtils.getPreferredAccount: com.mypackage.appname: Account from first account - [jbC...FgH]
But now I see that sometimes LVL uses not the first account, but another one. I see such messages in LogCat:
InAppBillingUtils.pickAccount: smpxg.mythdefdf: Account determined from library ownership - [boL...M5E]
Moreover, after fresh installation of my app InAppBilling returned receipts for one account, but LVL gave user-id of another! But this behaviour is not stable. For example, now I see that LVL and InAppBilling both think that second account is my primary and work with it as expected.
I assumed that both libraries will work side by side but it looks like I was wrong. Obviously when the app sends receipt belonging to user-id "...yUQ" along with current use-id "...ppA" to server it refuses to send purchased content. And he is right.
If user could change current account used for purchases, I'd just added this trick in FAQ. BUT I can't see a way to select it manually in settings. In addition, system somehow selects it in a random way! The only way to make things work is to ask a user to delete all accounts from the device except his primary, but it's a bad solution.
When user purchases iap item being logged into one account and then switches to another account he should expect not to see purchased item. It's a predictable behaviour, just like with purchasing apps. But he doesn't even know what account is used in the moment!
AFAIK, there's not way to get from InAppBilling service google user-id it selected for purchases. But even if I could - having user-id changed randomly by system makes iap items to appear and disappear from time to time :)
Looks like Google advises to use developer payload for protection, but doesn't give any stable ID which can be used to identify particular account.
So my questions are:
- Does anybody experience this strange account switching?
- How can I be sure which account is current?
- Is there any way to synchronize LVL and InAppBilling account selection? Any workarounds?
Thank you in advance!