13

I'm developing an android application and I would like some functionality of the application is not free.

I have thought to use in-app Billing Version 3 API, so I have defined an "In-App Product" in the developer console.

After reading the documentation, I know that when I start the purchase flow I should pass in a string token that helps the application to uniquely identify the user who made the purchase.

But how could I obtain a string token that identify the user?

Thanks

Maulik
  • 3,316
  • 20
  • 31
Eduardo
  • 1,169
  • 5
  • 21
  • 56

2 Answers2

19

you can use developer payload to identify user and for the security.

there are two way to generate developer payload according to your application in app billing requirement.

1) if you are using unmanaged item(not consumable item) then you can use simply UserID which is uniquely identify user in particular your app. you can send developer payload as UserID.

or

you can put email address into developer payload for the unique id if you have user's email id stored into server. when you get response from the google play after user paid for product then fetch it from server database of that user account, match your developer payload.

Local database(Like SQLite):

     UserID
     (Automatecally  
       generated by   product type     userEmailAddress
      Sql database)        


        1            product1            abc@gmail.com
        2            product1            xyz@gmail.com
        3            product1            pqr@gmail.com

Either you can pass it on payload as userID

--> it will create problem some time. if you don't want to go with server database then you can simply ignore the develop payload make it as a blank string it will not effect in you code much more.check this link of Nikolay Elenkov answer: stackoverflow.com/questions/14553515/

2) if you are using consumable item(managed item) then you can use random generated string

step 1: before on create method declare this:

            private static final char[] symbols = new char[36];

        static {
            for (int idx = 0; idx < 10; ++idx)
                symbols[idx] = (char) ('0' + idx);
            for (int idx = 10; idx < 36; ++idx)
                symbols[idx] = (char) ('a' + idx - 10);
        }

step 2: set RandomString and SessionIdentifierGenerator class in your activity

    public class RandomString {

        /*
         * static { for (int idx = 0; idx < 10; ++idx) symbols[idx] = (char)
         * ('0' + idx); for (int idx = 10; idx < 36; ++idx) symbols[idx] =
         * (char) ('a' + idx - 10); }
         */

        private final Random random = new Random();

        private final char[] buf;

        public RandomString(int length) {
            if (length < 1)
                throw new IllegalArgumentException("length < 1: " + length);
            buf = new char[length];
        }

        public String nextString() {
            for (int idx = 0; idx < buf.length; ++idx)
                buf[idx] = symbols[random.nextInt(symbols.length)];
            return new String(buf);
        }

    }

    public final class SessionIdentifierGenerator {

        private SecureRandom random = new SecureRandom();

        public String nextSessionId() {
            return new BigInteger(130, random).toString(32);
        }

    }

step 3: pass payload into your puchase request:

    RandomString randomString = new RandomString(36);
            System.out.println("RandomString>>>>" + randomString.nextString());
            /* String payload = ""; */
            // bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ
            String payload = randomString.nextString();
            Log.e("Random generated Payload", ">>>>>" + payload);

        Log.d(TAG, "Launching purchase flow for infinite gas subscription.");
            mHelper.launchPurchaseFlow(this, SKU_GAS,
                    IabHelper.ITEM_TYPE_INAPP, RC_REQUEST,
                    mPurchaseFinishedListener, payload);

    for more inforamation check this link:
    http://stackoverflow.com/questions/41107/how-to-generate-a-random-alpha-numeric-string

Make note this:

Security Recommendation: When you receive the purchase response from Google Play, make sure to check the returned data signature, the orderId, and the developerPayload string in the Purchase object to make sure that you are getting the expected values. You should verify that the orderId is a unique value that you have not previously processed, and the developerPayload string matches the token that you sent previously with the purchase request. As a further security precaution, you should perform the verification on your own secure server.

   check this link:
   http://developer.android.com/google/play/billing/billing_integrate.html
for more details check this link:

http://developer.android.com/google/play/billing/billing_best_practices.html

Hope it will help you.

Maulik
  • 3,316
  • 20
  • 31
  • Thanks for your reply. I'm not very sure if I've understood you. My product is not consumable as it is only to permit access to some application funcionality. Only users that buy the product will be able to access to this funcionality of the application, and they will access to it forever, so it is not a consumable product. Google documentation says: "For consumable items, you can use a randomly generated string, but for non-consumable items you should use a string that uniquely identifies the user." – Eduardo Jun 20 '13 at 09:22
  • What I understand about non-consumable items is that the payload must include a string that uniquely identifies the user, and this is for me something like an email address. You have written about UserId, but I don't know what is exactly this. How could I obtain UserId to include it in the payload? Thanks – Eduardo Jun 20 '13 at 09:22
  • check my edited answer above. you can pass user EmailAddress or user id (that will automatically generated in the local database) as a developer payload. – Maulik Jun 20 '13 at 10:28
  • According to my knowledge,In your case, I think UUID(device unique id) is not the better solution because if one user have more than to device then he may not match same payload in the other device. – Maulik Jun 20 '13 at 10:32
  • 1
    Ok, then suppose I use email as user identifier. What happen if two different users use the same account into their devices? Only user "X" has bought the application, and then he let other user "Y" uses his account into his device. Does the user "Y" can access the funcionality that user "X" has bought? – Eduardo Jun 20 '13 at 10:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/32072/discussion-between-maulik-and-eduardo) – Maulik Jun 20 '13 at 10:59
  • 1
    This does not give an answer. The question was "how obtain a string to identify the user". In the answer there is a lot of code without a way to get the user. It's only generically reported "UserID" or "email address" – ARLabs Feb 15 '17 at 16:12
  • Google advises against using gmail id in developer payload as gmail id can change for a google account. And even if you do use gmail id, you will need read account permission to read it from device and asking that permission prompts for "contacts" permission at runtime on android M and above. – A.J. Mar 30 '17 at 06:57
  • @A.J. We can use login information including email id stored for users details on the local device or we can simply use the random number to identify the user stored on the backend side database. Is it answer your question? – Maulik Mar 31 '17 at 03:39
  • @Maulik, I have no question. It was just a comment. – A.J. Apr 03 '17 at 06:26
  • why we use google account to do a purchase if that is not attach to my purchase? for example, if I set test gmail account in the developer console, google doesnt charge me for that. if I uninstall the app and reinstall, i can retrieve my purchases. How does google know that? I never pass any payload. I think that it is already attach to our gmail accounts, your logic makes no sense. – Emil Apr 25 '18 at 11:03
-2

Why do you not create an UUID for each user?

String uniqueID = UUID.randomUUID().toString();
Victor Laerte
  • 6,446
  • 13
  • 53
  • 102