In-app purchases with multiple accounts
Asked Answered
T

6

74

I am facing a problem with in app purchases/subscriptions:

If there are multiple accounts on the device, I can't get the purchases, which were made with the second account. This can sometimes be temporarily fixed, by installing the app from the Google Play web interface, but after a while, the purchases won't appear in the query, forcing the user to reinstall.

I am using the IabHelper classes from this sample.

Doing some Google searches, I found that this bug exists since a while, but unfortunately I couldn't find out if the error is in the IabHelper classes or on Google's side.

I'd like to draw attention to Google, so they provide a proper fix for this, either in the IabHelper classes or in the Play Services or to provide information, how this should be handled.

I am using the code in an app with (at the time of writing) 900.000 active user installs and I have to trigger quite a lot of refunds, due to this.

If there is a fix for this, which I missed, please let me know.

Edit: Sometimes it's not possible at all to retrieve the purchases, even if there is only one account on the phone.

Terpsichorean answered 2/3, 2015 at 13:53 Comment(6)
This is not a place to draw Googles Attention. You need to log your bug on code.google.com/p/android/issues/list.Marci
That's the wrong issue tracker. It's a playstore, play services, wallet or purchase issue. code.google.com/p/android/issues/detail?id=53307Terpsichorean
What version of the IAP are you using?Reshape
Can you highlight the specific question you have in an edit? It would make it easier for the community to identify the particular issue at a glance and help us help you quicker.Indelible
All the answers are awful here. Is there a proper solution in 2017, especially for developers, who testing their app from apk?Nightwear
@Nightwear unfortunately notTerpsichorean
M
1

It seems like there isn't a one way road to solve this, but let's try do this.

  1. When the user first install the app get his/her primary email or all accounts on the device

  2. Ask the user what email will they be using for future payment/ or which account is active for google play.

    you can use this code to get the account

    Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
    Account[] accounts = AccountManager.get(context).getAccounts();
    for (Account account : accounts) {
        if (emailPattern.matcher(account.name).matches()) {
            String possibleEmail = account.name;
            ...
        }
    }
    

    Don't forget to ask for permission

    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    

    After the user selects the email, you can send a link via email to confirm this email address

  3. Lead all the payment to that specific email.

Method 2

Use the new "Send & Receive money using Gmail" future

  1. Create a email intent and send specific data to the email intent and make payments.

  2. Upon success, send a code to the user email

  3. Use the code to activate whatever purchased they make.

Method 3

Use another payment library or gateway for your in app purchase instead of Google play.

Misinform answered 8/11, 2016 at 19:58 Comment(8)
Method 3 is against Google's policy when publishing on Play Store, same for Method 2 I suppose. Method 1, can't do #3 as there is no options to select an account in in-app purchase library.David
@David So there is no way to handle it? No way to let users "restore" the purchases via code?Benedictine
@androiddeveloper, any method others than accessing in-app from Play Store are not autorized. The in-app library provided by google have no email account parameter anywhere. Maybe the Google APIs allowing access to purchase information will be a good solution, but haven't tried it myself. Usual solution is for end-user to select the appropriate account in Play Store or Android OS, not sure which though.David
@David I was told on reddit that users could remove the app, visit the app's page on the Play Store website, choose the account they've used to perform the IAP on, and install the app from there. However, a user that told me about this issue said that he tried it and it didn't help :(Benedictine
@androiddeveloper yes, the idea is to be logged-in Play Store with the same account used to purchase in-apps, and/or as mentioned in below answers to make the account used to purchase in-apps the "main" account. It's a user workaround, nothing we can do on dev side. If they give you a chance to explain that you're lucky.David
@David So you noticed it's not always the solution for users?Benedictine
@androiddeveloper, I've seen a few bad reviews that looked like this issue and had one user contact me about it, once, in about ten years. I gave-up on this a long time ago and forgot about it. No idea if Google fixed or improved it in Play Store or nothing at all, but it's been a while since I received/read any complaints.David
Nop. Unfortunately it's still not fixed. :(Soembawa
C
1

As others have noted, this is a bug with the Google Play Billing Library. If it affects you, star this issue on https://issuetracker.google.com/issues/139597485 so Google can notice it (really?) and start working on a fix.

Cumulate answered 2/3, 2021 at 17:9 Comment(0)
G
0

It is sure a bug in the in-app billing service apis.

This

is a similar question and as mentioned in one of the answers, may be you need to introduce login mechanism and store the purchases made from an account to your server or locally on the device in an encrypted file or something similar.

Geronimo answered 19/11, 2015 at 11:19 Comment(3)
I'm not going to store the purchase somewhere else.Terpsichorean
What will we do the same purchase info is needed in another device? Or How will get the Purchase info if the same account is sync in different devices?Raver
Well in that scenario you need to sync it from your server. Every time a user logs into your application you will check if he is an existing user. If yes get the details from your database else create a new entry in the database.Geronimo
S
0

I had ran into same problem couple of months later. After hours of finding solutions and all i came up with a work around something like this,

You can use OAuth 2.0.

But you also have to manage it from your backend. I am not a backend developer so i didnt know how exactly it does in backend but at app side i have done something like this,

You can use the first Google account allowing authentication on your serve side. OAuth 2.0 is a tool that simplifies and get developers an easy way to allow users to access your application. The OAuthHmacSigner class does manages the authentication.

signer = new OAuthHmacSigner();
signer.clientSharedSecret = Constants.CONSUMER_SECRET;

Then the Android activity uses the following code to launch the OAuth flow :

launchOauth.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        startActivity(new Intent().setClass(v.getContext(),
            PrepareRequestTokenActivity.class));
    }
});

In order to get an OAuth 2.0 access token, you simply need to call:

AccountManager.getAuthToken()

I Hope this might help :)

Specie answered 21/11, 2015 at 19:17 Comment(0)
F
0

I have two accounts, but one does not work. What I did is I went into android's settings, and then went into account preferences. I changed my main account from the one that does not work to the working one. Then I assigned the new account to be the main one for all of my applications, including google play. That worked for me. Sometimes, if it does not work for some reason, you can also go online and access the Google Play store from the internet.

Felicafelicdad answered 29/4, 2016 at 14:59 Comment(0)
S
-2

I'm not sure if this is the answer you're searching for, but perhaps setting up a shared Google Play Family Library would suffice. It works for up to 5 users sharing the same purchases (app, music, movies, etc), if desired.

(See: https://support.google.com/googleplay/answer/7007852?hl=en)

Spectrophotometer answered 29/11, 2016 at 21:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.